]> git.mxchange.org Git - friendica.git/commitdiff
Merge branch 'develop' into rewrites/coding-convention-split2
authorRoland Häder <Quix0r@users.noreply.github.com>
Sat, 1 Apr 2017 20:16:08 +0000 (22:16 +0200)
committerGitHub <noreply@github.com>
Sat, 1 Apr 2017 20:16:08 +0000 (22:16 +0200)
93 files changed:
INSTALL.txt
boot.php
doc/Install.md
doc/Settings.md
doc/de/Install.md
htconfig.php
include/Probe.php
include/api.php
include/bb2diaspora.php
include/cron.php
include/cronjobs.php
include/crypto.php
include/dfrn.php
include/diaspora.php
include/discover_poco.php
include/html2bbcode.php
include/oembed.php
include/ostatus.php
include/socgraph.php
include/user.php
library/defuse/php-encryption-1.2.1/Crypto.php
library/markdown.php
library/oauth.php [deleted file]
library/php-markdown/License.md
library/php-markdown/Michelf/Markdown.inc.php
library/php-markdown/Michelf/Markdown.php
library/php-markdown/Michelf/MarkdownExtra.inc.php
library/php-markdown/Michelf/MarkdownExtra.php
library/php-markdown/Michelf/MarkdownInterface.inc.php
library/php-markdown/Michelf/MarkdownInterface.php
library/php-markdown/Readme.md
library/php-markdown/Readme.php
library/php-markdown/composer.json
library/phpsec/Crypt/AES.php [deleted file]
library/phpsec/Crypt/DES.php [deleted file]
library/phpsec/Crypt/Hash.php [deleted file]
library/phpsec/Crypt/RC4.php [deleted file]
library/phpsec/Crypt/RSA.php [deleted file]
library/phpsec/Crypt/Random.php [deleted file]
library/phpsec/Crypt/Rijndael.php [deleted file]
library/phpsec/Crypt/TripleDES.php [deleted file]
library/phpsec/Math/BigInteger.php [deleted file]
library/phpsec/Net/SFTP.php [deleted file]
library/phpsec/Net/SSH1.php [deleted file]
library/phpsec/Net/SSH2.php [deleted file]
library/phpsec/PHP/Compat/Function/array_fill.php [deleted file]
library/phpsec/PHP/Compat/Function/bcpowmod.php [deleted file]
library/phpsec/PHP/Compat/Function/str_split.php [deleted file]
library/phpsec/crypt.html [deleted file]
library/phpsec/docbook.css [deleted file]
library/phpsec/index.html [deleted file]
library/phpsec/intro.html [deleted file]
library/phpsec/math.html [deleted file]
library/phpsec/misc_crypt.html [deleted file]
library/phpsec/net.html [deleted file]
library/phpsec/sym_crypt.html [deleted file]
library/spam/README [deleted file]
library/spam/b8/b8.php [deleted file]
library/spam/b8/b8.php.ORIG [deleted file]
library/spam/b8/degenerator/degenerator_default.php [deleted file]
library/spam/b8/lexer/lexer_default.php [deleted file]
library/spam/b8/storage/storage_base.php [deleted file]
library/spam/b8/storage/storage_base.php.ORIG [deleted file]
library/spam/b8/storage/storage_dba.php [deleted file]
library/spam/b8/storage/storage_frndc.php [deleted file]
library/spam/b8/storage/storage_mysql.php [deleted file]
library/spam/doc/COPYING [deleted file]
library/spam/doc/ChangeLog [deleted file]
library/spam/doc/readme.htm [deleted file]
library/spam/doc/readme.rst [deleted file]
library/spam/example/index.php [deleted file]
library/spam/install/setup_berkeleydb.php [deleted file]
library/spam/install/setup_mysql.sql [deleted file]
mod/admin.php
mod/babel.php
mod/community.php
mod/dfrn_confirm.php
mod/dfrn_notify.php
mod/dirfind.php
mod/install.php
mod/nodeinfo.php
view/lang/es/messages.po
view/lang/es/strings.php
view/templates/admin_site.tpl
view/templates/htconfig.tpl
view/theme/frio/css/style.css
view/theme/frio/js/filebrowser.js
view/theme/frio/js/modal.js
view/theme/frio/php/default.php
view/theme/frio/php/standard.php
view/theme/frio/templates/filebrowser.tpl
view/theme/frost-mobile/templates/admin_site.tpl
view/theme/frost/templates/admin_site.tpl

index 4c57064f6be5db15f96d33d4064b4951c9871ddf..81dfdfd27219a02febeb1afe15686909317435e4 100644 (file)
@@ -37,7 +37,7 @@ local .htaccess file
                - PHP *command line* access with register_argc_argv set to true in the 
 php.ini file [or see 'poormancron' in section 8]
 
-               - curl, gd (with at least jpeg support), mysql, mbstring, mcrypt, and openssl extensions
+               - curl, gd (with at least jpeg support), mysql, mbstring and openssl extensions
 
                - some form of email server or email gateway such that PHP mail() works
 
index 5f65572d50b9408ab3f34b712b2fe63eb2d075a7..b1c7b265b28e1ea0905ba21b4e5826f07c454c04 100644 (file)
--- a/boot.php
+++ b/boot.php
@@ -649,7 +649,6 @@ class App {
                set_include_path(
                                'include' . PATH_SEPARATOR
                                . 'library' . PATH_SEPARATOR
-                               . 'library/phpsec' . PATH_SEPARATOR
                                . 'library/langdet' . PATH_SEPARATOR
                                . '.' );
 
index 9a194254a0e65f07ffcb47e9deec97b28a266d49..b817339bb012e03d650b417358a2b03e8046996f 100644 (file)
@@ -30,7 +30,6 @@ Requirements
 * PHP *command line* access with register_argc_argv set to true in the php.ini file
 * curl, gd, mysql, hash and openssl extensions
 * some form of email server or email gateway such that PHP mail() works
-* mcrypt (optional; used for server-to-server message encryption)
 * Mysql 5.5.3+ or an equivalant alternative for MySQL (MariaDB, Percona Server etc.)
 * the ability to schedule jobs with cron (Linux/Mac) or Scheduled Tasks (Windows) (Note: other options are presented in Section 7 of this document.)
 * Installation into a top-level domain or sub-domain (without a directory/path component in the URL) is preferred. Directory paths will not be as convenient to use and have not been thoroughly tested.
index 9590ad42d6076924327110fd9357c5093c4091b0..5055ed7d23df6d328c6a2dc20bcd4b97ee719224 100644 (file)
@@ -152,13 +152,6 @@ Value is in seconds.
 Default is 60 seconds.
 Set to 0 for unlimited (not recommended).
 
-#### UTF-8 Regular Expressions
-
-During registrations, full names are checked using UTF-8 regular expressions.
-This requires PHP to have been compiled with a special setting to allow UTF-8 expressions.
-If you are completely unable to register accounts, set no_utf to true.
-The default is set to false (meaning UTF8 regular expressions are supported and working).
-
 #### Verify SSL Certitificates
 
 By default Friendica allows SSL communication between websites that have "self-signed" SSL certificates.
index df95735f3601a88075c51decac48d12de788c848..740202310c79a8af57429cf370f60591ae616571 100644 (file)
@@ -26,7 +26,6 @@ Wir planen, diese Einschränkung in einer zukünftigen Version zu beheben.
         - PHP *Kommandozeilen*-Zugang mit register_argc_argv auf "true" gesetzt in der php.ini-Datei
         - curl, gd, mysql und openssl-Erweiterung
         - etwas in der Art eines Email-Servers oder eines Gateways wie PHP mail()
-        - mcrypt (optional; wird für die Server-zu-Server Nachrichtenentschlüsselung benötigt)
     - Mysql 5.x
     - die Möglichkeit, wiederkehrende Aufgaben mit cron (Linux/Mac) oder "Scheduled Tasks" einzustellen (Windows) [Beachte: andere Optionen sind in Abschnitt 7 dieser Dokumentation zu finden] 
     - Installation in einer Top-Level-Domain oder Subdomain (ohne eine Verzeichnis/Pfad-Komponente in der URL) wird bevorzugt. Verzeichnispfade sind für diesen Zweck nicht so günstig und wurden auch nicht ausführlich getestet.
@@ -37,7 +36,7 @@ Wir planen, diese Einschränkung in einer zukünftigen Version zu beheben.
     1.1. APT-Pakete
                - Apache: sudo apt-get install apache2
                - PHP5: sudo apt-get install php5
-                       - PHP5-Zusätzliche Pakete: sudo apt-get install php5-curl php5-gd php5-mysql php5-mcrypt
+                       - PHP5-Zusätzliche Pakete: sudo apt-get install php5-curl php5-gd php5-mysql
                - MySQL: sudo apt-get install mysql-server
 
 2. Entpacke die Friendica-Daten in das Quellverzeichnis (root) des Dokumentenbereichs deines Webservers.
index 41317c46083034c47987194fdf7dce741a1088b8..5967e79f4e1efec7ca934aea20d801c343833945 100644 (file)
@@ -65,9 +65,8 @@ $a->config['php_path'] = 'php';
 $a->config['system']['huburl'] = '[internal]';
 
 // Server-to-server private message encryption (RINO) is allowed by default.
-// Encryption will only be provided if this setting is set to a non zero
-// value and the PHP mcrypt extension is installed on both systems
-// set to 0 to disable, 2 to enable, 1 is deprecated but wont need mcrypt
+// Encryption will only be provided if this setting is set to a non zero value
+// set to 0 to disable, 2 to enable, 1 is deprecated
 
 $a->config['system']['rino_encrypt'] = 2;
 
index 1b6feb107f4d32cf260da732dac770b64247790d..d0b799bfbafdf756abd76b2d6436d87bcedfdcc9 100644 (file)
@@ -18,6 +18,8 @@ require_once('include/network.php');
  */
 class Probe {
 
+       private static $baseurl;
+
        /**
         * @brief Rearrange the array so that it always has the same order
         *
@@ -54,6 +56,9 @@ class Probe {
         */
        private function xrd($host) {
 
+               // Reset the static variable
+               self::$baseurl = '';
+
                $ssl_url = "https://".$host."/.well-known/host-meta";
                $url = "http://".$host."/.well-known/host-meta";
 
@@ -102,6 +107,9 @@ class Probe {
                        elseif ($attributes["rel"] == "lrdd")
                                $xrd_data["lrdd"] = $attributes["template"];
                }
+
+               self::$baseurl = "http://".$host;
+
                return $xrd_data;
        }
 
@@ -169,6 +177,8 @@ class Probe {
 
                        $path_parts = explode("/", trim($parts["path"], "/"));
 
+                       $nick = array_pop($path_parts);
+
                        do {
                                $lrdd = self::xrd($host);
                                $host .= "/".array_shift($path_parts);
@@ -192,6 +202,19 @@ class Probe {
                                $path = str_replace('{uri}', urlencode("acct:".$uri), $link);
                                $webfinger = self::webfinger($path);
                        }
+
+                       // Special treatment for Mastodon
+                       // Problem is that Mastodon uses an URL format like http://domain.tld/@nick
+                       // But the webfinger for this format fails.
+                       if (!$webfinger AND isset($nick)) {
+                               // Mastodon uses a "@" as prefix for usernames in their url format
+                               $nick = ltrim($nick, '@');
+
+                               $addr = $nick."@".$host;
+
+                               $path = str_replace('{uri}', urlencode("acct:".$addr), $link);
+                               $webfinger = self::webfinger($path);
+                       }
                }
 
                if (!is_array($webfinger["links"]))
@@ -258,8 +281,13 @@ class Probe {
                                $data['nick'] = trim(substr($data['nick'], 0, strpos($data['nick'], ' ')));
                }
 
-               if (!isset($data["network"]))
+               if (self::$baseurl != "") {
+                       $data["baseurl"] = self::$baseurl;
+               }
+
+               if (!isset($data["network"])) {
                        $data["network"] = NETWORK_PHANTOM;
+               }
 
                $data = self::rearrange_data($data);
 
@@ -286,6 +314,7 @@ class Probe {
                                        dbesc(normalise_link($data['url']))
                        );
                }
+
                return $data;
        }
 
@@ -301,7 +330,34 @@ class Probe {
         * @return array uri data
         */
        private function detect($uri, $network, $uid) {
-               if (strstr($uri, '@')) {
+               $parts = parse_url($uri);
+
+               if (isset($parts["scheme"]) AND isset($parts["host"]) AND isset($parts["path"])) {
+
+                       /// @todo: Ports?
+                       $host = $parts["host"];
+
+                       if ($host == 'twitter.com') {
+                               return array("network" => NETWORK_TWITTER);
+                       }
+                       $lrdd = self::xrd($host);
+
+                       $path_parts = explode("/", trim($parts["path"], "/"));
+
+                       while (!$lrdd AND (sizeof($path_parts) > 1)) {
+                               $host .= "/".array_shift($path_parts);
+                               $lrdd = self::xrd($host);
+                       }
+                       if (!$lrdd) {
+                               return self::feed($uri);
+                       }
+                       $nick = array_pop($path_parts);
+
+                       // Mastodon uses a "@" as prefix for usernames in their url format
+                       $nick = ltrim($nick, '@');
+
+                       $addr = $nick."@".$host;
+               } elseif (strstr($uri, '@')) {
                        // If the URI starts with "mailto:" then jump directly to the mail detection
                        if (strpos($url,'mailto:') !== false) {
                                $uri = str_replace('mailto:', '', $url);
@@ -317,42 +373,19 @@ class Probe {
                        $host = substr($uri,strpos($uri, '@') + 1);
                        $nick = substr($uri,0, strpos($uri, '@'));
 
-                       if (strpos($uri, '@twitter.com'))
+                       if (strpos($uri, '@twitter.com')) {
                                return array("network" => NETWORK_TWITTER);
-
+                       }
                        $lrdd = self::xrd($host);
 
-                       if (!$lrdd)
+                       if (!$lrdd) {
                                return self::mail($uri, $uid);
-
+                       }
                        $addr = $uri;
                } else {
-                       $parts = parse_url($uri);
-                       if (!isset($parts["scheme"]) OR
-                               !isset($parts["host"]) OR
-                               !isset($parts["path"]))
-                               return false;
-
-                       /// @todo: Ports?
-                       $host = $parts["host"];
-
-                       if ($host == 'twitter.com')
-                               return array("network" => NETWORK_TWITTER);
-
-                       $lrdd = self::xrd($host);
-
-                       $path_parts = explode("/", trim($parts["path"], "/"));
-
-                       while (!$lrdd AND (sizeof($path_parts) > 1)) {
-                               $host .= "/".array_shift($path_parts);
-                               $lrdd = self::xrd($host);
-                       }
-                       if (!$lrdd)
-                               return self::feed($uri);
-
-                       $nick = array_pop($path_parts);
-                       $addr = $nick."@".$host;
+                       return false;
                }
+
                $webfinger = false;
 
                /// @todo Do we need the prefix "acct:" or "acct://"?
index 701e527cc8236ad86b43aaf04b0d38f500f7f5b4..9fc853340af520d22f9a56b945906a7bd54e9fd2 100644 (file)
@@ -352,6 +352,7 @@ use \Friendica\Core\Config;
                                        }
                                }
                        }
+                       logger('API call not implemented: '.$a->query_string);
                        throw new NotImplementedException();
                } catch (HTTPException $e) {
                        header("HTTP/1.1 {$e->httpcode} {$e->httpdesc}");
@@ -2720,6 +2721,7 @@ use \Friendica\Core\Config;
                return api_format_data('config', $type, array('config' => $config));
 
        }
+       api_register_func('api/gnusocial/config','api_statusnet_config',false);
        api_register_func('api/statusnet/config','api_statusnet_config',false);
 
        function api_statusnet_version($type) {
@@ -2728,6 +2730,7 @@ use \Friendica\Core\Config;
 
                return api_format_data('version', $type, array('version' => $fake_statusnet_version));
        }
+       api_register_func('api/gnusocial/version','api_statusnet_version',false);
        api_register_func('api/statusnet/version','api_statusnet_version',false);
 
        /**
@@ -3963,7 +3966,7 @@ use \Friendica\Core\Config;
                $multi_profiles = feature_enabled(api_user(),'multi_profiles');
                $directory = get_config('system', 'directory');
 
-// get data of the specified profile id or all profiles of the user if not specified
+               // get data of the specified profile id or all profiles of the user if not specified
                if ($profileid != 0) {
                        $r = q("SELECT * FROM `profile` WHERE `uid` = %d AND `id` = %d",
                                intval(api_user()),
@@ -3971,11 +3974,10 @@ use \Friendica\Core\Config;
                        // error message if specified gid is not in database
                        if (!dbm::is_result($r))
                                throw new BadRequestException("profile_id not available");
-               }
-               else
+               } else {
                        $r = q("SELECT * FROM `profile` WHERE `uid` = %d",
                                intval(api_user()));
-
+               }
                // loop through all returned profiles and retrieve data and users
                $k = 0;
                foreach ($r as $rr) {
@@ -4002,9 +4004,11 @@ use \Friendica\Core\Config;
                }
 
                // return settings, authenticated user and profiles data
+               $self = q("SELECT `nurl` FROM `contact` WHERE `uid`= %d AND `self` LIMIT 1", intval(api_user()));
+
                $result = array('multi_profiles' => $multi_profiles ? true : false,
                                                'global_dir' => $directory,
-                                               'friendica_owner' => api_get_user($a, intval(api_user())),
+                                               'friendica_owner' => api_get_user($a, $self[0]['nurl']),
                                                'profiles' => $profiles);
                return api_format_data("friendica_profiles", $type, array('$result' => $result));
        }
index e5099992366558b722c8c27fb635713bc24a4f6c..03eff5a6b73a5bd2c398d11fe8c4d448110a1497 100644 (file)
@@ -59,15 +59,6 @@ function diaspora2bb($s) {
 
        $s = str_replace('&#35;', '#', $s);
 
-       $search = array(" \n", "\n ");
-       $replace = array("\n", "\n");
-       do {
-               $oldtext = $s;
-               $s = str_replace($search, $replace, $s);
-       } while ($oldtext != $s);
-
-       $s = str_replace("\n\n", '<br>', $s);
-
        $s = html2bbcode($s);
 
        // protect the recycle symbol from turning into a tag, but without unescaping angles and naked ampersands
index ca9b5dff25e9ade75dc9546ec3b1d86bc83b5daf..58a3fcf9ce9e5f54ad8dabca0fde89821e44dce1 100644 (file)
@@ -1,28 +1,24 @@
 <?php
 use \Friendica\Core\Config;
 
-require_once('include/photos.php');
-require_once('include/user.php');
-
 function cron_run(&$argv, &$argc){
        global $a;
 
-       require_once('include/session.php');
        require_once('include/datetime.php');
-       require_once('include/items.php');
-       require_once('include/Contact.php');
-       require_once('include/email.php');
-       require_once('include/socgraph.php');
-       require_once('mod/nodeinfo.php');
-       require_once('include/post_update.php');
+
+       // Poll contacts with specific parameters
+       if ($argc > 1) {
+               cron_poll_contacts($argc, $argv);
+               return;
+       }
 
        $last = get_config('system','last_cron');
 
        $poll_interval = intval(get_config('system','cron_interval'));
-       if(! $poll_interval)
+       if (! $poll_interval) {
                $poll_interval = 10;
-
-       if($last) {
+       }
+       if ($last) {
                $next = $last + ($poll_interval * 60);
                if($next > time()) {
                        logger('cron intervall not reached');
@@ -33,19 +29,16 @@ function cron_run(&$argv, &$argc){
        logger('cron: start');
 
        // run queue delivery process in the background
-
        proc_run(PRIORITY_NEGLIGIBLE, "include/queue.php");
 
        // run the process to discover global contacts in the background
-
        proc_run(PRIORITY_LOW, "include/discover_poco.php");
 
        // run the process to update locally stored global contacts in the background
-
        proc_run(PRIORITY_LOW, "include/discover_poco.php", "checkcontact");
 
        // Expire and remove user entries
-       cron_expire_and_remove_users();
+       proc_run(PRIORITY_MEDIUM, "include/cronjobs.php", "expire_and_remove_users");
 
        // Check OStatus conversations
        proc_run(PRIORITY_MEDIUM, "include/cronjobs.php", "ostatus_mentions");
@@ -59,14 +52,22 @@ function cron_run(&$argv, &$argc){
        // update nodeinfo data
        proc_run(PRIORITY_LOW, "include/cronjobs.php", "nodeinfo");
 
-       // once daily run birthday_updates and then expire in background
+       // Clear cache entries
+       proc_run(PRIORITY_LOW, "include/cronjobs.php", "clear_cache");
+
+       // Repair missing Diaspora values in contacts
+       proc_run(PRIORITY_LOW, "include/cronjobs.php", "repair_diaspora");
+
+       // Repair entries in the database
+       proc_run(PRIORITY_LOW, "include/cronjobs.php", "repair_database");
 
+       // once daily run birthday_updates and then expire in background
        $d1 = get_config('system','last_expire_day');
        $d2 = intval(datetime_convert('UTC','UTC','now','d'));
 
        if($d2 != intval($d1)) {
 
-               update_contact_birthdays();
+               proc_run(PRIORITY_LOW, "include/cronjobs.php", "update_contact_birthdays");
 
                proc_run(PRIORITY_LOW, "include/discover_poco.php", "update_server");
 
@@ -78,18 +79,9 @@ function cron_run(&$argv, &$argc){
 
                proc_run(PRIORITY_MEDIUM, 'include/dbclean.php');
 
-               cron_update_photo_albums();
+               proc_run(PRIORITY_LOW, "include/cronjobs.php", "update_photo_albums");
        }
 
-       // Clear cache entries
-       cron_clear_cache($a);
-
-       // Repair missing Diaspora values in contacts
-       cron_repair_diaspora($a);
-
-       // Repair entries in the database
-       cron_repair_database();
-
        // Poll contacts
        cron_poll_contacts($argc, $argv);
 
@@ -100,39 +92,6 @@ function cron_run(&$argv, &$argc){
        return;
 }
 
-/**
- * @brief Update the cached values for the number of photo albums per user
- */
-function cron_update_photo_albums() {
-       $r = q("SELECT `uid` FROM `user` WHERE NOT `account_expired` AND NOT `account_removed`");
-       if (!dbm::is_result($r)) {
-               return;
-       }
-
-       foreach ($r AS $user) {
-               photo_albums($user['uid'], true);
-       }
-}
-
-/**
- * @brief Expire and remove user entries
- */
-function cron_expire_and_remove_users() {
-       // expire any expired accounts
-       q("UPDATE user SET `account_expired` = 1 where `account_expired` = 0
-               AND `account_expires_on` > '%s'
-               AND `account_expires_on` < UTC_TIMESTAMP()", dbesc(NULL_DATE));
-
-       // delete user and contact records for recently removed accounts
-       $r = q("SELECT * FROM `user` WHERE `account_removed` AND `account_expires_on` < UTC_TIMESTAMP() - INTERVAL 3 DAY");
-       if ($r) {
-               foreach($r as $user) {
-                       q("DELETE FROM `contact` WHERE `uid` = %d", intval($user['uid']));
-                       q("DELETE FROM `user` WHERE `uid` = %d", intval($user['uid']));
-               }
-       }
-}
-
 /**
  * @brief Poll contacts for unreceived messages
  *
@@ -145,14 +104,15 @@ function cron_poll_contacts($argc, $argv) {
        $force      = false;
        $restart    = false;
 
-       if (($argc > 1) && ($argv[1] == 'force'))
+       if (($argc > 1) && ($argv[1] == 'force')) {
                $force = true;
-
+       }
        if (($argc > 1) && ($argv[1] == 'restart')) {
                $restart = true;
                $generation = intval($argv[2]);
-               if (!$generation)
+               if (!$generation) {
                        killme();
+               }
        }
 
        if (($argc > 1) && intval($argv[1])) {
@@ -171,9 +131,9 @@ function cron_poll_contacts($argc, $argv) {
        // we are unable to match those posts with a Diaspora GUID and prevent duplicates.
 
        $abandon_days = intval(get_config('system','account_abandon_days'));
-       if($abandon_days < 1)
+       if ($abandon_days < 1) {
                $abandon_days = 0;
-
+       }
        $abandon_sql = (($abandon_days)
                ? sprintf(" AND `user`.`login_date` > UTC_TIMESTAMP() - INTERVAL %d DAY ", intval($abandon_days))
                : ''
@@ -244,185 +204,44 @@ function cron_poll_contacts($argc, $argv) {
 
                                switch ($contact['priority']) {
                                        case 5:
-                                               if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 month"))
+                                               if (datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 month")) {
                                                        $update = true;
+                                               }
                                                break;
                                        case 4:
-                                               if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 week"))
+                                               if (datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 week")) {
                                                        $update = true;
+                                               }
                                                break;
                                        case 3:
-                                               if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day"))
+                                               if (datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day")) {
                                                        $update = true;
+                                               }
                                                break;
                                        case 2:
-                                               if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 12 hour"))
+                                               if (datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 12 hour")) {
                                                        $update = true;
+                                               }
                                                break;
                                        case 1:
                                        default:
-                                               if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 hour"))
+                                               if (datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 hour")) {
                                                        $update = true;
+                                               }
                                                break;
                                }
-                               if (!$update)
+                               if (!$update) {
                                        continue;
+                               }
                        }
 
                        logger("Polling ".$contact["network"]." ".$contact["id"]." ".$contact["nick"]." ".$contact["name"]);
 
                        if (($contact['network'] == NETWORK_FEED) AND ($contact['priority'] <= 3)) {
-                               proc_run(PRIORITY_MEDIUM, 'include/onepoll.php', $contact['id']);
+                               proc_run(PRIORITY_MEDIUM, 'include/onepoll.php', intval($contact['id']));
                        } else {
-                               proc_run(PRIORITY_LOW, 'include/onepoll.php', $contact['id']);
+                               proc_run(PRIORITY_LOW, 'include/onepoll.php', intval($contact['id']));
                        }
                }
        }
 }
-
-/**
- * @brief Clear cache entries
- *
- * @param App $a
- */
-function cron_clear_cache(App $a) {
-
-       $last = get_config('system','cache_last_cleared');
-
-       if($last) {
-               $next = $last + (3600); // Once per hour
-               $clear_cache = ($next <= time());
-       } else
-               $clear_cache = true;
-
-       if (!$clear_cache)
-               return;
-
-       // clear old cache
-       Cache::clear();
-
-       // clear old item cache files
-       clear_cache();
-
-       // clear cache for photos
-       clear_cache($a->get_basepath(), $a->get_basepath()."/photo");
-
-       // clear smarty cache
-       clear_cache($a->get_basepath()."/view/smarty3/compiled", $a->get_basepath()."/view/smarty3/compiled");
-
-       // clear cache for image proxy
-       if (!get_config("system", "proxy_disabled")) {
-               clear_cache($a->get_basepath(), $a->get_basepath()."/proxy");
-
-               $cachetime = get_config('system','proxy_cache_time');
-               if (!$cachetime) $cachetime = PROXY_DEFAULT_TIME;
-
-               q('DELETE FROM `photo` WHERE `uid` = 0 AND `resource-id` LIKE "pic:%%" AND `created` < NOW() - INTERVAL %d SECOND', $cachetime);
-       }
-
-       // Delete the cached OEmbed entries that are older than one year
-       q("DELETE FROM `oembed` WHERE `created` < NOW() - INTERVAL 3 MONTH");
-
-       // Delete the cached "parse_url" entries that are older than one year
-       q("DELETE FROM `parsed_url` WHERE `created` < NOW() - INTERVAL 3 MONTH");
-
-       // Maximum table size in megabyte
-       $max_tablesize = intval(get_config('system','optimize_max_tablesize')) * 1000000;
-       if ($max_tablesize == 0)
-               $max_tablesize = 100 * 1000000; // Default are 100 MB
-
-       if ($max_tablesize > 0) {
-               // Minimum fragmentation level in percent
-               $fragmentation_level = intval(get_config('system','optimize_fragmentation')) / 100;
-               if ($fragmentation_level == 0)
-                       $fragmentation_level = 0.3; // Default value is 30%
-
-               // Optimize some tables that need to be optimized
-               $r = q("SHOW TABLE STATUS");
-               foreach($r as $table) {
-
-                       // Don't optimize tables that are too large
-                       if ($table["Data_length"] > $max_tablesize)
-                               continue;
-
-                       // Don't optimize empty tables
-                       if ($table["Data_length"] == 0)
-                               continue;
-
-                       // Calculate fragmentation
-                       $fragmentation = $table["Data_free"] / ($table["Data_length"] + $table["Index_length"]);
-
-                       logger("Table ".$table["Name"]." - Fragmentation level: ".round($fragmentation * 100, 2), LOGGER_DEBUG);
-
-                       // Don't optimize tables that needn't to be optimized
-                       if ($fragmentation < $fragmentation_level)
-                               continue;
-
-                       // So optimize it
-                       logger("Optimize Table ".$table["Name"], LOGGER_DEBUG);
-                       q("OPTIMIZE TABLE `%s`", dbesc($table["Name"]));
-               }
-       }
-
-       set_config('system','cache_last_cleared', time());
-}
-
-/**
- * @brief Repair missing values in Diaspora contacts
- *
- * @param App $a
- */
-function cron_repair_diaspora(App $a) {
-       $r = q("SELECT `id`, `url` FROM `contact`
-               WHERE `network` = '%s' AND (`batch` = '' OR `notify` = '' OR `poll` = '' OR pubkey = '')
-                       ORDER BY RAND() LIMIT 50", dbesc(NETWORK_DIASPORA));
-       if (dbm::is_result($r)) {
-               foreach ($r AS $contact) {
-                       if (poco_reachable($contact["url"])) {
-                               $data = probe_url($contact["url"]);
-                               if ($data["network"] == NETWORK_DIASPORA) {
-                                       logger("Repair contact ".$contact["id"]." ".$contact["url"], LOGGER_DEBUG);
-                                       q("UPDATE `contact` SET `batch` = '%s', `notify` = '%s', `poll` = '%s', pubkey = '%s' WHERE `id` = %d",
-                                               dbesc($data["batch"]), dbesc($data["notify"]), dbesc($data["poll"]), dbesc($data["pubkey"]),
-                                               intval($contact["id"]));
-                               }
-                       }
-               }
-       }
-}
-
-/**
- * @brief Do some repairs in database entries
- *
- */
-function cron_repair_database() {
-
-       // Sometimes there seem to be issues where the "self" contact vanishes.
-       // We haven't found the origin of the problem by now.
-       $r = q("SELECT `uid` FROM `user` WHERE NOT EXISTS (SELECT `uid` FROM `contact` WHERE `contact`.`uid` = `user`.`uid` AND `contact`.`self`)");
-       if (dbm::is_result($r)) {
-               foreach ($r AS $user) {
-                       logger('Create missing self contact for user '.$user['uid']);
-                       user_create_self_contact($user['uid']);
-               }
-       }
-
-       // Set the parent if it wasn't set. (Shouldn't happen - but does sometimes)
-       // This call is very "cheap" so we can do it at any time without a problem
-       q("UPDATE `item` INNER JOIN `item` AS `parent` ON `parent`.`uri` = `item`.`parent-uri` AND `parent`.`uid` = `item`.`uid` SET `item`.`parent` = `parent`.`id` WHERE `item`.`parent` = 0");
-
-       // There was an issue where the nick vanishes from the contact table
-       q("UPDATE `contact` INNER JOIN `user` ON `contact`.`uid` = `user`.`uid` SET `nick` = `nickname` WHERE `self` AND `nick`=''");
-
-       // Update the global contacts for local users
-       $r = q("SELECT `uid` FROM `user` WHERE `verified` AND NOT `blocked` AND NOT `account_removed` AND NOT `account_expired`");
-       if (dbm::is_result($r))
-               foreach ($r AS $user)
-                       update_gcontact_for_user($user["uid"]);
-
-       /// @todo
-       /// - remove thread entries without item
-       /// - remove sign entries without item
-       /// - remove children when parent got lost
-       /// - set contact-id in item when not present
-}
index 5cc2bf1323518327a64c24d61d4373ead573bbf4..79ee32bb37f0224f4be80e76b0a2ea1fba160c01 100644 (file)
@@ -8,10 +8,17 @@ function cronjobs_run(&$argv, &$argc){
        require_once('include/ostatus.php');
        require_once('include/post_update.php');
        require_once('mod/nodeinfo.php');
+       require_once('include/photos.php');
+       require_once('include/user.php');
+       require_once('include/socgraph.php');
+       require_once('include/Probe.php');
 
        // No parameter set? So return
-       if ($argc <= 1)
+       if ($argc <= 1) {
                return;
+       }
+
+       logger("Starting cronjob ".$argv[1], LOGGER_DEBUG);
 
        // Check OStatus conversations
        // Check only conversations with mentions (for a longer time)
@@ -39,5 +46,244 @@ function cronjobs_run(&$argv, &$argc){
                return;
        }
 
+       // Expire and remove user entries
+       if ($argv[1] == 'expire_and_remove_users') {
+               cron_expire_and_remove_users();
+               return;
+       }
+
+       if ($argv[1] == 'update_contact_birthdays') {
+               update_contact_birthdays();
+               return;
+       }
+
+       if ($argv[1] == 'update_photo_albums') {
+               cron_update_photo_albums();
+               return;
+       }
+
+       // Clear cache entries
+       if ($argv[1] == 'clear_cache') {
+               cron_clear_cache($a);
+               return;
+       }
+
+       // Repair missing Diaspora values in contacts
+       if ($argv[1] == 'repair_diaspora') {
+               cron_repair_diaspora($a);
+               return;
+       }
+
+       // Repair entries in the database
+       if ($argv[1] == 'repair_database') {
+               cron_repair_database();
+               return;
+       }
+
+       logger("Xronjob ".$argv[1]." is unknown.", LOGGER_DEBUG);
+
        return;
 }
+
+/**
+ * @brief Update the cached values for the number of photo albums per user
+ */
+function cron_update_photo_albums() {
+       $r = q("SELECT `uid` FROM `user` WHERE NOT `account_expired` AND NOT `account_removed`");
+       if (!dbm::is_result($r)) {
+               return;
+       }
+
+       foreach ($r AS $user) {
+               photo_albums($user['uid'], true);
+       }
+}
+
+/**
+ * @brief Expire and remove user entries
+ */
+function cron_expire_and_remove_users() {
+       // expire any expired accounts
+       q("UPDATE user SET `account_expired` = 1 where `account_expired` = 0
+               AND `account_expires_on` > '%s'
+               AND `account_expires_on` < UTC_TIMESTAMP()", dbesc(NULL_DATE));
+
+       // delete user and contact records for recently removed accounts
+       $r = q("SELECT * FROM `user` WHERE `account_removed` AND `account_expires_on` < UTC_TIMESTAMP() - INTERVAL 3 DAY");
+       if (dbm::is_result($r)) {
+               foreach ($r as $user) {
+                       q("DELETE FROM `contact` WHERE `uid` = %d", intval($user['uid']));
+                       q("DELETE FROM `user` WHERE `uid` = %d", intval($user['uid']));
+               }
+       }
+}
+
+/**
+ * @brief Clear cache entries
+ *
+ * @param App $a
+ */
+function cron_clear_cache(App $a) {
+
+       $last = get_config('system','cache_last_cleared');
+
+       if ($last) {
+               $next = $last + (3600); // Once per hour
+               $clear_cache = ($next <= time());
+       } else {
+               $clear_cache = true;
+       }
+
+       if (!$clear_cache) {
+               return;
+       }
+
+       // clear old cache
+       Cache::clear();
+
+       // clear old item cache files
+       clear_cache();
+
+       // clear cache for photos
+       clear_cache($a->get_basepath(), $a->get_basepath()."/photo");
+
+       // clear smarty cache
+       clear_cache($a->get_basepath()."/view/smarty3/compiled", $a->get_basepath()."/view/smarty3/compiled");
+
+       // clear cache for image proxy
+       if (!get_config("system", "proxy_disabled")) {
+               clear_cache($a->get_basepath(), $a->get_basepath()."/proxy");
+
+               $cachetime = get_config('system','proxy_cache_time');
+               if (!$cachetime) {
+                       $cachetime = PROXY_DEFAULT_TIME;
+               }
+               q('DELETE FROM `photo` WHERE `uid` = 0 AND `resource-id` LIKE "pic:%%" AND `created` < NOW() - INTERVAL %d SECOND', $cachetime);
+       }
+
+       // Delete the cached OEmbed entries that are older than one year
+       q("DELETE FROM `oembed` WHERE `created` < NOW() - INTERVAL 3 MONTH");
+
+       // Delete the cached "parse_url" entries that are older than one year
+       q("DELETE FROM `parsed_url` WHERE `created` < NOW() - INTERVAL 3 MONTH");
+
+       // Maximum table size in megabyte
+       $max_tablesize = intval(get_config('system','optimize_max_tablesize')) * 1000000;
+       if ($max_tablesize == 0) {
+               $max_tablesize = 100 * 1000000; // Default are 100 MB
+       }
+       if ($max_tablesize > 0) {
+               // Minimum fragmentation level in percent
+               $fragmentation_level = intval(get_config('system','optimize_fragmentation')) / 100;
+               if ($fragmentation_level == 0) {
+                       $fragmentation_level = 0.3; // Default value is 30%
+               }
+
+               // Optimize some tables that need to be optimized
+               $r = q("SHOW TABLE STATUS");
+               foreach ($r as $table) {
+
+                       // Don't optimize tables that are too large
+                       if ($table["Data_length"] > $max_tablesize) {
+                               continue;
+                       }
+
+                       // Don't optimize empty tables
+                       if ($table["Data_length"] == 0) {
+                               continue;
+                       }
+
+                       // Calculate fragmentation
+                       $fragmentation = $table["Data_free"] / ($table["Data_length"] + $table["Index_length"]);
+
+                       logger("Table ".$table["Name"]." - Fragmentation level: ".round($fragmentation * 100, 2), LOGGER_DEBUG);
+
+                       // Don't optimize tables that needn't to be optimized
+                       if ($fragmentation < $fragmentation_level) {
+                               continue;
+                       }
+
+                       // So optimize it
+                       logger("Optimize Table ".$table["Name"], LOGGER_DEBUG);
+                       q("OPTIMIZE TABLE `%s`", dbesc($table["Name"]));
+               }
+       }
+
+       set_config('system','cache_last_cleared', time());
+}
+
+/**
+ * @brief Repair missing values in Diaspora contacts
+ *
+ * @param App $a
+ */
+function cron_repair_diaspora(App $a) {
+
+        $starttime = time();
+
+       $r = q("SELECT `id`, `url` FROM `contact`
+               WHERE `network` = '%s' AND (`batch` = '' OR `notify` = '' OR `poll` = '' OR pubkey = '')
+                       ORDER BY RAND() LIMIT 50", dbesc(NETWORK_DIASPORA));
+       if (!dbm::is_result($r)) {
+               return;
+       }
+
+       foreach ($r AS $contact) {
+               // Quit the loop after 3 minutes
+               if (time() > ($starttime + 180)) {
+                       return;
+               }
+
+               if (!poco_reachable($contact["url"])) {
+                       continue;
+               }
+
+               $data = Probe::uri($contact["url"]);
+               if ($data["network"] != NETWORK_DIASPORA) {
+                       continue;
+               }
+
+               logger("Repair contact ".$contact["id"]." ".$contact["url"], LOGGER_DEBUG);
+               q("UPDATE `contact` SET `batch` = '%s', `notify` = '%s', `poll` = '%s', pubkey = '%s' WHERE `id` = %d",
+                       dbesc($data["batch"]), dbesc($data["notify"]), dbesc($data["poll"]), dbesc($data["pubkey"]),
+                       intval($contact["id"]));
+       }
+}
+
+/**
+ * @brief Do some repairs in database entries
+ *
+ */
+function cron_repair_database() {
+
+       // Sometimes there seem to be issues where the "self" contact vanishes.
+       // We haven't found the origin of the problem by now.
+       $r = q("SELECT `uid` FROM `user` WHERE NOT EXISTS (SELECT `uid` FROM `contact` WHERE `contact`.`uid` = `user`.`uid` AND `contact`.`self`)");
+       if (dbm::is_result($r)) {
+               foreach ($r AS $user) {
+                       logger('Create missing self contact for user '.$user['uid']);
+                       user_create_self_contact($user['uid']);
+               }
+       }
+
+       // Set the parent if it wasn't set. (Shouldn't happen - but does sometimes)
+       // This call is very "cheap" so we can do it at any time without a problem
+       q("UPDATE `item` INNER JOIN `item` AS `parent` ON `parent`.`uri` = `item`.`parent-uri` AND `parent`.`uid` = `item`.`uid` SET `item`.`parent` = `parent`.`id` WHERE `item`.`parent` = 0");
+
+       // There was an issue where the nick vanishes from the contact table
+       q("UPDATE `contact` INNER JOIN `user` ON `contact`.`uid` = `user`.`uid` SET `nick` = `nickname` WHERE `self` AND `nick`=''");
+
+       // Update the global contacts for local users
+       $r = q("SELECT `uid` FROM `user` WHERE `verified` AND NOT `blocked` AND NOT `account_removed` AND NOT `account_expired`");
+       if (dbm::is_result($r)) {
+               foreach ($r AS $user) {
+                       update_gcontact_for_user($user["uid"]);
+               }
+       }
+
+       /// @todo
+       /// - remove thread entries without item
+       /// - remove sign entries without item
+       /// - remove children when parent got lost
+       /// - set contact-id in item when not present
+}
index f5163a9dacbeb2bb8ccf8b3be23ff6de27a62546..4600e7291b7c3ec27622bbb4af64c02f5dfcb22c 100644 (file)
@@ -1,94 +1,52 @@
 <?php
 
-require_once('library/ASNValue.class.php');
-require_once('library/asn1.php');
+require_once 'library/ASNValue.class.php';
+require_once 'library/asn1.php';
 
 // supported algorithms are 'sha256', 'sha1'
 
-function rsa_sign($data,$key,$alg = 'sha256') {
-
-       $sig = '';
-       if (version_compare(PHP_VERSION, '5.3.0', '>=') || $alg === 'sha1') {
-               openssl_sign($data,$sig,$key,(($alg == 'sha1') ? OPENSSL_ALGO_SHA1 : $alg));
-    }
-    else {
-               if(strlen($key) < 1024 || extension_loaded('gmp')) {
-                       require_once('library/phpsec/Crypt/RSA.php');
-                       $rsa = new CRYPT_RSA();
-                       $rsa->signatureMode = CRYPT_RSA_SIGNATURE_PKCS1;
-                       $rsa->setHash($alg);
-                       $rsa->loadKey($key);
-                       $sig = $rsa->sign($data);
-               }
-               else {
-                       logger('rsa_sign: insecure algorithm used. Please upgrade PHP to 5.3');
-                       openssl_private_encrypt(hex2bin('3031300d060960864801650304020105000420') . hash('sha256',$data,true), $sig, $key);
-               }
-       }
+function rsa_sign($data, $key, $alg = 'sha256') {
+       openssl_sign($data, $sig, $key, (($alg == 'sha1') ? OPENSSL_ALGO_SHA1 : $alg));
        return $sig;
 }
 
-function rsa_verify($data,$sig,$key,$alg = 'sha256') {
-
-       if (version_compare(PHP_VERSION, '5.3.0', '>=') || $alg === 'sha1') {
-               $verify = openssl_verify($data,$sig,$key,(($alg == 'sha1') ? OPENSSL_ALGO_SHA1 : $alg));
-    }
-    else {
-               if(strlen($key) <= 300 || extension_loaded('gmp')) {
-                       require_once('library/phpsec/Crypt/RSA.php');
-                       $rsa = new CRYPT_RSA();
-                       $rsa->signatureMode = CRYPT_RSA_SIGNATURE_PKCS1;
-                       $rsa->setHash($alg);
-                       $rsa->loadKey($key);
-                       $verify = $rsa->verify($data,$sig);
-               }
-               else {
-                       // fallback sha256 verify for PHP < 5.3 and large key lengths
-                       $rawsig = '';
-               openssl_public_decrypt($sig,$rawsig,$key);
-               $verify = (($rawsig && substr($rawsig,-32) === hash('sha256',$data,true)) ? true : false);
-       }
-       }
-       return $verify;
+function rsa_verify($data, $sig, $key, $alg = 'sha256') {
+       return openssl_verify($data, $sig, $key, (($alg == 'sha1') ? OPENSSL_ALGO_SHA1 : $alg));
 }
 
-
-function DerToPem($Der, $Private=false)
-{
-    //Encode:
-    $Der = base64_encode($Der);
-    //Split lines:
-    $lines = str_split($Der, 65);
-    $body = implode("\n", $lines);
-    //Get title:
-    $title = $Private? 'RSA PRIVATE KEY' : 'PUBLIC KEY';
-    //Add wrapping:
-    $result = "-----BEGIN {$title}-----\n";
-    $result .= $body . "\n";
-    $result .= "-----END {$title}-----\n";
-    return $result;
+function DerToPem($Der, $Private = false) {
+       //Encode:
+       $Der = base64_encode($Der);
+       //Split lines:
+       $lines = str_split($Der, 65);
+       $body = implode("\n", $lines);
+       //Get title:
+       $title = $Private ? 'RSA PRIVATE KEY' : 'PUBLIC KEY';
+       //Add wrapping:
+       $result = "-----BEGIN {$title}-----\n";
+       $result .= $body . "\n";
+       $result .= "-----END {$title}-----\n";
+
+       return $result;
 }
 
-function DerToRsa($Der)
-{
-    //Encode:
-    $Der = base64_encode($Der);
-    //Split lines:
-    $lines = str_split($Der, 64);
-    $body = implode("\n", $lines);
-    //Get title:
-    $title = 'RSA PUBLIC KEY';
-    //Add wrapping:
-    $result = "-----BEGIN {$title}-----\n";
-    $result .= $body . "\n";
-    $result .= "-----END {$title}-----\n";
-    return $result;
+function DerToRsa($Der) {
+       //Encode:
+       $Der = base64_encode($Der);
+       //Split lines:
+       $lines = str_split($Der, 64);
+       $body = implode("\n", $lines);
+       //Get title:
+       $title = 'RSA PUBLIC KEY';
+       //Add wrapping:
+       $result = "-----BEGIN {$title}-----\n";
+       $result .= $body . "\n";
+       $result .= "-----END {$title}-----\n";
+
+       return $result;
 }
 
-
-function pkcs8_encode($Modulus,$PublicExponent) {
+function pkcs8_encode($Modulus, $PublicExponent) {
        //Encode key sequence
        $modulus = new ASNValue(ASNValue::TAG_INTEGER);
        $modulus->SetIntBuffer($Modulus);
@@ -111,8 +69,7 @@ function pkcs8_encode($Modulus,$PublicExponent) {
        return $PublicDER;
 }
 
-
-function pkcs1_encode($Modulus,$PublicExponent) {
+function pkcs1_encode($Modulus, $PublicExponent) {
        //Encode key sequence
        $modulus = new ASNValue(ASNValue::TAG_INTEGER);
        $modulus->SetIntBuffer($Modulus);
@@ -126,22 +83,20 @@ function pkcs1_encode($Modulus,$PublicExponent) {
        return $bitStringValue;
 }
 
-
-function metopem($m,$e) {
-       $der = pkcs8_encode($m,$e);
-       $key = DerToPem($der,false);
+function metopem($m, $e) {
+       $der = pkcs8_encode($m, $e);
+       $key = DerToPem($der, false);
        return $key;
-}      
-
+}
 
 function pubrsatome($key,&$m,&$e) {
        require_once('library/asn1.php');
        require_once('include/salmon.php');
 
-       $lines = explode("\n",$key);
+       $lines = explode("\n", $key);
        unset($lines[0]);
        unset($lines[count($lines)]);
-       $x = base64_decode(implode('',$lines));
+       $x = base64_decode(implode('', $lines));
 
        $r = ASN_BASE::parseASNString($x);
 
@@ -151,21 +106,21 @@ function pubrsatome($key,&$m,&$e) {
 
 
 function rsatopem($key) {
-       pubrsatome($key,$m,$e);
-       return(metopem($m,$e));
+       pubrsatome($key, $m, $e);
+       return metopem($m, $e);
 }
 
 function pemtorsa($key) {
-       pemtome($key,$m,$e);
-       return(metorsa($m,$e));
+       pemtome($key, $m, $e);
+       return metorsa($m, $e);
 }
 
-function pemtome($key,&$m,&$e) {
+function pemtome($key, &$m, &$e) {
        require_once('include/salmon.php');
-       $lines = explode("\n",$key);
+       $lines = explode("\n", $key);
        unset($lines[0]);
        unset($lines[count($lines)]);
-       $x = base64_decode(implode('',$lines));
+       $x = base64_decode(implode('', $lines));
 
        $r = ASN_BASE::parseASNString($x);
 
@@ -173,82 +128,36 @@ function pemtome($key,&$m,&$e) {
        $e = base64url_decode($r[0]->asnData[1]->asnData[0]->asnData[1]->asnData);
 }
 
-function metorsa($m,$e) {
-       $der = pkcs1_encode($m,$e);
+function metorsa($m, $e) {
+       $der = pkcs1_encode($m, $e);
        $key = DerToRsa($der);
        return $key;
-}      
-
-function salmon_key($pubkey) {
-       pemtome($pubkey,$m,$e);
-       return 'RSA' . '.' . base64url_encode($m,true) . '.' . base64url_encode($e,true) ;
 }
 
-
-
-if(! function_exists('aes_decrypt')) {
-// DEPRECATED IN 3.4.1
-function aes_decrypt($val,$ky)
-{
-    $key="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
-    for($a=0;$a<strlen($ky);$a++)
-      $key[$a%16]=chr(ord($key[$a%16]) ^ ord($ky[$a]));
-    $mode = MCRYPT_MODE_ECB;
-    $enc = MCRYPT_RIJNDAEL_128;
-    $dec = @mcrypt_decrypt($enc, $key, $val, $mode, @mcrypt_create_iv( @mcrypt_get_iv_size($enc, $mode), MCRYPT_DEV_URANDOM ) );
-    return rtrim($dec,(( ord(substr($dec,strlen($dec)-1,1))>=0 and ord(substr($dec, strlen($dec)-1,1))<=16)? chr(ord( substr($dec,strlen($dec)-1,1))):null));
-}}
-
-
-if(! function_exists('aes_encrypt')) {
-// DEPRECATED IN 3.4.1
-function aes_encrypt($val,$ky)
-{
-    $key="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
-    for($a=0;$a<strlen($ky);$a++)
-      $key[$a%16]=chr(ord($key[$a%16]) ^ ord($ky[$a]));
-    $mode=MCRYPT_MODE_ECB;
-    $enc=MCRYPT_RIJNDAEL_128;
-    $val=str_pad($val, (16*(floor(strlen($val) / 16)+(strlen($val) % 16==0?2:1))), chr(16-(strlen($val) % 16)));
-    return mcrypt_encrypt($enc, $key, $val, $mode, mcrypt_create_iv( mcrypt_get_iv_size($enc, $mode), MCRYPT_DEV_URANDOM));
-}} 
-
-function pkcs5_pad ($text, $blocksize)
-{
-    $pad = $blocksize - (strlen($text) % $blocksize);
-    return $text . str_repeat(chr($pad), $pad);
+function salmon_key($pubkey) {
+       pemtome($pubkey, $m, $e);
+       return 'RSA' . '.' . base64url_encode($m, true) . '.' . base64url_encode($e, true) ;
 }
 
-function pkcs5_unpad($text)
-{
-    $pad = ord($text{strlen($text)-1});
-    if ($pad > strlen($text)) return false;
-    if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
-    return substr($text, 0, -1 * $pad);
-} 
-
-
 function new_keypair($bits) {
-
        $openssl_options = array(
                'digest_alg'       => 'sha1',
                'private_key_bits' => $bits,
-               'encrypt_key'      => false 
+               'encrypt_key'      => false
        );
 
-       $conf = get_config('system','openssl_conf_file');
-       if($conf)
+       $conf = get_config('system', 'openssl_conf_file');
+       if ($conf) {
                $openssl_options['config'] = $conf;
-       
+       }
        $result = openssl_pkey_new($openssl_options);
 
-       if(empty($result)) {
+       if (empty($result)) {
                logger('new_keypair: failed');
                return false;
        }
 
        // Get private key
-
        $response = array('prvkey' => '', 'pubkey' => '');
 
        openssl_pkey_export($result, $response['prvkey']);
@@ -258,6 +167,4 @@ function new_keypair($bits) {
        $response['pubkey'] = $pkey["key"];
 
        return $response;
-
 }
-
index 83d76a0ae45cea961b58cd1ea60944fac1f10a0c..aae935963d0427c7b6ab7afd3cefc62ecc73893a 100644 (file)
@@ -931,6 +931,30 @@ class dfrn {
                return $entry;
        }
 
+       /**
+        * @brief encrypts data via AES
+        *
+        * @param string $data The data that is to be encrypted
+        * @param string $key The AES key
+        *
+        * @return string encrypted data
+        */
+       private static function aes_encrypt($data, $key) {
+               return openssl_encrypt($data, 'aes-128-ecb', $key, OPENSSL_RAW_DATA);
+       }
+
+       /**
+        * @brief decrypts data via AES
+        *
+        * @param string $encrypted The encrypted data
+        * @param string $key The AES key
+        *
+        * @return string decrypted data
+        */
+       public static function aes_decrypt($encrypted, $key) {
+               return openssl_decrypt($encrypted, 'aes-128-ecb', $key, OPENSSL_RAW_DATA);
+       }
+
        /**
         * @brief Delivers the atom content to the contacts
         *
@@ -958,11 +982,6 @@ class dfrn {
                $rino = get_config('system', 'rino_encrypt');
                $rino = intval($rino);
 
-               // use RINO1 if mcrypt isn't installed and RINO2 was selected
-               if ($rino == 2 and !function_exists('mcrypt_create_iv')) {
-                       $rino = 1;
-               }
-
                logger("Local rino version: ". $rino, LOGGER_DEBUG);
 
                $ssl_val = intval(get_config('system','ssl_policy'));
@@ -1093,8 +1112,8 @@ class dfrn {
                        switch ($rino_remote_version) {
                                case 1:
                                        // Deprecated rino version!
-                                       $key = substr(random_string(), 0, 16);
-                                       $data = aes_encrypt($postvars['data'],$key);
+                                       $key = openssl_random_pseudo_bytes(16);
+                                       $data = self::aes_encrypt($postvars['data'], $key);
                                        break;
                                case 2:
                                        // RINO 2 based on php-encryption
@@ -1458,7 +1477,9 @@ class dfrn {
                        $poco["photo"] = $author["avatar"];
                        $poco["hide"] = $hide;
                        $poco["contact-type"] = $contact["contact-type"];
-                       update_gcontact($poco);
+                       $gcid = update_gcontact($poco);
+
+                       link_gcontact($gcid, $importer["uid"], $contact["id"]);
                }
 
                return($author);
index eca22092d81352987a2a8a0e6981c8c7aa3fb206..bdedb9e0b7336ede8ef8b4e455c67e116febeb6e 100644 (file)
 
 use \Friendica\Core\Config;
 
-require_once("include/items.php");
-require_once("include/bb2diaspora.php");
-require_once("include/Scrape.php");
-require_once("include/Contact.php");
-require_once("include/Photo.php");
-require_once("include/socgraph.php");
-require_once("include/group.php");
-require_once("include/xml.php");
-require_once("include/datetime.php");
-require_once("include/queue_fn.php");
-require_once("include/cache.php");
+require_once 'include/items.php';
+require_once 'include/bb2diaspora.php';
+require_once 'include/Scrape.php';
+require_once 'include/Contact.php';
+require_once 'include/Photo.php';
+require_once 'include/socgraph.php';
+require_once 'include/group.php';
+require_once 'include/xml.php';
+require_once 'include/datetime.php';
+require_once 'include/queue_fn.php';
+require_once 'include/cache.php';
 
 /**
  * @brief This class contain functions to create and send Diaspora XML files
@@ -160,6 +160,32 @@ class Diaspora {
                return $data;
        }
 
+       /**
+        * @brief encrypts data via AES
+        *
+        * @param string $key The AES key
+        * @param string $iv The IV (is used for CBC encoding)
+        * @param string $data The data that is to be encrypted
+        *
+        * @return string encrypted data
+        */
+       private static function aes_encrypt($key, $iv, $data) {
+               return openssl_encrypt($data, 'aes-256-cbc', str_pad($key, 32, "\0"), OPENSSL_RAW_DATA, str_pad($iv, 16, "\0"));
+       }
+
+       /**
+        * @brief decrypts data via AES
+        *
+        * @param string $key The AES key
+        * @param string $iv The IV (is used for CBC encoding)
+        * @param string $encrypted The encrypted data
+        *
+        * @return string decrypted data
+        */
+       private static function aes_decrypt($key, $iv, $encrypted) {
+               return openssl_decrypt($encrypted,'aes-256-cbc', str_pad($key, 32, "\0"), OPENSSL_RAW_DATA,str_pad($iv, 16, "\0"));
+       }
+
        /**
         * @brief: Decodes incoming Diaspora message
         *
@@ -199,10 +225,7 @@ class Diaspora {
                        $outer_iv = base64_decode($j_outer_key_bundle->iv);
                        $outer_key = base64_decode($j_outer_key_bundle->key);
 
-                       $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $outer_key, $ciphertext, MCRYPT_MODE_CBC, $outer_iv);
-
-
-                       $decrypted = pkcs5_unpad($decrypted);
+                       $decrypted = self::aes_decrypt($outer_key, $outer_iv, $ciphertext);
 
                        logger('decrypted: '.$decrypted, LOGGER_DEBUG);
                        $idom = parse_xml_string($decrypted,false);
@@ -261,8 +284,7 @@ class Diaspora {
                        // Decode the encrypted blob
 
                        $inner_encrypted = base64_decode($data);
-                       $inner_decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $inner_aes_key, $inner_encrypted, MCRYPT_MODE_CBC, $inner_iv);
-                       $inner_decrypted = pkcs5_unpad($inner_decrypted);
+                       $inner_decrypted = self::aes_decrypt($inner_aes_key, $inner_iv, $inner_encrypted);
                }
 
                if (!$author_link) {
@@ -1848,18 +1870,15 @@ class Diaspora {
                        intval($importer["uid"])
                );
 
-               if ($searchable) {
-                       poco_check($contact["url"], $name, NETWORK_DIASPORA, $image_url, $about, $location, $gender, $keywords, "",
-                               datetime_convert(), 2, $contact["id"], $importer["uid"]);
-               }
-
                $gcontact = array("url" => $contact["url"], "network" => NETWORK_DIASPORA, "generation" => 2,
                                        "photo" => $image_url, "name" => $name, "location" => $location,
                                        "about" => $about, "birthday" => $birthday, "gender" => $gender,
                                        "addr" => $author, "nick" => $nick, "keywords" => $keywords,
                                        "hide" => !$searchable, "nsfw" => $nsfw);
 
-               update_gcontact($gcontact);
+               $gcid = update_gcontact($gcontact);
+
+               link_gcontact($gcid, $importer["uid"], $contact["id"]);
 
                logger("Profile of contact ".$contact["id"]." stored for user ".$importer["uid"], LOGGER_DEBUG);
 
@@ -2621,20 +2640,19 @@ class Diaspora {
                        return false;
                }
 
-               $inner_aes_key = random_string(32);
+               $inner_aes_key = openssl_random_pseudo_bytes(32);
                $b_inner_aes_key = base64_encode($inner_aes_key);
-               $inner_iv = random_string(16);
+               $inner_iv = openssl_random_pseudo_bytes(16);
                $b_inner_iv = base64_encode($inner_iv);
 
-               $outer_aes_key = random_string(32);
+               $outer_aes_key = openssl_random_pseudo_bytes(32);
                $b_outer_aes_key = base64_encode($outer_aes_key);
-               $outer_iv = random_string(16);
+               $outer_iv = openssl_random_pseudo_bytes(16);
                $b_outer_iv = base64_encode($outer_iv);
 
                $handle = self::my_handle($user);
 
-               $padded_data = pkcs5_pad($msg,16);
-               $inner_encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $inner_aes_key, $padded_data, MCRYPT_MODE_CBC, $inner_iv);
+               $inner_encrypted = self::aes_encrypt($inner_aes_key, $inner_iv, $msg);
 
                $b64_data = base64_encode($inner_encrypted);
 
@@ -2656,9 +2674,8 @@ class Diaspora {
                                                        "author_id" => $handle));
 
                $decrypted_header = xml::from_array($xmldata, $xml, true);
-               $decrypted_header = pkcs5_pad($decrypted_header,16);
 
-               $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $outer_aes_key, $decrypted_header, MCRYPT_MODE_CBC, $outer_iv);
+               $ciphertext = self::aes_encrypt($outer_aes_key, $outer_iv, $decrypted_header);
 
                $outer_json = json_encode(array("iv" => $b_outer_iv, "key" => $b_outer_aes_key));
 
index 2923cd01f127489ca07276df210ef4538d05a5e2..bb53efb5ccc125b37097c0d1112338d4b7269b1e 100644 (file)
@@ -16,6 +16,7 @@ function discover_poco_run(&$argv, &$argc) {
        - update_server: Frequently check the first 250 servers for vitality.
        - update_server_directory: Discover the given server id for their contacts
        - poco_load: Load POCO data from a given POCO address
+       - check_profile: Update remote profile data
        */
 
        if (($argc > 2) && ($argv[1] == "dirsearch")) {
@@ -33,6 +34,8 @@ function discover_poco_run(&$argv, &$argc) {
                $mode = 6;
        } elseif (($argc > 5) && ($argv[1] == "poco_load")) {
                $mode = 7;
+       } elseif (($argc == 3) && ($argv[1] == "check_profile")) {
+               $mode = 8;
        } elseif ($argc == 1) {
                $search = "";
                $mode = 0;
@@ -42,7 +45,12 @@ function discover_poco_run(&$argv, &$argc) {
 
        logger('start '.$search);
 
-       if ($mode == 7) {
+       if ($mode == 8) {
+               $profile_url = base64_decode($argv[2]);
+               if ($profile_url != "") {
+                       poco_last_updated($profile_url, true);
+               }
+       } elseif ($mode == 7) {
                if ($argc == 6) {
                        $url = base64_decode($argv[5]);
                } else {
@@ -121,7 +129,9 @@ function update_server() {
 function discover_users() {
        logger("Discover users", LOGGER_DEBUG);
 
-       $users = q("SELECT `url`, `created`, `updated`, `last_failure`, `last_contact`, `server_url` FROM `gcontact`
+       $starttime = time();
+
+       $users = q("SELECT `url`, `created`, `updated`, `last_failure`, `last_contact`, `server_url`, `network` FROM `gcontact`
                        WHERE `last_contact` < UTC_TIMESTAMP - INTERVAL 1 MONTH AND
                                `last_failure` < UTC_TIMESTAMP - INTERVAL 1 MONTH AND
                                `network` IN ('%s', '%s', '%s', '%s', '') ORDER BY rand()",
@@ -155,14 +165,19 @@ function discover_users() {
                        continue;
                }
 
+               $server_url = poco_detect_server($user["url"]);
+               $force_update = false;
+
                if ($user["server_url"] != "") {
+
+                       $force_update = (normalise_link($user["server_url"]) != normalise_link($server_url));
+
                        $server_url = $user["server_url"];
-               } else {
-                       $server_url = poco_detect_server($user["url"]);
                }
-               if (($server_url == "") OR poco_check_server($server_url, $gcontacts[0]["network"])) {
-                       logger('Check user '.$user["url"]);
-                       poco_last_updated($user["url"], true);
+
+               if ((($server_url == "") AND ($user["network"] == NETWORK_FEED)) OR $force_update OR poco_check_server($server_url, $user["network"])) {
+                       logger('Check profile '.$user["url"]);
+                       proc_run(PRIORITY_LOW, "include/discover_poco.php", "check_profile", base64_encode($user["url"]));
 
                        if (++$checked > 100) {
                                return;
@@ -171,6 +186,11 @@ function discover_users() {
                        q("UPDATE `gcontact` SET `last_failure` = '%s' WHERE `nurl` = '%s'",
                                dbesc(datetime_convert()), dbesc(normalise_link($user["url"])));
                }
+
+               // Quit the loop after 3 minutes
+               if (time() > ($starttime + 180)) {
+                       return;
+               }
        }
 }
 
@@ -217,7 +237,14 @@ function discover_directory($search) {
                        if ($data["network"] == NETWORK_DFRN) {
                                logger("Profile ".$jj->url." is reachable (".$search.")", LOGGER_DEBUG);
                                logger("Add profile ".$jj->url." to local directory (".$search.")", LOGGER_DEBUG);
-                               poco_check($data["url"], $data["name"], $data["network"], $data["photo"], "", "", "", $jj->tags, $data["addr"], "", 0);
+
+                               if ($jj->tags != "") {
+                                       $data["keywords"] = $jj->tags;
+                               }
+
+                               $data["server_url"] = $data["baseurl"];
+
+                               update_gcontact($data);
                        } else {
                                logger("Profile ".$jj->url." is not responding or no Friendica contact - but network ".$data["network"], LOGGER_DEBUG);
                        }
index 189ba91f19c847e673844367c10c9a02054da19b..c14629b895ed52bff01ab0f8b5788fdf55bdd736 100644 (file)
@@ -2,7 +2,7 @@
 /**
  * @file include/html2bbcode.php
  * @brief Converter for HTML to BBCode
- * 
+ *
  * Made by: ike@piratenpartei.de
  * Originally made for the syncom project: http://wiki.piratenpartei.de/Syncom
  *                                     https://github.com/annando/Syncom
@@ -79,16 +79,25 @@ function node2bbcodesub(&$doc, $oldnode, $attributes, $startbb, $endbb)
        return($replace);
 }
 
-function _replace_code_cb($m){
-       return "<code>".str_replace("\n","<br>\n",$m[1]). "</code>";
-}
-
 function html2bbcode($message)
 {
 
        $message = str_replace("\r", "", $message);
 
-       $message = preg_replace_callback("|<pre><code>([^<]*)</code></pre>|ism", "_replace_code_cb", $message);
+       // Removing code blocks before the whitespace removal processing below
+       $codeblocks = [];
+       $message = preg_replace_callback('#<pre><code(?: class="([^"]*)")?>(.*)</code></pre>#iUs',
+               function ($matches) use (&$codeblocks) {
+                       $return = '[codeblock-' . count($codeblocks) . ']';
+
+            $prefix = '[code]';
+            if ($matches[1] != '') {
+                $prefix = '[code=' . $matches[1] . ']';
+            }
+                       $codeblocks[] = $prefix . $matches[2] . '[/code]';
+                       return $return;
+               }
+       , $message);
 
        $message = str_replace(array(
                                        "<li><p>",
@@ -232,7 +241,6 @@ function html2bbcode($message)
        node2bbcode($doc, 'audio', array('src'=>'/(.+)/'), '[audio]$1', '[/audio]');
        node2bbcode($doc, 'iframe', array('src'=>'/(.+)/'), '[iframe]$1', '[/iframe]');
 
-       node2bbcode($doc, 'code', array(), '[code]', '[/code]');
        node2bbcode($doc, 'key', array(), '[code]', '[/code]');
 
        $message = $doc->saveHTML();
@@ -302,6 +310,19 @@ function html2bbcode($message)
        // Handling Yahoo style of mails
        $message = str_replace('[hr][b]From:[/b]', '[quote][b]From:[/b]', $message);
 
-       return(trim($message));
+       // Restore code blocks
+       $message = preg_replace_callback('#\[codeblock-([0-9]+)\]#iU',
+               function ($matches) use ($codeblocks) {
+            $return = '';
+            if (isset($codeblocks[intval($matches[1])])) {
+                $return = $codeblocks[$matches[1]];
+            }
+                       return $return;
+               }
+       , $message);
+
+       $message = trim($message);
+
+       return $message;
 }
 ?>
index a1945894fcaf3fb877ff36c7e2b5a2ec1e0b7e71..0b8b713667e7aa1faede525a5a08db1b07b03c0b 100755 (executable)
@@ -17,10 +17,10 @@ function oembed_replacecb($matches){
 
 /**
  * @brief Get data from an URL to embed its content.
- * 
+ *
  * @param string $embedurl The URL from which the data should be fetched.
  * @param bool $no_rich_type If set to true rich type content won't be fetched.
- * 
+ *
  * @return bool|object Returns object with embed content or false if no embedable
  *      content exists
  */
@@ -41,8 +41,8 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){
        // These media files should now be caught in bbcode.php
        // left here as a fallback in case this is called from another source
 
-       $noexts = array("mp3","mp4","ogg","ogv","oga","ogm","webm");
-       $ext = pathinfo(strtolower($embedurl),PATHINFO_EXTENSION);
+       $noexts = array("mp3", "mp4", "ogg", "ogv", "oga", "ogm", "webm");
+       $ext = pathinfo(strtolower($embedurl), PATHINFO_EXTENSION);
 
 
        if (is_null($txt)) {
@@ -74,21 +74,10 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){
                        }
                }
 
-               if ($txt==false || $txt=="") {
-                       $embedly = Config::get("system", "embedly");
-                       if ($embedly != "") {
-                               // try embedly service
-                               $ourl = "https://api.embed.ly/1/oembed?key=".$embedly."&url=".urlencode($embedurl);
-                               $txt = fetch_url($ourl);
-
-                               logger("oembed_fetch_url: ".$txt, LOGGER_DEBUG);
-                       }
-               }
-
-               $txt=trim($txt);
+               $txt = trim($txt);
 
-               if ($txt[0]!="{") {
-                       $txt='{"type":"error"}';
+               if ($txt[0] != "{") {
+                       $txt = '{"type":"error"}';
                } else {        //save in cache
                        $j = json_decode($txt);
                        if ($j->type != "error") {
index 6061ef9e11847ba3117d2f9205695f4ba5715aec..7090e765feb154a6416048aaf8e494f0aa4d689b 100644 (file)
@@ -132,9 +132,6 @@ class ostatus {
                                        dbesc($contact["name"]), dbesc($contact["nick"]), dbesc($contact["alias"]),
                                        dbesc($contact["about"]), dbesc($contact["location"]),
                                        dbesc(datetime_convert()), intval($contact["id"]));
-
-                               poco_check($contact["url"], $contact["name"], $contact["network"], $author["author-avatar"], $contact["about"], $contact["location"],
-                                                       "", "", "", datetime_convert(), 2, $contact["id"], $contact["uid"]);
                        }
 
                        if (isset($author["author-avatar"]) AND ($author["author-avatar"] != $r[0]['avatar'])) {
@@ -163,7 +160,9 @@ class ostatus {
                        $contact["generation"] = 2;
                        $contact["hide"] = false; // OStatus contacts are never hidden
                        $contact["photo"] = $author["author-avatar"];
-                       update_gcontact($contact);
+                       $gcid = update_gcontact($contact);
+
+                       link_gcontact($gcid, $contact["uid"], $contact["id"]);
                }
 
                return($author);
@@ -808,6 +807,9 @@ class ostatus {
 
                /// @todo This function is totally ugly and has to be rewritten totally
 
+               // Import all threads or only threads that were started by our followers?
+               $all_threads = !get_config('system','ostatus_full_threads');
+
                $item_stored = -1;
 
                $conversation_url = self::fetch_conversation($self, $conversation_url);
@@ -816,8 +818,8 @@ class ostatus {
                // Don't do a completion on liked content
                if (((intval(get_config('system','ostatus_poll_interval')) == -2) AND (count($item) > 0)) OR
                        ($item["verb"] == ACTIVITY_LIKE) OR ($conversation_url == "")) {
-                       $item_stored = item_store($item, true);
-                       return($item_stored);
+                       $item_stored = item_store($item, $all_threads);
+                       return $item_stored;
                }
 
                // Get the parent
@@ -897,7 +899,7 @@ class ostatus {
 
                if (!sizeof($items)) {
                        if (count($item) > 0) {
-                               $item_stored = item_store($item, true);
+                               $item_stored = item_store($item, $all_threads);
 
                                if ($item_stored) {
                                        logger("Conversation ".$conversation_url." couldn't be fetched. Item uri ".$item["uri"]." stored: ".$item_stored, LOGGER_DEBUG);
@@ -1195,7 +1197,7 @@ class ostatus {
                                }
                        }
 
-                       $item_stored = item_store($item, true);
+                       $item_stored = item_store($item, $all_threads);
                        if ($item_stored) {
                                logger("Uri ".$item["uri"]." wasn't found in conversation ".$conversation_url, LOGGER_DEBUG);
                                self::store_conversation($item_stored, $conversation_url);
index f43ad62d088c71a829bb0342ed18775145333cc7..642d03d8911a6bf8b204f40ce9915bd092fbacbc 100644 (file)
@@ -34,7 +34,7 @@ require_once("include/Photo.php");
  */
 function poco_load($cid, $uid = 0, $zcid = 0, $url = null) {
        // Call the function "poco_load_worker" via the worker
-       proc_run(PRIORITY_LOW, "include/discover_poco.php", "poco_load", $cid, $uid, $zcid, base64_encode($url));
+       proc_run(PRIORITY_LOW, "include/discover_poco.php", "poco_load", intval($cid), intval($uid), intval($zcid), base64_encode($url));
 }
 
 /**
@@ -159,27 +159,27 @@ function poco_load_worker($cid, $uid, $zcid, $url) {
                if (isset($entry->contactType) AND ($entry->contactType >= 0))
                        $contact_type = $entry->contactType;
 
-               // If you query a Friendica server for its profiles, the network has to be Friendica
-               /// TODO It could also be a Redmatrix server
-               //if ($uid == 0)
-               //      $network = NETWORK_DFRN;
+               $gcontact = array("url" => $profile_url,
+                               "name" => $name,
+                               "network" => $network,
+                               "photo" => $profile_photo,
+                               "about" => $about,
+                               "location" => $location,
+                               "gender" => $gender,
+                               "keywords" => $keywords,
+                               "connect" => $connect_url,
+                               "updated" => $updated,
+                               "contact-type" => $contact_type,
+                               "generation" => $generation);
 
-               poco_check($profile_url, $name, $network, $profile_photo, $about, $location, $gender, $keywords, $connect_url, $updated, $generation, $cid, $uid, $zcid);
+               try {
+                       $gcontact = sanitize_gcontact($gcontact);
+                       $gcid = update_gcontact($gcontact);
 
-               $gcontact = array("url" => $profile_url, "contact-type" => $contact_type, "generation" => $generation);
-               update_gcontact($gcontact);
-
-               // Update the Friendica contacts. Diaspora is doing it via a message. (See include/diaspora.php)
-               // Deactivated because we now update Friendica contacts in dfrn.php
-               //if (($location != "") OR ($about != "") OR ($keywords != "") OR ($gender != ""))
-               //      q("UPDATE `contact` SET `location` = '%s', `about` = '%s', `keywords` = '%s', `gender` = '%s'
-               //              WHERE `nurl` = '%s' AND NOT `self` AND `network` = '%s'",
-               //              dbesc($location),
-               //              dbesc($about),
-               //              dbesc($keywords),
-               //              dbesc($gender),
-               //              dbesc(normalise_link($profile_url)),
-               //              dbesc(NETWORK_DFRN));
+                       link_gcontact($gcid, $uid, $cid, $zcid);
+               } catch (Exception $e) {
+                       logger($e->getMessage(), LOGGER_DEBUG);
+               }
        }
        logger("poco_load: loaded $total entries",LOGGER_DEBUG);
 
@@ -190,172 +190,158 @@ function poco_load_worker($cid, $uid, $zcid, $url) {
        );
 
 }
+/**
+ * @brief Sanitize the given gcontact data
+ *
+ * @param array $gcontact array with gcontact data
+ * @throw Exception
+ *
+ * Generation:
+ *  0: No definition
+ *  1: Profiles on this server
+ *  2: Contacts of profiles on this server
+ *  3: Contacts of contacts of profiles on this server
+ *  4: ...
+ *
+ */
+function sanitize_gcontact($gcontact) {
 
-function poco_check($profile_url, $name, $network, $profile_photo, $about, $location, $gender, $keywords, $connect_url, $updated, $generation, $cid = 0, $uid = 0, $zcid = 0) {
-
-       // Generation:
-       //  0: No definition
-       //  1: Profiles on this server
-       //  2: Contacts of profiles on this server
-       //  3: Contacts of contacts of profiles on this server
-       //  4: ...
-
-       $gcid = "";
-
-       if ($profile_url == "")
-               return $gcid;
+       if ($gcontact['url'] == "") {
+               throw new Exception('URL is empty');
+       }
 
-       $urlparts = parse_url($profile_url);
-       if (!isset($urlparts["scheme"]))
-               return $gcid;
+       $urlparts = parse_url($gcontact['url']);
+       if (!isset($urlparts["scheme"])) {
+               throw new Exception("This (".$gcontact['url'].") doesn't seem to be an url.");
+       }
 
        if (in_array($urlparts["host"], array("www.facebook.com", "facebook.com", "twitter.com",
-                                               "identi.ca", "alpha.app.net")))
-               return $gcid;
+                                               "identi.ca", "alpha.app.net"))) {
+               throw new Exception('Contact from a non federated network ignored. ('.$gcontact['url'].')');
+       }
 
        // Don't store the statusnet connector as network
        // We can't simply set this to NETWORK_OSTATUS since the connector could have fetched posts from friendica as well
-       if ($network == NETWORK_STATUSNET)
-               $network = "";
+       if ($gcontact['network'] == NETWORK_STATUSNET) {
+               $gcontact['network'] = "";
+       }
 
        // Assure that there are no parameter fragments in the profile url
-       if (in_array($network, array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, "")))
-               $profile_url = clean_contact_url($profile_url);
-
-       $alternate = poco_alternate_ostatus_url($profile_url);
+       if (in_array($gcontact['network'], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, ""))) {
+               $gcontact['url'] = clean_contact_url($gcontact['url']);
+       }
 
-       $orig_updated = $updated;
+       $alternate = poco_alternate_ostatus_url($gcontact['url']);
 
        // The global contacts should contain the original picture, not the cached one
-       if (($generation != 1) AND stristr(normalise_link($profile_photo), normalise_link(App::get_baseurl()."/photo/"))) {
-               $profile_photo = "";
+       if (($gcontact['generation'] != 1) AND stristr(normalise_link($gcontact['photo']), normalise_link(App::get_baseurl()."/photo/"))) {
+               $gcontact['photo'] = "";
        }
 
-       $r = q("SELECT `network` FROM `contact` WHERE `nurl` = '%s' AND `network` != '' AND `network` != '%s' LIMIT 1",
-               dbesc(normalise_link($profile_url)), dbesc(NETWORK_STATUSNET)
-       );
-       if (dbm::is_result($r)) {
-               $network = $r[0]["network"];
-       }
-
-       if (($network == "") OR ($network == NETWORK_OSTATUS)) {
-               $r = q("SELECT `network`, `url` FROM `contact` WHERE `alias` IN ('%s', '%s') AND `network` != '' AND `network` != '%s' LIMIT 1",
-                       dbesc($profile_url), dbesc(normalise_link($profile_url)), dbesc(NETWORK_STATUSNET)
+       if (!isset($gcontact['network'])) {
+               $r = q("SELECT `network` FROM `contact` WHERE `uid` = 0 AND `nurl` = '%s' AND `network` != '' AND `network` != '%s' LIMIT 1",
+                       dbesc(normalise_link($gcontact['url'])), dbesc(NETWORK_STATUSNET)
                );
                if (dbm::is_result($r)) {
-                       $network = $r[0]["network"];
-                       //$profile_url = $r[0]["url"];
+                       $gcontact['network'] = $r[0]["network"];
+               }
+
+               if (($gcontact['network'] == "") OR ($gcontact['network'] == NETWORK_OSTATUS)) {
+                       $r = q("SELECT `network`, `url` FROM `contact` WHERE `uid` = 0 AND `alias` IN ('%s', '%s') AND `network` != '' AND `network` != '%s' LIMIT 1",
+                               dbesc($gcontact['url']), dbesc(normalise_link($gcontact['url'])), dbesc(NETWORK_STATUSNET)
+                       );
+                       if (dbm::is_result($r)) {
+                               $gcontact['network'] = $r[0]["network"];
+                       }
                }
        }
 
+       $gcontact['server_url'] = '';
+       $gcontact['network'] = '';
+
        $x = q("SELECT * FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1",
-               dbesc(normalise_link($profile_url))
+               dbesc(normalise_link($gcontact['url']))
        );
 
        if (count($x)) {
-               if (($network == "") AND ($x[0]["network"] != NETWORK_STATUSNET)) {
-                       $network = $x[0]["network"];
-               }
-               if ($updated <= NULL_DATE) {
-                       $updated = $x[0]["updated"];
-               }
-               $created = $x[0]["created"];
-               $server_url = $x[0]["server_url"];
-               $nick = $x[0]["nick"];
-               $addr = $x[0]["addr"];
-               $alias =  $x[0]["alias"];
-               $notify =  $x[0]["notify"];
-       } else {
-               $created = NULL_DATE;
-               $server_url = "";
-
-               $urlparts = parse_url($profile_url);
-               $nick = end(explode("/", $urlparts["path"]));
-               $addr = "";
-               $alias = "";
-               $notify = "";
+               if (!isset($gcontact['network']) AND ($x[0]["network"] != NETWORK_STATUSNET)) {
+                       $gcontact['network'] = $x[0]["network"];
+               }
+               if ($gcontact['updated'] <= NULL_DATE) {
+                       $gcontact['updated'] = $x[0]["updated"];
+               }
+               if (!isset($gcontact['server_url']) AND (normalise_link($x[0]["server_url"]) != normalise_link($x[0]["url"]))) {
+                       $gcontact['server_url'] = $x[0]["server_url"];
+               }
+               if (!isset($gcontact['addr'])) {
+                       $gcontact['addr'] = $x[0]["addr"];
+               }
        }
 
-       if ((($network == "") OR ($name == "") OR ($addr == "") OR ($profile_photo == "") OR ($server_url == "") OR $alternate)
-               AND poco_reachable($profile_url, $server_url, $network, false)) {
-               $data = probe_url($profile_url);
+       if ((!isset($gcontact['network']) OR !isset($gcontact['name']) OR !isset($gcontact['addr']) OR !isset($gcontact['photo']) OR !isset($gcontact['server_url']) OR $alternate)
+               AND poco_reachable($gcontact['url'], $gcontact['server_url'], $gcontact['network'], false)) {
+               $data = Probe::uri($gcontact['url']);
+
+               if ($data["network"] == NETWORK_PHANTOM) {
+                       throw new Exception('Probing for URL '.$gcontact['url'].' failed');
+               }
+
+               $orig_profile = $gcontact['url'];
 
-               $orig_profile = $profile_url;
+               $gcontact["server_url"] = $data["baseurl"];
 
-               $network = $data["network"];
-               $name = $data["name"];
-               $nick = $data["nick"];
-               $addr = $data["addr"];
-               $alias = $data["alias"];
-               $notify = $data["notify"];
-               $profile_url = $data["url"];
-               $profile_photo = $data["photo"];
-               $server_url = $data["baseurl"];
+               $gcontact = array_merge($gcontact, $data);
 
-               if ($alternate AND ($network == NETWORK_OSTATUS)) {
+               if ($alternate AND ($gcontact['network'] == NETWORK_OSTATUS)) {
                        // Delete the old entry - if it exists
                        $r = q("SELECT `id` FROM `gcontact` WHERE `nurl` = '%s'", dbesc(normalise_link($orig_profile)));
                        if ($r) {
                                q("DELETE FROM `gcontact` WHERE `nurl` = '%s'", dbesc(normalise_link($orig_profile)));
                                q("DELETE FROM `glink` WHERE `gcid` = %d", intval($r[0]["id"]));
                        }
-
-                       // possibly create a new entry
-                       poco_check($profile_url, $name, $network, $profile_photo, $about, $location, $gender, $keywords, $connect_url, $updated, $generation, $cid, $uid, $zcid);
                }
        }
 
-       if ($alternate AND ($network == NETWORK_OSTATUS))
-               return $gcid;
+       if (!isset($gcontact['name']) OR !isset($gcontact['photo'])) {
+               throw new Exception('No name and photo for URL '.$gcontact['url']);
+       }
 
-       if (count($x) AND ($x[0]["network"] == "") AND ($network != "")) {
-               q("UPDATE `gcontact` SET `network` = '%s' WHERE `nurl` = '%s'",
-                       dbesc($network),
-                       dbesc(normalise_link($profile_url))
-               );
+       if (!in_array($gcontact['network'], array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA))) {
+               throw new Exception('No federated network ('.$gcontact['network'].') detected for URL '.$gcontact['url']);
        }
 
-       if (($name == "") OR ($profile_photo == ""))
-               return $gcid;
+       if (!isset($gcontact['server_url'])) {
+               // We check the server url to be sure that it is a real one
+               $server_url = poco_detect_server($gcontact['url']);
 
-       if (!in_array($network, array(NETWORK_DFRN, NETWORK_OSTATUS, NETWORK_DIASPORA)))
-               return $gcid;
+               // We are now sure that it is a correct URL. So we use it in the future
+               if ($server_url != "") {
+                       $gcontact['server_url'] = $server_url;
+               }
+       }
 
-       logger("profile-check generation: ".$generation." Network: ".$network." URL: ".$profile_url." name: ".$name." avatar: ".$profile_photo, LOGGER_DEBUG);
+       // The server URL doesn't seem to be valid, so we don't store it.
+       if (!poco_check_server($gcontact['server_url'], $gcontact['network'])) {
+               $gcontact['server_url'] = "";
+       }
 
-       // We check the server url to be sure that it is a real one
-       $server_url2 = poco_detect_server($profile_url);
+       return $gcontact;
+}
 
-       // We are no sure that it is a correct URL. So we use it in the future
-       if ($server_url2 != "") {
-               $server_url = $server_url2;
-       }
+/**
+ * @brief Link the gcontact entry with user, contact and global contact
+ *
+ * @param integer $gcid Global contact ID
+ * @param integer $cid Contact ID
+ * @param integer $uid User ID
+ * @param integer $zcid Global Contact ID
+ * *
+ */
+function link_gcontact($gcid, $uid = 0, $cid = 0, $zcid = 0) {
 
-       // The server URL doesn't seem to be valid, so we don't store it.
-       if (!poco_check_server($server_url, $network)) {
-               $server_url = "";
-       }
-
-       $gcontact = array("url" => $profile_url,
-                       "addr" => $addr,
-                       "alias" => $alias,
-                       "name" => $name,
-                       "network" => $network,
-                       "photo" => $profile_photo,
-                       "about" => $about,
-                       "location" => $location,
-                       "gender" => $gender,
-                       "keywords" => $keywords,
-                       "server_url" => $server_url,
-                       "connect" => $connect_url,
-                       "notify" => $notify,
-                       "updated" => $updated,
-                       "generation" => $generation);
-
-       $gcid = update_gcontact($gcontact);
-
-       if(!$gcid)
-               return $gcid;
+       if ($gcid <= 0) {
+               return;
+       }
 
        $r = q("SELECT * FROM `glink` WHERE `cid` = %d AND `uid` = %d AND `gcid` = %d AND `zcid` = %d LIMIT 1",
                intval($cid),
@@ -363,8 +349,8 @@ function poco_check($profile_url, $name, $network, $profile_photo, $about, $loca
                intval($gcid),
                intval($zcid)
        );
-       if (! dbm::is_result($r)) {
-               q("INSERT INTO `glink` (`cid`,`uid`,`gcid`,`zcid`, `updated`) VALUES (%d,%d,%d,%d, '%s') ",
+       if (!dbm::is_result($r)) {
+               q("INSERT INTO `glink` (`cid`, `uid`, `gcid`, `zcid`, `updated`) VALUES (%d, %d, %d, %d, '%s') ",
                        intval($cid),
                        intval($uid),
                        intval($gcid),
@@ -380,8 +366,6 @@ function poco_check($profile_url, $name, $network, $profile_photo, $about, $loca
                        intval($zcid)
                );
        }
-
-       return $gcid;
 }
 
 function poco_reachable($profile, $server = "", $network = "", $force = false) {
@@ -479,15 +463,26 @@ function poco_last_updated($profile, $force = false) {
        $gcontacts = q("SELECT * FROM `gcontact` WHERE `nurl` = '%s'",
                        dbesc(normalise_link($profile)));
 
+       if (!dbm::is_result($gcontacts)) {
+               return false;
+       }
+
+       $contact = array("url" => $profile);
+
        if ($gcontacts[0]["created"] <= NULL_DATE) {
-               q("UPDATE `gcontact` SET `created` = '%s' WHERE `nurl` = '%s'",
-                       dbesc(datetime_convert()), dbesc(normalise_link($profile)));
+               $contact['created'] = datetime_convert();
        }
-       if ($gcontacts[0]["server_url"] != "") {
+
+       if ($force) {
+               $server_url = normalise_link(poco_detect_server($profile));
+       }
+
+       if (($server_url == '') AND ($gcontacts[0]["server_url"] != "")) {
                $server_url = $gcontacts[0]["server_url"];
        }
-       if (($server_url == '') OR ($gcontacts[0]["server_url"] == $gcontacts[0]["nurl"])) {
-               $server_url = poco_detect_server($profile);
+
+       if (!$force AND (($server_url == '') OR ($gcontacts[0]["server_url"] == $gcontacts[0]["nurl"]))) {
+               $server_url = normalise_link(poco_detect_server($profile));
        }
 
        if (!in_array($gcontacts[0]["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_FEED, NETWORK_OSTATUS, ""))) {
@@ -497,67 +492,64 @@ function poco_last_updated($profile, $force = false) {
 
        if ($server_url != "") {
                if (!poco_check_server($server_url, $gcontacts[0]["network"], $force)) {
-
-                       if ($force)
+                       if ($force) {
                                q("UPDATE `gcontact` SET `last_failure` = '%s' WHERE `nurl` = '%s'",
                                        dbesc(datetime_convert()), dbesc(normalise_link($profile)));
+                       }
 
                        logger("Profile ".$profile.": Server ".$server_url." wasn't reachable.", LOGGER_DEBUG);
                        return false;
                }
-
-               q("UPDATE `gcontact` SET `server_url` = '%s' WHERE `nurl` = '%s'",
-                       dbesc($server_url), dbesc(normalise_link($profile)));
+               $contact['server_url'] = $server_url;
        }
 
        if (in_array($gcontacts[0]["network"], array("", NETWORK_FEED))) {
                $server = q("SELECT `network` FROM `gserver` WHERE `nurl` = '%s' AND `network` != ''",
                        dbesc(normalise_link($server_url)));
 
-               if ($server)
-                       q("UPDATE `gcontact` SET `network` = '%s' WHERE `nurl` = '%s'",
-                               dbesc($server[0]["network"]), dbesc(normalise_link($profile)));
-               else
+               if ($server) {
+                       $contact['network'] = $server[0]["network"];
+               } else {
                        return false;
+               }
        }
 
        // noscrape is really fast so we don't cache the call.
-       if (($gcontacts[0]["server_url"] != "") AND ($gcontacts[0]["nick"] != "")) {
+       if (($server_url != "") AND ($gcontacts[0]["nick"] != "")) {
 
                //  Use noscrape if possible
-               $server = q("SELECT `noscrape`, `network` FROM `gserver` WHERE `nurl` = '%s' AND `noscrape` != ''", dbesc(normalise_link($gcontacts[0]["server_url"])));
+               $server = q("SELECT `noscrape`, `network` FROM `gserver` WHERE `nurl` = '%s' AND `noscrape` != ''", dbesc(normalise_link($server_url)));
 
                if ($server) {
                        $noscraperet = z_fetch_url($server[0]["noscrape"]."/".$gcontacts[0]["nick"]);
 
-                        if ($noscraperet["success"] AND ($noscraperet["body"] != "")) {
+                       if ($noscraperet["success"] AND ($noscraperet["body"] != "")) {
 
                                $noscrape = json_decode($noscraperet["body"], true);
 
                                if (is_array($noscrape)) {
-                                       $contact = array("url" => $profile,
-                                                       "network" => $server[0]["network"],
-                                                       "generation" => $gcontacts[0]["generation"]);
+                                       $contact["network"] = $server[0]["network"];
 
-                                       if (isset($noscrape["fn"]))
+                                       if (isset($noscrape["fn"])) {
                                                $contact["name"] = $noscrape["fn"];
-
-                                       if (isset($noscrape["comm"]))
+                                       }
+                                       if (isset($noscrape["comm"])) {
                                                $contact["community"] = $noscrape["comm"];
-
+                                       }
                                        if (isset($noscrape["tags"])) {
                                                $keywords = implode(" ", $noscrape["tags"]);
-                                               if ($keywords != "")
+                                               if ($keywords != "") {
                                                        $contact["keywords"] = $keywords;
+                                               }
                                        }
 
                                        $location = formatted_location($noscrape);
-                                       if ($location)
+                                       if ($location) {
                                                $contact["location"] = $location;
-
-                                       if (isset($noscrape["dfrn-notify"]))
+                                       }
+                                       if (isset($noscrape["dfrn-notify"])) {
                                                $contact["notify"] = $noscrape["dfrn-notify"];
-
+                                       }
                                        // Remove all fields that are not present in the gcontact table
                                        unset($noscrape["fn"]);
                                        unset($noscrape["key"]);
@@ -595,12 +587,14 @@ function poco_last_updated($profile, $force = false) {
        }
 
        // If we only can poll the feed, then we only do this once a while
-       if (!$force AND !poco_do_update($gcontacts[0]["created"], $gcontacts[0]["updated"], $gcontacts[0]["last_failure"],  $gcontacts[0]["last_contact"])) {
+       if (!$force AND !poco_do_update($gcontacts[0]["created"], $gcontacts[0]["updated"], $gcontacts[0]["last_failure"], $gcontacts[0]["last_contact"])) {
                logger("Profile ".$profile." was last updated at ".$gcontacts[0]["updated"]." (cached)", LOGGER_DEBUG);
+
+               update_gcontact($contact);
                return $gcontacts[0]["updated"];
        }
 
-       $data = probe_url($profile);
+       $data = Probe::uri($profile);
 
        // Is the profile link the alternate OStatus link notation? (http://domain.tld/user/4711)
        // Then check the other link and delete this one
@@ -612,10 +606,18 @@ function poco_last_updated($profile, $force = false) {
                q("DELETE FROM `gcontact` WHERE `nurl` = '%s'", dbesc(normalise_link($profile)));
                q("DELETE FROM `glink` WHERE `gcid` = %d", intval($gcontacts[0]["id"]));
 
-               poco_check($data["url"], $data["name"], $data["network"], $data["photo"], $gcontacts[0]["about"], $gcontacts[0]["location"],
-                               $gcontacts[0]["gender"], $gcontacts[0]["keywords"], $data["addr"], $gcontacts[0]["updated"], $gcontacts[0]["generation"]);
+               $gcontact = array_merge($gcontacts[0], $data);
+
+               $gcontact["server_url"] = $data["baseurl"];
+
+               try {
+                       $gcontact = sanitize_gcontact($gcontact);
+                       update_gcontact($gcontact);
 
-               poco_last_updated($data["url"], $force);
+                       poco_last_updated($data["url"], $force);
+               } catch (Exception $e) {
+                       logger($e->getMessage(), LOGGER_DEBUG);
+               }
 
                logger("Profile ".$profile." was deleted", LOGGER_DEBUG);
                return false;
@@ -629,21 +631,10 @@ function poco_last_updated($profile, $force = false) {
                return false;
        }
 
-       $contact = array("generation" => $gcontacts[0]["generation"]);
-
        $contact = array_merge($contact, $data);
 
        $contact["server_url"] = $data["baseurl"];
 
-       unset($contact["batch"]);
-       unset($contact["poll"]);
-       unset($contact["request"]);
-       unset($contact["confirm"]);
-       unset($contact["poco"]);
-       unset($contact["priority"]);
-       unset($contact["pubkey"]);
-       unset($contact["baseurl"]);
-
        update_gcontact($contact);
 
        $feedret = z_fetch_url($data["poll"]);
@@ -686,9 +677,10 @@ function poco_last_updated($profile, $force = false) {
        q("UPDATE `gcontact` SET `updated` = '%s', `last_contact` = '%s' WHERE `nurl` = '%s'",
                dbesc(dbm::date($last_updated)), dbesc(dbm::date()), dbesc(normalise_link($profile)));
 
-       if (($gcontacts[0]["generation"] == 0))
+       if (($gcontacts[0]["generation"] == 0)) {
                q("UPDATE `gcontact` SET `generation` = 9 WHERE `nurl` = '%s'",
                        dbesc(normalise_link($profile)));
+       }
 
        logger("Profile ".$profile." was last updated at ".$last_updated, LOGGER_DEBUG);
 
@@ -1769,7 +1761,7 @@ function poco_discover($complete = false) {
                        }
 
                        logger('Update directory from server '.$server['url'].' with ID '.$server['id'], LOGGER_DEBUG);
-                       proc_run(PRIORITY_LOW, "include/discover_poco.php", "update_server_directory", $server['id']);
+                       proc_run(PRIORITY_LOW, "include/discover_poco.php", "update_server_directory", intval($server['id']));
 
                        if (!$complete AND (--$no_of_queries == 0)) {
                                break;
@@ -1889,10 +1881,26 @@ function poco_discover_server($data, $default_generation = 0) {
                        $success = true;
 
                        logger("Store profile ".$profile_url, LOGGER_DEBUG);
-                       poco_check($profile_url, $name, $network, $profile_photo, $about, $location, $gender, $keywords, $connect_url, $updated, $generation, 0, 0, 0);
 
-                       $gcontact = array("url" => $profile_url, "contact-type" => $contact_type, "generation" => $generation);
-                       update_gcontact($gcontact);
+                       $gcontact = array("url" => $profile_url,
+                                       "name" => $name,
+                                       "network" => $network,
+                                       "photo" => $profile_photo,
+                                       "about" => $about,
+                                       "location" => $location,
+                                       "gender" => $gender,
+                                       "keywords" => $keywords,
+                                       "connect" => $connect_url,
+                                       "updated" => $updated,
+                                       "contact-type" => $contact_type,
+                                       "generation" => $generation);
+
+                       try {
+                               $gcontact = sanitize_gcontact($gcontact);
+                               update_gcontact($gcontact);
+                       } catch (Exception $e) {
+                               logger($e->getMessage(), LOGGER_DEBUG);
+                       }
 
                        logger("Done for profile ".$profile_url, LOGGER_DEBUG);
                }
@@ -2187,6 +2195,8 @@ function update_gcontact_from_probe($url) {
                return;
        }
 
+       $data["server_url"] = $data["baseurl"];
+
        update_gcontact($data);
 }
 
index df871c5468ac7d3abb7087adb87635b453633d25..973d6b8b1f808b3bbd46ccd0675885d6e8e62ae0 100644 (file)
@@ -97,13 +97,6 @@ function create_user($arr) {
        if(mb_strlen($username) < 3)
                $result['message'] .= t('Name too short.') . EOL;
 
-       // I don't really like having this rule, but it cuts down
-       // on the number of auto-registrations by Russian spammers
-
-       //  Using preg_match was completely unreliable, due to mixed UTF-8 regex support
-       //      $no_utf = get_config('system','no_utf');
-       //      $pat = (($no_utf) ? '/^[a-zA-Z]* [a-zA-Z]*$/' : '/^\p{L}* \p{L}*$/u' );
-
        // So now we are just looking for a space in the full name.
 
        $loose_reg = get_config('system','no_regfullname');
@@ -182,17 +175,7 @@ function create_user($arr) {
        $prvkey = $keys['prvkey'];
        $pubkey = $keys['pubkey'];
 
-       /**
-        *
-        * Create another keypair for signing/verifying
-        * salmon protocol messages. We have to use a slightly
-        * less robust key because this won't be using openssl
-        * but the phpseclib. Since it is PHP interpreted code
-        * it is not nearly as efficient, and the larger keys
-        * will take several minutes each to process.
-        *
-        */
-
+       // Create another keypair for signing/verifying salmon protocol messages.
        $sres    = new_keypair(512);
        $sprvkey = $sres['prvkey'];
        $spubkey = $sres['pubkey'];
index 60b5a62cc126991beef986b0812d8a3f0f0e0c90..5b60f6f121ce12c19a842a84f6428ee30176ba0d 100644 (file)
@@ -342,9 +342,9 @@ final class Crypto
      */
     private static function SecureRandom($octets)
     {
-        self::EnsureFunctionExists("mcrypt_create_iv");
-        $random = mcrypt_create_iv($octets, MCRYPT_DEV_URANDOM);
-        if ($random === FALSE) {
+        self::EnsureFunctionExists("openssl_random_pseudo_bytes");
+        $random = openssl_random_pseudo_bytes($octets, $crypto_strong);
+        if ($crypto_strong === FALSE) {
             throw new CannotPerformOperationException();
         } else {
             return $random;
index a8152c2ab61929b8e6b75fb45adf14ee0839991b..769bdb1219745fd68e338cc2de97f161c6477d48 100644 (file)
@@ -1,24 +1,17 @@
 <?php
-//# Install PSR-0-compatible class autoloader
-//spl_autoload_register(function($class){
-//     require preg_replace('{\\\\|_(?!.*\\\\)}', DIRECTORY_SEPARATOR, ltrim($class, '\\')).'.php';
-//});
-
-require_once("library/php-markdown/Michelf/MarkdownExtra.inc.php");
-# Get Markdown class
+require_once "library/php-markdown/Michelf/MarkdownExtra.inc.php";
 use \Michelf\MarkdownExtra;
 
 function Markdown($text) {
-
        $a = get_app();
 
        $stamp1 = microtime(true);
 
-       # Read file and pass content through the Markdown parser
-       $html = MarkdownExtra::defaultTransform($text);
+       $MarkdownParser = new MarkdownExtra();
+       $MarkdownParser->hard_wrap = true;
+       $html = $MarkdownParser->transform($text);
 
        $a->save_timestamp($stamp1, "parser");
 
        return $html;
 }
-?>
diff --git a/library/oauth.php b/library/oauth.php
deleted file mode 100644 (file)
index caf1a08..0000000
+++ /dev/null
@@ -1,728 +0,0 @@
-<?php
-
-//ini_set('display_errors', 1);
-//error_reporting(E_ALL | E_STRICT);
-
-// Regex to filter out the client identifier
-// (described in Section 2 of IETF draft)
-// IETF draft does not prescribe a format for these, however
-// I've arbitrarily chosen alphanumeric strings with hyphens and underscores, 3-12 characters long
-// Feel free to change.
-define("REGEX_CLIENT_ID", "/^[a-z0-9-_]{3,12}$/i");
-
-// Used to define the name of the OAuth access token parameter (POST/GET/etc.)
-// IETF Draft sections 5.2 and 5.3 specify that it should be called "oauth_token"
-// but other implementations use things like "access_token"
-// I won't be heartbroken if you change it, but it might be better to adhere to the spec
-define("OAUTH_TOKEN_PARAM_NAME", "oauth_token");
-
-// Client types (for client authorization)
-//define("WEB_SERVER_CLIENT_TYPE", "web_server");
-//define("USER_AGENT_CLIENT_TYPE", "user_agent");
-//define("REGEX_CLIENT_TYPE", "/^(web_server|user_agent)$/");
-define("ACCESS_TOKEN_AUTH_RESPONSE_TYPE", "token");
-define("AUTH_CODE_AUTH_RESPONSE_TYPE", "code");
-define("CODE_AND_TOKEN_AUTH_RESPONSE_TYPE", "code-and-token");
-define("REGEX_AUTH_RESPONSE_TYPE", "/^(token|code|code-and-token)$/");
-
-// Grant Types (for token obtaining)
-define("AUTH_CODE_GRANT_TYPE", "authorization-code");
-define("USER_CREDENTIALS_GRANT_TYPE", "basic-credentials");
-define("ASSERTION_GRANT_TYPE", "assertion");
-define("REFRESH_TOKEN_GRANT_TYPE", "refresh-token");
-define("NONE_GRANT_TYPE", "none");
-define("REGEX_TOKEN_GRANT_TYPE", "/^(authorization-code|basic-credentials|assertion|refresh-token|none)$/");
-
-/* Error handling constants */
-
-// HTTP status codes
-define("ERROR_NOT_FOUND", "404 Not Found");
-define("ERROR_BAD_REQUEST", "400 Bad Request");
-
-// TODO: Extend for i18n
-
-// "Official" OAuth 2.0 errors
-define("ERROR_REDIRECT_URI_MISMATCH", "redirect-uri-mismatch");
-define("ERROR_INVALID_CLIENT_CREDENTIALS", "invalid-client-credentials");
-define("ERROR_UNAUTHORIZED_CLIENT", "unauthorized-client");
-define("ERROR_USER_DENIED", "access-denied");
-define("ERROR_INVALID_REQUEST", "invalid-request");
-define("ERROR_INVALID_CLIENT_ID", "invalid-client-id");
-define("ERROR_UNSUPPORTED_RESPONSE_TYPE", "unsupported-response-type");
-define("ERROR_INVALID_SCOPE", "invalid-scope");
-define("ERROR_INVALID_GRANT", "invalid-grant");
-
-// Protected resource errors
-define("ERROR_INVALID_TOKEN", "invalid-token");
-define("ERROR_EXPIRED_TOKEN", "expired-token");
-define("ERROR_INSUFFICIENT_SCOPE", "insufficient-scope");
-
-// Messages
-define("ERROR_INVALID_RESPONSE_TYPE", "Invalid response type.");
-
-// Errors that we made up
-
-// Error for trying to use a grant type that we haven't implemented
-define("ERROR_UNSUPPORTED_GRANT_TYPE", "unsupported-grant-type");
-
-abstract class OAuth2 {
-
-    /* Subclasses must implement the following functions */
-
-    // Make sure that the client id is valid
-    // If a secret is required, check that they've given the right one
-    // Must return false if the client credentials are invalid
-    abstract protected function auth_client_credentials($client_id, $client_secret = null);
-
-    // OAuth says we should store request URIs for each registered client
-    // Implement this function to grab the stored URI for a given client id
-    // Must return false if the given client does not exist or is invalid
-    abstract protected function get_redirect_uri($client_id);
-
-    // We need to store and retrieve access token data as we create and verify tokens
-    // Implement these functions to do just that
-
-    // Look up the supplied token id from storage, and return an array like:
-    //
-    //  array(
-    //      "client_id" => <stored client id>,
-    //      "expires" => <stored expiration timestamp>,
-    //      "scope" => <stored scope (may be null)
-    //  )
-    //
-    //  Return null if the supplied token is invalid
-    //
-    abstract protected function get_access_token($token_id);
-
-    // Store the supplied values
-    abstract protected function store_access_token($token_id, $client_id, $expires, $scope = null);
-
-    /*
-     *
-     * Stuff that should get overridden by subclasses
-     *
-     * I don't want to make these abstract, because then subclasses would have
-     * to implement all of them, which is too much work.
-     *
-     * So they're just stubs.  Override the ones you need.
-     *
-     */
-
-    // You should override this function with something,
-    // or else your OAuth provider won't support any grant types!
-    protected function get_supported_grant_types() {
-        // If you support all grant types, then you'd do:
-        // return array(
-        //             AUTH_CODE_GRANT_TYPE,
-        //             USER_CREDENTIALS_GRANT_TYPE,
-        //             ASSERTION_GRANT_TYPE,
-        //             REFRESH_TOKEN_GRANT_TYPE,
-        //             NONE_GRANT_TYPE
-        //     );
-
-        return array();
-    }
-
-    // You should override this function with your supported response types
-    protected function get_supported_auth_response_types() {
-        return array(
-            AUTH_CODE_AUTH_RESPONSE_TYPE,
-            ACCESS_TOKEN_AUTH_RESPONSE_TYPE,
-            CODE_AND_TOKEN_AUTH_RESPONSE_TYPE
-        );
-    }
-
-    // If you want to support scope use, then have this function return a list
-    // of all acceptable scopes (used to throw the invalid-scope error)
-    protected function get_supported_scopes() {
-        //  Example:
-        //  return array("my-friends", "photos", "whatever-else");
-        return array();
-    }
-
-    // If you want to restrict clients to certain authorization response types,
-    // override this function
-    // Given a client identifier and auth type, return true or false
-    // (auth type would be one of the values contained in REGEX_AUTH_RESPONSE_TYPE)
-    protected function authorize_client_response_type($client_id, $response_type) {
-        return true;
-    }
-
-    // If you want to restrict clients to certain grant types, override this function
-    // Given a client identifier and grant type, return true or false
-    protected function authorize_client($client_id, $grant_type) {
-        return true;
-    }
-
-    /* Functions that help grant access tokens for various grant types */
-
-    // Fetch authorization code data (probably the most common grant type)
-    // IETF Draft 4.1.1: http://tools.ietf.org/html/draft-ietf-oauth-v2-08#section-4.1.1
-    // Required for AUTH_CODE_GRANT_TYPE
-    protected function get_stored_auth_code($code) {
-        // Retrieve the stored data for the given authorization code
-        // Should return:
-        //
-        // array (
-        //  "client_id" => <stored client id>,
-        //  "redirect_uri" => <stored redirect URI>,
-        //  "expires" => <stored code expiration time>,
-        //  "scope" => <stored scope values (space-separated string), or can be omitted if scope is unused>
-        // )
-        //
-        // Return null if the code is invalid.
-
-        return null;
-    }
-
-    // Take the provided authorization code values and store them somewhere (db, etc.)
-    // Required for AUTH_CODE_GRANT_TYPE
-    protected function store_auth_code($code, $client_id, $redirect_uri, $expires, $scope) {
-        // This function should be the storage counterpart to get_stored_auth_code
-
-        // If storage fails for some reason, we're not currently checking
-        // for any sort of success/failure, so you should bail out of the
-        // script and provide a descriptive fail message
-    }
-
-    // Grant access tokens for basic user credentials
-    // IETF Draft 4.1.2: http://tools.ietf.org/html/draft-ietf-oauth-v2-08#section-4.1.2
-    // Required for USER_CREDENTIALS_GRANT_TYPE
-    protected function check_user_credentials($client_id, $username, $password) {
-        // Check the supplied username and password for validity
-        // You can also use the $client_id param to do any checks required
-        // based on a client, if you need that
-        // If the username and password are invalid, return false
-
-        // If the username and password are valid, and you want to verify the scope of
-        // a user's access, return an array with the scope values, like so:
-        //
-        // array (
-        //  "scope" => <stored scope values (space-separated string)>
-        // )
-        //
-        // We'll check the scope you provide against the requested scope before
-        // providing an access token.
-        //
-        // Otherwise, just return true.
-
-        return false;
-    }
-
-    // Grant access tokens for assertions
-    // IETF Draft 4.1.3: http://tools.ietf.org/html/draft-ietf-oauth-v2-08#section-4.1.3
-    // Required for ASSERTION_GRANT_TYPE
-    protected function check_assertion($client_id, $assertion_type, $assertion) {
-        // Check the supplied assertion for validity
-        // You can also use the $client_id param to do any checks required
-        // based on a client, if you need that
-        // If the assertion is invalid, return false
-
-        // If the assertion is valid, and you want to verify the scope of
-        // an access request, return an array with the scope values, like so:
-        //
-        // array (
-        //  "scope" => <stored scope values (space-separated string)>
-        // )
-        //
-        // We'll check the scope you provide against the requested scope before
-        // providing an access token.
-        //
-        // Otherwise, just return true.
-
-        return false;
-    }
-
-    // Grant refresh access tokens
-    // IETF Draft 4.1.4: http://tools.ietf.org/html/draft-ietf-oauth-v2-08#section-4.1.4
-    // Required for REFRESH_TOKEN_GRANT_TYPE
-    protected function get_refresh_token($refresh_token) {
-        // Retrieve the stored data for the given refresh token
-        // Should return:
-        //
-        // array (
-        //  "client_id" => <stored client id>,
-        //  "expires" => <refresh token expiration time>,
-        //  "scope" => <stored scope values (space-separated string), or can be omitted if scope is unused>
-        // )
-        //
-        // Return null if the token id is invalid.
-
-        return null;
-    }
-
-    // Store refresh access tokens
-    // Required for REFRESH_TOKEN_GRANT_TYPE
-    protected function store_refresh_token($token, $client_id, $expires, $scope = null) {
-        // If storage fails for some reason, we're not currently checking
-        // for any sort of success/failure, so you should bail out of the
-        // script and provide a descriptive fail message
-
-        return;
-    }
-
-    // Grant access tokens for the "none" grant type
-    // Not really described in the IETF Draft, so I just left a method stub...do whatever you want!
-    // Required for NONE_GRANT_TYPE
-    protected function check_none_access($client_id) {
-        return false;
-    }
-
-    protected function get_default_authentication_realm() {
-        // Change this to whatever authentication realm you want to send in a WWW-Authenticate header
-        return "Service";
-    }
-
-    /* End stuff that should get overridden */
-
-    private $access_token_lifetime = 3600;
-    private $auth_code_lifetime = 30;
-    private $refresh_token_lifetime = 1209600; // Two weeks
-
-    public function __construct($access_token_lifetime = 3600, $auth_code_lifetime = 30, $refresh_token_lifetime = 1209600) {
-        $this->access_token_lifetime = $access_token_lifetime;
-        $this->auth_code_lifetime = $auth_code_lifetime;
-        $this->refresh_token_lifetime = $refresh_token_lifetime;
-    }
-
-    /* Resource protecting (Section 5) */
-
-    // Check that a valid access token has been provided
-    //
-    // The scope parameter defines any required scope that the token must have
-    // If a scope param is provided and the token does not have the required scope,
-    // we bounce the request
-    //
-    // Some implementations may choose to return a subset of the protected resource
-    // (i.e. "public" data) if the user has not provided an access token
-    // or if the access token is invalid or expired
-    //
-    // The IETF spec says that we should send a 401 Unauthorized header and bail immediately
-    // so that's what the defaults are set to
-    //
-    // Here's what each parameter does:
-    // $scope = A space-separated string of required scope(s), if you want to check for scope
-    // $exit_not_present = If true and no access token is provided, send a 401 header and exit, otherwise return false
-    // $exit_invalid = If true and the implementation of get_access_token returns null, exit, otherwise return false
-    // $exit_expired = If true and the access token has expired, exit, otherwise return false
-    // $exit_scope = If true the access token does not have the required scope(s), exit, otherwise return false
-    // $realm = If you want to specify a particular realm for the WWW-Authenticate header, supply it here
-    public function verify_access_token($scope = null, $exit_not_present = true, $exit_invalid = true, $exit_expired = true, $exit_scope = true, $realm = null) {
-        $token_param = $this->get_access_token_param();
-        if ($token_param === false) // Access token was not provided
-            return $exit_not_present ? $this->send_401_unauthorized($realm, $scope) : false;
-
-        // Get the stored token data (from the implementing subclass)
-        $token = $this->get_access_token($token_param);
-        if ($token === null)
-            return $exit_invalid ? $this->send_401_unauthorized($realm, $scope, ERROR_INVALID_TOKEN) : false;
-
-        // Check token expiration (I'm leaving this check separated, later we'll fill in better error messages)
-        if (isset($token["expires"]) && time() > $token["expires"])
-            return $exit_expired ? $this->send_401_unauthorized($realm, $scope, ERROR_EXPIRED_TOKEN) : false;
-
-        // Check scope, if provided
-        // If token doesn't have a scope, it's null/empty, or it's insufficient, then throw an error
-        if ($scope &&
-                (!isset($token["scope"]) || !$token["scope"] || !$this->check_scope($scope, $token["scope"])))
-            return $exit_scope ? $this->send_401_unauthorized($realm, $scope, ERROR_INSUFFICIENT_SCOPE) : false;
-
-        return true;
-    }
-
-
-    // Returns true if everything in required scope is contained in available scope
-    // False if something in required scope is not in available scope
-    private function check_scope($required_scope, $available_scope) {
-        // The required scope should match or be a subset of the available scope
-        if (!is_array($required_scope))
-            $required_scope = explode(" ", $required_scope);
-
-        if (!is_array($available_scope))
-            $available_scope = explode(" ", $available_scope);
-
-        return (count(array_diff($required_scope, $available_scope)) == 0);
-    }
-
-    // Send a 401 unauthorized header with the given realm
-    // and an error, if provided
-    private function send_401_unauthorized($realm, $scope, $error = null) {
-        $realm = $realm === null ? $this->get_default_authentication_realm() : $realm;
-
-        $auth_header = "WWW-Authenticate: Token realm='".$realm."'";
-
-        if ($scope)
-            $auth_header .= ", scope='".$scope."'";
-
-        if ($error !== null)
-            $auth_header .= ", error='".$error."'";
-
-        header("HTTP/1.1 401 Unauthorized");
-        header($auth_header);
-
-        exit;
-    }
-
-    // Pulls the access token out of the HTTP request
-    // Either from the Authorization header or GET/POST/etc.
-    // Returns false if no token is present
-    // TODO: Support POST or DELETE
-    private function get_access_token_param() {
-        $auth_header = $this->get_authorization_header();
-
-        if ($auth_header !== false) {
-            // Make sure only the auth header is set
-            if (isset($_GET[OAUTH_TOKEN_PARAM_NAME]) || isset($_POST[OAUTH_TOKEN_PARAM_NAME]))
-                $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_REQUEST);
-
-            $auth_header = trim($auth_header);
-
-            // Make sure it's Token authorization
-            if (strcmp(substr($auth_header, 0, 6),"Token ") !== 0)
-                $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_REQUEST);
-
-            // Parse the rest of the header
-            if (preg_match('/\s*token\s*="(.+)"/', substr($auth_header, 6), $matches) == 0 || count($matches) < 2)
-                $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_REQUEST);
-
-            return $matches[1];
-        }
-
-        if (isset($_GET[OAUTH_TOKEN_PARAM_NAME]))  {
-            if (isset($_POST[OAUTH_TOKEN_PARAM_NAME])) // Both GET and POST are not allowed
-                $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_REQUEST);
-
-            return $_GET[OAUTH_TOKEN_PARAM_NAME];
-        }
-
-        if (isset($_POST[OAUTH_TOKEN_PARAM_NAME]))
-            return $_POST[OAUTH_TOKEN_PARAM_NAME];
-
-        return false;
-    }
-
-    /* Access token granting (Section 4) */
-
-    // Grant or deny a requested access token
-    // This would be called from the "/token" endpoint as defined in the spec
-    // Obviously, you can call your endpoint whatever you want
-    public function grant_access_token() {
-        $filters = array(
-            "grant_type" => array("filter" => FILTER_VALIDATE_REGEXP, "options" => array("regexp" => REGEX_TOKEN_GRANT_TYPE), "flags" => FILTER_REQUIRE_SCALAR),
-            "scope" => array("flags" => FILTER_REQUIRE_SCALAR),
-            "code" => array("flags" => FILTER_REQUIRE_SCALAR),
-            "redirect_uri" => array("filter" => FILTER_VALIDATE_URL, "flags" => array(FILTER_FLAG_SCHEME_REQUIRED, FILTER_REQUIRE_SCALAR)),
-            "username" => array("flags" => FILTER_REQUIRE_SCALAR),
-            "password" => array("flags" => FILTER_REQUIRE_SCALAR),
-            "assertion_type" => array("flags" => FILTER_REQUIRE_SCALAR),
-            "assertion" => array("flags" => FILTER_REQUIRE_SCALAR),
-            "refresh_token" => array("flags" => FILTER_REQUIRE_SCALAR),
-        );
-
-        $input = filter_input_array(INPUT_POST, $filters);
-
-        // Grant Type must be specified.
-        if (!$input["grant_type"])
-            $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_REQUEST);
-
-        // Make sure we've implemented the requested grant type
-        if (!in_array($input["grant_type"], $this->get_supported_grant_types()))
-            $this->error(ERROR_BAD_REQUEST, ERROR_UNSUPPORTED_GRANT_TYPE);
-
-        // Authorize the client
-        $client = $this->get_client_credentials();
-
-        if ($this->auth_client_credentials($client[0], $client[1]) === false)
-            $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_CLIENT_CREDENTIALS);
-
-        if (!$this->authorize_client($client[0], $input["grant_type"]))
-            $this->error(ERROR_BAD_REQUEST, ERROR_UNAUTHORIZED_CLIENT);
-
-        // Do the granting
-        switch ($input["grant_type"]) {
-            case AUTH_CODE_GRANT_TYPE:
-                if (!$input["code"] || !$input["redirect_uri"])
-                    $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_REQUEST);
-
-                $stored = $this->get_stored_auth_code($input["code"]);
-
-                if ($stored === null || $input["redirect_uri"] != $stored["redirect_uri"] || $client[0] != $stored["client_id"])
-                    $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_GRANT);
-
-                if ($stored["expires"] > time())
-                    $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_GRANT);
-
-                break;
-            case USER_CREDENTIALS_GRANT_TYPE:
-                if (!$input["username"] || !$input["password"])
-                    $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_REQUEST);
-
-                $stored = $this->check_user_credentials($client[0], $input["username"], $input["password"]);
-
-                if ($stored === false)
-                    $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_GRANT);
-
-                break;
-            case ASSERTION_GRANT_TYPE:
-                if (!$input["assertion_type"] || !$input["assertion"])
-                    $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_REQUEST);
-
-                $stored = $this->check_assertion($client[0], $input["assertion_type"], $input["assertion"]);
-
-                if ($stored === false)
-                    $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_GRANT);
-
-                break;
-            case REFRESH_TOKEN_GRANT_TYPE:
-                if (!$input["refresh_token"])
-                    $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_REQUEST);
-
-                $stored = $this->get_refresh_token($input["refresh_token"]);
-
-                if ($stored === null || $client[0] != $stored["client_id"])
-                    $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_GRANT);
-
-                if ($stored["expires"] > time())
-                    $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_GRANT);
-
-                break;
-            case NONE_GRANT_TYPE:
-                $stored = $this->check_none_access($client[0]);
-
-                if ($stored === false)
-                    $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_REQUEST);
-        }
-
-        // Check scope, if provided
-        if ($input["scope"] && (!is_array($stored) || !isset($stored["scope"]) || !$this->check_scope($input["scope"], $stored["scope"])))
-            $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_SCOPE);
-
-        if (!$input["scope"])
-            $input["scope"] = null;
-
-        $token = $this->create_access_token($client[0], $input["scope"]);
-
-        $this->send_json_headers();
-        echo json_encode($token);
-    }
-
-    // Internal function used to get the client credentials from HTTP basic auth or POST data
-    // See http://tools.ietf.org/html/draft-ietf-oauth-v2-08#section-2
-    private function get_client_credentials() {
-        if (isset($_SERVER["PHP_AUTH_USER"]) && $_POST && isset($_POST["client_id"]))
-            $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_CLIENT_CREDENTIALS);
-
-        // Try basic auth
-        if (isset($_SERVER["PHP_AUTH_USER"]))
-            return array($_SERVER["PHP_AUTH_USER"], $_SERVER["PHP_AUTH_PW"]);
-
-        // Try POST
-        if ($_POST && isset($_POST["client_id"])) {
-            if (isset($_POST["client_secret"]))
-                return array($_POST["client_id"], $_POST["client_secret"]);
-
-            return array($_POST["client_id"], NULL);
-        }
-
-        // No credentials were specified
-        $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_CLIENT_CREDENTIALS);
-    }
-
-    /* End-user/client Authorization (Section 3 of IETF Draft) */
-
-    // Pull the authorization request data out of the HTTP request
-    // and return it so the authorization server can prompt the user
-    // for approval
-    public function get_authorize_params() {
-        $filters = array(
-            "client_id" => array("filter" => FILTER_VALIDATE_REGEXP, "options" => array("regexp" => REGEX_CLIENT_ID), "flags" => FILTER_REQUIRE_SCALAR),
-            "response_type" => array("filter" => FILTER_VALIDATE_REGEXP, "options" => array("regexp" => REGEX_AUTH_RESPONSE_TYPE), "flags" => FILTER_REQUIRE_SCALAR),
-            "redirect_uri" => array("filter" => FILTER_VALIDATE_URL, "flags" => array(FILTER_FLAG_SCHEME_REQUIRED, FILTER_REQUIRE_SCALAR)),
-            "state" => array("flags" => FILTER_REQUIRE_SCALAR),
-            "scope" => array("flags" => FILTER_REQUIRE_SCALAR),
-        );
-
-        $input = filter_input_array(INPUT_GET, $filters);
-
-        // Make sure a valid client id was supplied
-        if (!$input["client_id"]) {
-            if ($input["redirect_uri"])
-                $this->callback_error($input["redirect_uri"], ERROR_INVALID_CLIENT_ID, $input["state"]);
-
-            $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_CLIENT_ID); // We don't have a good URI to use
-        }
-
-        // redirect_uri is not required if already established via other channels
-        // check an existing redirect URI against the one supplied
-        $redirect_uri = $this->get_redirect_uri($input["client_id"]);
-
-        // At least one of: existing redirect URI or input redirect URI must be specified
-        if (!$redirect_uri && !$input["redirect_uri"])
-            $this->error(ERROR_BAD_REQUEST, ERROR_INVALID_REQUEST);
-
-        // get_redirect_uri should return false if the given client ID is invalid
-        // this probably saves us from making a separate db call, and simplifies the method set
-        if ($redirect_uri === false)
-            $this->callback_error($input["redirect_uri"], ERROR_INVALID_CLIENT_ID, $input["state"]);
-
-        // If there's an existing uri and one from input, verify that they match
-        if ($redirect_uri && $input["redirect_uri"]) {
-            // Ensure that the input uri starts with the stored uri
-            if (strcasecmp(substr($input["redirect_uri"], 0, strlen($redirect_uri)),$redirect_uri) !== 0)
-                $this->callback_error($input["redirect_uri"], ERROR_REDIRECT_URI_MISMATCH, $input["state"]);
-        } elseif ($redirect_uri) { // They did not provide a uri from input, so use the stored one
-            $input["redirect_uri"] = $redirect_uri;
-        }
-
-        // type and client_id are required
-        if (!$input["response_type"])
-            $this->callback_error($input["redirect_uri"], ERROR_INVALID_REQUEST, $input["state"], ERROR_INVALID_RESPONSE_TYPE);
-
-        // Check requested auth response type against the list of supported types
-        if (array_search($input["response_type"], $this->get_supported_auth_response_types()) === false)
-            $this->callback_error($input["redirect_uri"], ERROR_UNSUPPORTED_RESPONSE_TYPE, $input["state"]);
-
-        // Validate that the requested scope is supported
-        if ($input["scope"] && !$this->check_scope($input["scope"], $this->get_supported_scopes()))
-            $this->callback_error($input["redirect_uri"], ERROR_INVALID_SCOPE, $input["state"]);
-
-        return $input;
-    }
-
-    // After the user has approved or denied the access request
-    // the authorization server should call this function to redirect
-    // the user appropriately
-
-    // The params all come from the results of get_authorize_params
-    // except for $is_authorized -- this is true or false depending on whether
-    // the user authorized the access
-    public function finish_client_authorization($is_authorized, $type, $client_id, $redirect_uri, $state, $scope = null) {
-        if ($state !== null)
-            $result["query"]["state"] = $state;
-
-        if ($is_authorized === false) {
-            $result["query"]["error"] = ERROR_USER_DENIED;
-        } else {
-            if ($type == AUTH_CODE_AUTH_RESPONSE_TYPE || $type == CODE_AND_TOKEN_AUTH_RESPONSE_TYPE)
-                $result["query"]["code"] = $this->create_auth_code($client_id, $redirect_uri, $scope);
-
-            if ($type == ACCESS_TOKEN_AUTH_RESPONSE_TYPE || $type == CODE_AND_TOKEN_AUTH_RESPONSE_TYPE)
-                $result["fragment"] = $this->create_access_token($client_id, $scope);
-        }
-
-        $this->do_redirect_uri_callback($redirect_uri, $result);
-    }
-
-    /* Other/utility functions */
-
-    private function do_redirect_uri_callback($redirect_uri, $result) {
-        header("HTTP/1.1 302 Found");
-        header("Location: " . $this->build_uri($redirect_uri, $result));
-        exit;
-    }
-
-    private function build_uri($uri, $data) {
-        $parse_url = parse_url($uri);
-
-        // Add our data to the parsed uri
-        foreach ($data as $k => $v) {
-            if (isset($parse_url[$k]))
-                $parse_url[$k] .= "&" . http_build_query($v);
-            else
-                $parse_url[$k] = http_build_query($v);
-        }
-
-        // Put humpty dumpty back together
-        return
-             ((isset($parse_url["scheme"])) ? $parse_url["scheme"] . "://" : "")
-            .((isset($parse_url["user"])) ? $parse_url["user"] . ((isset($parse_url["pass"])) ? ":" . $parse_url["pass"] : "") ."@" : "")
-            .((isset($parse_url["host"])) ? $parse_url["host"] : "")
-            .((isset($parse_url["port"])) ? ":" . $parse_url["port"] : "")
-            .((isset($parse_url["path"])) ? $parse_url["path"] : "")
-            .((isset($parse_url["query"])) ? "?" . $parse_url["query"] : "")
-            .((isset($parse_url["fragment"])) ? "#" . $parse_url["fragment"] : "");
-    }
-
-    // This belongs in a separate factory, but to keep it simple, I'm just keeping it here.
-    private function create_access_token($client_id, $scope) {
-        $token = array(
-            "access_token" => $this->gen_access_token(),
-            "expires_in" => $this->access_token_lifetime,
-            "scope" => $scope
-        );
-
-        $this->store_access_token($token["access_token"], $client_id, time() + $this->access_token_lifetime, $scope);
-
-        // Issue a refresh token also, if we support them
-        if (in_array(REFRESH_TOKEN_GRANT_TYPE, $this->get_supported_grant_types())) {
-            $token["refresh_token"] = $this->gen_access_token();
-            $this->store_refresh_token($token["refresh_token"], $client_id, time() + $this->refresh_token_lifetime, $scope);
-        }
-
-        return $token;
-    }
-
-    private function create_auth_code($client_id, $redirect_uri, $scope) {
-        $code = $this->gen_auth_code();
-        $this->store_auth_code($code, $client_id, $redirect_uri, time() + $this->auth_code_lifetime, $scope);
-        return $code;
-    }
-
-    // Implementing classes may want to override these two functions
-    // to implement other access token or auth code generation schemes
-    private function gen_access_token() {
-        return base64_encode(pack('N6', mt_rand(), mt_rand(), mt_rand(), mt_rand(), mt_rand(), mt_rand()));
-    }
-
-    private function gen_auth_code() {
-        return base64_encode(pack('N6', mt_rand(), mt_rand(), mt_rand(), mt_rand(), mt_rand(), mt_rand()));
-    }
-
-    // Implementing classes may need to override this function for use on non-Apache web servers
-    // Just pull out the Authorization HTTP header and return it
-    // Return false if the Authorization header does not exist
-    private function get_authorization_header() {
-        if (array_key_exists("HTTP_AUTHORIZATION", $_SERVER))
-            return $_SERVER["HTTP_AUTHORIZATION"];
-
-        if (function_exists("apache_request_headers")) {
-            $headers = apache_request_headers();
-
-            if (array_key_exists("Authorization", $headers))
-                return $headers["Authorization"];
-        }
-
-        return false;
-    }
-
-    private function send_json_headers() {
-        header("Content-Type: application/json");
-        header("Cache-Control: no-store");
-    }
-
-    public function error($code, $message = null) {
-        header("HTTP/1.1 " . $code);
-
-        if ($message) {
-            $this->send_json_headers();
-            echo json_encode(array("error" => $message));
-        }
-
-        exit;
-    }
-
-    public function callback_error($redirect_uri, $error, $state, $message = null, $error_uri = null) {
-        $result["query"]["error"] = $error;
-
-        if ($state)
-            $result["query"]["state"] = $state;
-
-        if ($message)
-            $result["query"]["error_description"] = $message;
-
-        if ($error_uri)
-            $result["query"]["error_uri"] = $error_uri;
-
-        $this->do_redirect_uri_callback($redirect_uri, $result);
-    }
-}
\ No newline at end of file
index 8a5b85447ee4af8220915ee8e939c52f8049dd50..c16197b692ecd21856de4dbdbbee911e732fc3a0 100644 (file)
@@ -1,11 +1,11 @@
 PHP Markdown Lib  
-Copyright (c) 2004-2014 Michel Fortin  
-<http://michelf.ca/>  
+Copyright (c) 2004-2016 Michel Fortin  
+<https://michelf.ca/>  
 All rights reserved.
 
 Based on Markdown  
 Copyright (c) 2003-2006 John Gruber   
-<http://daringfireball.net/>   
+<https://daringfireball.net/>   
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
index 8c281094ceb30c8bb11ef4048615bb88c2d99e28..e2bd3808e8537a0fb353cc7f990a690ca9ab4025 100644 (file)
@@ -1,10 +1,10 @@
 <?php
 
-# Use this file if you cannot use class autoloading. It will include all the
-# files needed for the Markdown parser.
-#
-# Take a look at the PSR-0-compatible class autoloading implementation
-# in the Readme.php file if you want a simple autoloader setup.
+// Use this file if you cannot use class autoloading. It will include all the
+// files needed for the Markdown parser.
+//
+// Take a look at the PSR-0-compatible class autoloading implementation
+// in the Readme.php file if you want a simple autoloader setup.
 
 require_once dirname(__FILE__) . '/MarkdownInterface.php';
 require_once dirname(__FILE__) . '/Markdown.php';
index c8ced899c61da0f4f93b597a9b4b3897cb3fb125..04577298a48435b3899b23e4dce2d99ff6cc26a7 100644 (file)
 <?php
-#
-# Markdown  -  A text-to-HTML conversion tool for web writers
-#
-# PHP Markdown  
-# Copyright (c) 2004-2014 Michel Fortin  
-# <http://michelf.com/projects/php-markdown/>
-#
-# Original Markdown  
-# Copyright (c) 2004-2006 John Gruber  
-# <http://daringfireball.net/projects/markdown/>
-#
-namespace Michelf;
-
+/**
+ * Markdown  -  A text-to-HTML conversion tool for web writers
+ *
+ * @package   php-markdown
+ * @author    Michel Fortin <michel.fortin@michelf.com>
+ * @copyright 2004-2016 Michel Fortin <https://michelf.com/projects/php-markdown/>
+ * @copyright (Original Markdown) 2004-2006 John Gruber <https://daringfireball.net/projects/markdown/>
+ */
 
-#
-# Markdown Parser Class
-#
+namespace Michelf;
 
+/**
+ * Markdown Parser Class
+ */
 class Markdown implements MarkdownInterface {
-
-       ### Version ###
-
-       const  MARKDOWNLIB_VERSION  =  "1.4.1";
-
-       ### Simple Function Interface ###
-
+       /**
+        * Define the package version
+        * @var string
+        */
+       const MARKDOWNLIB_VERSION = "1.7.0";
+
+       /**
+        * Simple function interface - Initialize the parser and return the result
+        * of its transform method. This will work fine for derived classes too.
+        *
+        * @api
+        *
+        * @param  string $text
+        * @return string
+        */
        public static function defaultTransform($text) {
-       #
-       # Initialize the parser and return the result of its transform method.
-       # This will work fine for derived classes too.
-       #
-               # Take parser class on which this function was called.
+               // Take parser class on which this function was called.
                $parser_class = \get_called_class();
 
-               # try to take parser from the static parser list
+               // Try to take parser from the static parser list
                static $parser_list;
                $parser =& $parser_list[$parser_class];
 
-               # create the parser it not already set
-               if (!$parser)
+               // Create the parser it not already set
+               if (!$parser) {
                        $parser = new $parser_class;
+               }
 
-               # Transform text using parser.
+               // Transform text using parser.
                return $parser->transform($text);
        }
 
-       ### Configuration Variables ###
+       /**
+        * Configuration variables
+        */
 
-       # Change to ">" for HTML output.
+       /**
+        * Change to ">" for HTML output.
+        * @var string
+        */
        public $empty_element_suffix = " />";
+
+       /**
+        * The width of indentation of the output markup
+        * @var int
+        */
        public $tab_width = 4;
-       
-       # Change to `true` to disallow markup or entities.
-       public $no_markup = false;
+
+       /**
+        * Change to `true` to disallow markup or entities.
+        * @var boolean
+        */
+       public $no_markup   = false;
        public $no_entities = false;
-       
-       # Predefined urls and titles for reference links and images.
-       public $predef_urls = array();
-       public $predef_titles = array();
 
-       # Optional filter function for URLs
-       public $url_filter_func = null;
 
+       /**
+        * Change to `true` to enable line breaks on \n without two trailling spaces
+        * @var boolean
+        */
+       public $hard_wrap = false;
 
-       ### Parser Implementation ###
+       /**
+        * Predefined URLs and titles for reference links and images.
+        * @var array
+        */
+       public $predef_urls   = array();
+       public $predef_titles = array();
+
+       /**
+        * Optional filter function for URLs
+        * @var callable
+        */
+       public $url_filter_func = null;
 
-       # Regex to match balanced [brackets].
-       # Needed to insert a maximum bracked depth while converting to PHP.
+       /**
+        * Optional header id="" generation callback function.
+        * @var callable
+        */
+       public $header_id_func = null;
+
+       /**
+        * Optional function for converting code block content to HTML
+        * @var callable
+        */
+       public $code_block_content_func = null;
+
+       /**
+        * Optional function for converting code span content to HTML.
+        * @var callable
+        */
+       public $code_span_content_func = null;
+
+       /**
+        * Class attribute to toggle "enhanced ordered list" behaviour
+        * setting this to true will allow ordered lists to start from the index
+        * number that is defined first.
+        *
+        * For example:
+        * 2. List item two
+        * 3. List item three
+        *
+        * Becomes:
+        * <ol start="2">
+        * <li>List item two</li>
+        * <li>List item three</li>
+        * </ol>
+        *
+        * @var bool
+        */
+       public $enhanced_ordered_list = false;
+
+       /**
+        * Parser implementation
+        */
+
+       /**
+        * Regex to match balanced [brackets].
+        * Needed to insert a maximum bracked depth while converting to PHP.
+        * @var int
+        */
        protected $nested_brackets_depth = 6;
        protected $nested_brackets_re;
-       
+
        protected $nested_url_parenthesis_depth = 4;
        protected $nested_url_parenthesis_re;
 
-       # Table of hash values for escaped characters:
+       /**
+        * Table of hash values for escaped characters:
+        * @var string
+        */
        protected $escape_chars = '\`*_{}[]()>#+-.!';
        protected $escape_chars_re;
 
-
+       /**
+        * Constructor function. Initialize appropriate member variables.
+        * @return void
+        */
        public function __construct() {
-       #
-       # Constructor function. Initialize appropriate member variables.
-       #
                $this->_initDetab();
                $this->prepareItalicsAndBold();
-       
-               $this->nested_brackets_re = 
+
+               $this->nested_brackets_re =
                        str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth).
                        str_repeat('\])*', $this->nested_brackets_depth);
-       
-               $this->nested_url_parenthesis_re = 
+
+               $this->nested_url_parenthesis_re =
                        str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth).
                        str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth);
-               
+
                $this->escape_chars_re = '['.preg_quote($this->escape_chars).']';
-               
-               # Sort document, block, and span gamut in ascendent priority order.
+
+               // Sort document, block, and span gamut in ascendent priority order.
                asort($this->document_gamut);
                asort($this->block_gamut);
                asort($this->span_gamut);
        }
 
 
-       # Internal hashes used during transformation.
-       protected $urls = array();
-       protected $titles = array();
+       /**
+        * Internal hashes used during transformation.
+        * @var array
+        */
+       protected $urls        = array();
+       protected $titles      = array();
        protected $html_hashes = array();
-       
-       # Status flag to avoid invalid nesting.
+
+       /**
+        * Status flag to avoid invalid nesting.
+        * @var boolean
+        */
        protected $in_anchor = false;
-       
-       
+
+       /**
+        * Called before the transformation process starts to setup parser states.
+        * @return void
+        */
        protected function setup() {
-       #
-       # Called before the transformation process starts to setup parser 
-       # states.
-       #
-               # Clear global hashes.
-               $this->urls = $this->predef_urls;
-               $this->titles = $this->predef_titles;
+               // Clear global hashes.
+               $this->urls        = $this->predef_urls;
+               $this->titles      = $this->predef_titles;
                $this->html_hashes = array();
-               
-               $this->in_anchor = false;
+               $this->in_anchor   = false;
        }
-       
+
+       /**
+        * Called after the transformation process to clear any variable which may
+        * be taking up memory unnecessarly.
+        * @return void
+        */
        protected function teardown() {
-       #
-       # Called after the transformation process to clear any variable 
-       # which may be taking up memory unnecessarly.
-       #
-               $this->urls = array();
-               $this->titles = array();
+               $this->urls        = array();
+               $this->titles      = array();
                $this->html_hashes = array();
        }
 
-
+       /**
+        * Main function. Performs some preprocessing on the input text and pass
+        * it through the document gamut.
+        *
+        * @api
+        *
+        * @param  string $text
+        * @return string
+        */
        public function transform($text) {
-       #
-       # Main function. Performs some preprocessing on the input text
-       # and pass it through the document gamut.
-       #
                $this->setup();
-       
+
                # Remove UTF-8 BOM and marker character in input, if present.
                $text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text);
 
@@ -168,28 +248,33 @@ class Markdown implements MarkdownInterface {
                foreach ($this->document_gamut as $method => $priority) {
                        $text = $this->$method($text);
                }
-               
+
                $this->teardown();
 
                return $text . "\n";
        }
-       
+
+       /**
+        * Define the document gamut
+        * @var array
+        */
        protected $document_gamut = array(
-               # Strip link definitions, store in hashes.
+               // Strip link definitions, store in hashes.
                "stripLinkDefinitions" => 20,
-               
                "runBasicBlockGamut"   => 30,
-               );
-
-
+       );
+
+       /**
+        * Strips link definitions from text, stores the URLs and titles in
+        * hash references
+        * @param  string $text
+        * @return string
+        */
        protected function stripLinkDefinitions($text) {
-       #
-       # Strips link definitions from text, stores the URLs and titles in
-       # hash references.
-       #
+
                $less_than_tab = $this->tab_width - 1;
 
-               # Link defs are in the form: ^[id]: url "optional title"
+               // Link defs are in the form: ^[id]: url "optional title"
                $text = preg_replace_callback('{
                                                        ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1
                                                          [ ]*
@@ -213,43 +298,58 @@ class Markdown implements MarkdownInterface {
                                                        (?:\n+|\Z)
                        }xm',
                        array($this, '_stripLinkDefinitions_callback'),
-                       $text);
+                       $text
+               );
                return $text;
        }
+
+       /**
+        * The callback to strip link definitions
+        * @param  array $matches
+        * @return string
+        */
        protected function _stripLinkDefinitions_callback($matches) {
                $link_id = strtolower($matches[1]);
                $url = $matches[2] == '' ? $matches[3] : $matches[2];
                $this->urls[$link_id] = $url;
                $this->titles[$link_id] =& $matches[4];
-               return ''; # String that will replace the block
+               return ''; // String that will replace the block
        }
 
-
+       /**
+        * Hashify HTML blocks
+        * @param  string $text
+        * @return string
+        */
        protected function hashHTMLBlocks($text) {
-               if ($this->no_markup)  return $text;
+               if ($this->no_markup) {
+                       return $text;
+               }
 
                $less_than_tab = $this->tab_width - 1;
 
-               # Hashify HTML blocks:
-               # We only want to do this for block-level HTML tags, such as headers,
-               # lists, and tables. That's because we still want to wrap <p>s around
-               # "paragraphs" that are wrapped in non-block-level tags, such as anchors,
-               # phrase emphasis, and spans. The list of tags we're looking for is
-               # hard-coded:
-               #
-               # *  List "a" is made of tags which can be both inline or block-level.
-               #    These will be treated block-level when the start tag is alone on 
-               #    its line, otherwise they're not matched here and will be taken as 
-               #    inline later.
-               # *  List "b" is made of tags which are always block-level;
-               #
+               /**
+                * Hashify HTML blocks:
+                *
+                * We only want to do this for block-level HTML tags, such as headers,
+                * lists, and tables. That's because we still want to wrap <p>s around
+                * "paragraphs" that are wrapped in non-block-level tags, such as
+                * anchors, phrase emphasis, and spans. The list of tags we're looking
+                * for is hard-coded:
+                *
+                * *  List "a" is made of tags which can be both inline or block-level.
+                *    These will be treated block-level when the start tag is alone on
+                *    its line, otherwise they're not matched here and will be taken as
+                *    inline later.
+                * *  List "b" is made of tags which are always block-level;
+                */
                $block_tags_a_re = 'ins|del';
                $block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'.
                                                   'script|noscript|style|form|fieldset|iframe|math|svg|'.
                                                   'article|section|nav|aside|hgroup|header|footer|'.
                                                   'figure';
 
-               # Regular expression for the content of a block tag.
+               // Regular expression for the content of a block tag.
                $nested_tags_level = 4;
                $attr = '
                        (?>                             # optional tag attributes
@@ -263,7 +363,7 @@ class Markdown implements MarkdownInterface {
                          |
                                \'[^\']*\'      # text inside single quotes (tolerate ">")
                          )*
-                       )?      
+                       )?
                        ';
                $content =
                        str_repeat('
@@ -275,29 +375,32 @@ class Markdown implements MarkdownInterface {
                                        (?>
                                          />
                                        |
-                                         >', $nested_tags_level).      # end of opening tag
-                                         '.*?'.                                        # last level nested tag content
+                                         >', $nested_tags_level).      // end of opening tag
+                                         '.*?'.                                        // last level nested tag content
                        str_repeat('
                                          </\2\s*>      # closing nested tag
                                        )
-                                 |                             
+                                 |
                                        <(?!/\2\s*>     # other tags with a different name
                                  )
                                )*',
                                $nested_tags_level);
                $content2 = str_replace('\2', '\3', $content);
 
-               # First, look for nested blocks, e.g.:
-               #       <div>
-               #               <div>
-               #               tags for inner block must be indented.
-               #               </div>
-               #       </div>
-               #
-               # The outermost tags must start at the left margin for this to match, and
-               # the inner nested divs must be indented.
-               # We need to do this before the next, more liberal match, because the next
-               # match will start at the first `<div>` and stop at the first `</div>`.
+               /**
+                * First, look for nested blocks, e.g.:
+                *      <div>
+                *              <div>
+                *              tags for inner block must be indented.
+                *              </div>
+                *      </div>
+                *
+                * The outermost tags must start at the left margin for this to match,
+                * and the inner nested divs must be indented.
+                * We need to do this before the next, more liberal match, because the
+                * next match will start at the first `<div>` and stop at the
+                * first `</div>`.
+                */
                $text = preg_replace_callback('{(?>
                        (?>
                                (?<=\n)                 # Starting on its own line
@@ -306,9 +409,9 @@ class Markdown implements MarkdownInterface {
                        )
                        (                                               # save in $1
 
-                         # Match from `\n<tag>` to `</tag>\n`, handling nested tags 
+                         # Match from `\n<tag>` to `</tag>\n`, handling nested tags
                          # in between.
-                                       
+
                                                [ ]{0,'.$less_than_tab.'}
                                                <('.$block_tags_b_re.')# start tag = $2
                                                '.$attr.'>                      # attributes followed by > and \n
@@ -326,28 +429,28 @@ class Markdown implements MarkdownInterface {
                                                </\3>                           # the matching end tag
                                                [ ]*                            # trailing spaces/tabs
                                                (?=\n+|\Z)      # followed by a newline or end of document
-                                       
-                       | # Special case just for <hr />. It was easier to make a special 
+
+                       | # Special case just for <hr />. It was easier to make a special
                          # case than to make the other regex more complicated.
-                       
+
                                                [ ]{0,'.$less_than_tab.'}
                                                <(hr)                           # start tag = $2
                                                '.$attr.'                       # attributes
                                                /?>                                     # the matching end tag
                                                [ ]*
                                                (?=\n{2,}|\Z)           # followed by a blank line or end of document
-                       
+
                        | # Special case for standalone HTML comments:
-                       
+
                                        [ ]{0,'.$less_than_tab.'}
                                        (?s:
                                                <!-- .*? -->
                                        )
                                        [ ]*
                                        (?=\n{2,}|\Z)           # followed by a blank line or end of document
-                       
+
                        | # PHP and ASP-style processor instructions (<? and <%)
-                       
+
                                        [ ]{0,'.$less_than_tab.'}
                                        (?s:
                                                <([?%])                 # $2
@@ -356,98 +459,118 @@ class Markdown implements MarkdownInterface {
                                        )
                                        [ ]*
                                        (?=\n{2,}|\Z)           # followed by a blank line or end of document
-                                       
+
                        )
                        )}Sxmi',
                        array($this, '_hashHTMLBlocks_callback'),
-                       $text);
+                       $text
+               );
 
                return $text;
        }
+
+       /**
+        * The callback for hashing HTML blocks
+        * @param  string $matches
+        * @return string
+        */
        protected function _hashHTMLBlocks_callback($matches) {
                $text = $matches[1];
                $key  = $this->hashBlock($text);
                return "\n\n$key\n\n";
        }
-       
-       
+
+       /**
+        * Called whenever a tag must be hashed when a function insert an atomic
+        * element in the text stream. Passing $text to through this function gives
+        * a unique text-token which will be reverted back when calling unhash.
+        *
+        * The $boundary argument specify what character should be used to surround
+        * the token. By convension, "B" is used for block elements that needs not
+        * to be wrapped into paragraph tags at the end, ":" is used for elements
+        * that are word separators and "X" is used in the general case.
+        *
+        * @param  string $text
+        * @param  string $boundary
+        * @return string
+        */
        protected function hashPart($text, $boundary = 'X') {
-       #
-       # Called whenever a tag must be hashed when a function insert an atomic 
-       # element in the text stream. Passing $text to through this function gives
-       # a unique text-token which will be reverted back when calling unhash.
-       #
-       # The $boundary argument specify what character should be used to surround
-       # the token. By convension, "B" is used for block elements that needs not
-       # to be wrapped into paragraph tags at the end, ":" is used for elements
-       # that are word separators and "X" is used in the general case.
-       #
-               # Swap back any tag hash found in $text so we do not have to `unhash`
-               # multiple times at the end.
+               // Swap back any tag hash found in $text so we do not have to `unhash`
+               // multiple times at the end.
                $text = $this->unhash($text);
-               
-               # Then hash the block.
+
+               // Then hash the block.
                static $i = 0;
                $key = "$boundary\x1A" . ++$i . $boundary;
                $this->html_hashes[$key] = $text;
-               return $key; # String that will replace the tag.
+               return $key; // String that will replace the tag.
        }
 
-
+       /**
+        * Shortcut function for hashPart with block-level boundaries.
+        * @param  string $text
+        * @return string
+        */
        protected function hashBlock($text) {
-       #
-       # Shortcut function for hashPart with block-level boundaries.
-       #
                return $this->hashPart($text, 'B');
        }
 
-
+       /**
+        * Define the block gamut - these are all the transformations that form
+        * block-level tags like paragraphs, headers, and list items.
+        * @var array
+        */
        protected $block_gamut = array(
-       #
-       # These are all the transformations that form block-level
-       # tags like paragraphs, headers, and list items.
-       #
                "doHeaders"         => 10,
                "doHorizontalRules" => 20,
-               
                "doLists"           => 40,
                "doCodeBlocks"      => 50,
                "doBlockQuotes"     => 60,
-               );
-
+       );
+
+       /**
+        * Run block gamut tranformations.
+        *
+        * We need to escape raw HTML in Markdown source before doing anything
+        * else. This need to be done for each block, and not only at the
+        * begining in the Markdown function since hashed blocks can be part of
+        * list items and could have been indented. Indented blocks would have
+        * been seen as a code block in a previous pass of hashHTMLBlocks.
+        *
+        * @param  string $text
+        * @return string
+        */
        protected function runBlockGamut($text) {
-       #
-       # Run block gamut tranformations.
-       #
-               # We need to escape raw HTML in Markdown source before doing anything 
-               # else. This need to be done for each block, and not only at the 
-               # begining in the Markdown function since hashed blocks can be part of
-               # list items and could have been indented. Indented blocks would have 
-               # been seen as a code block in a previous pass of hashHTMLBlocks.
                $text = $this->hashHTMLBlocks($text);
-               
                return $this->runBasicBlockGamut($text);
        }
-       
+
+       /**
+        * Run block gamut tranformations, without hashing HTML blocks. This is
+        * useful when HTML blocks are known to be already hashed, like in the first
+        * whole-document pass.
+        *
+        * @param  string $text
+        * @return string
+        */
        protected function runBasicBlockGamut($text) {
-       #
-       # Run block gamut tranformations, without hashing HTML blocks. This is 
-       # useful when HTML blocks are known to be already hashed, like in the first
-       # whole-document pass.
-       #
+
                foreach ($this->block_gamut as $method => $priority) {
                        $text = $this->$method($text);
                }
-               
-               # Finally form paragraph and restore hashed blocks.
+
+               // Finally form paragraph and restore hashed blocks.
                $text = $this->formParagraphs($text);
 
                return $text;
        }
-       
-       
+
+       /**
+        * Convert horizontal rules
+        * @param  string $text
+        * @return string
+        */
        protected function doHorizontalRules($text) {
-               # Do Horizontal Rules:
                return preg_replace(
                        '{
                                ^[ ]{0,3}       # Leading space
@@ -459,67 +582,82 @@ class Markdown implements MarkdownInterface {
                                [ ]*            # Tailing spaces
                                $                       # End of line.
                        }mx',
-                       "\n".$this->hashBlock("<hr$this->empty_element_suffix")."\n", 
-                       $text);
+                       "\n".$this->hashBlock("<hr$this->empty_element_suffix")."\n",
+                       $text
+               );
        }
 
-
+       /**
+        * These are all the transformations that occur *within* block-level
+        * tags like paragraphs, headers, and list items.
+        * @var array
+        */
        protected $span_gamut = array(
-       #
-       # These are all the transformations that occur *within* block-level
-       # tags like paragraphs, headers, and list items.
-       #
-               # Process character escapes, code spans, and inline HTML
-               # in one shot.
+               // Process character escapes, code spans, and inline HTML
+               // in one shot.
                "parseSpan"           => -30,
-
-               # Process anchor and image tags. Images must come first,
-               # because ![foo][f] looks like an anchor.
+               // Process anchor and image tags. Images must come first,
+               // because ![foo][f] looks like an anchor.
                "doImages"            =>  10,
                "doAnchors"           =>  20,
-               
-               # Make links out of things like `<http://example.com/>`
-               # Must come after doAnchors, because you can use < and >
-               # delimiters in inline links like [this](<url>).
+               // Make links out of things like `<https://example.com/>`
+               // Must come after doAnchors, because you can use < and >
+               // delimiters in inline links like [this](<url>).
                "doAutoLinks"         =>  30,
                "encodeAmpsAndAngles" =>  40,
-
                "doItalicsAndBold"    =>  50,
                "doHardBreaks"        =>  60,
-               );
+       );
 
+       /**
+        * Run span gamut transformations
+        * @param  string $text
+        * @return string
+        */
        protected function runSpanGamut($text) {
-       #
-       # Run span gamut tranformations.
-       #
                foreach ($this->span_gamut as $method => $priority) {
                        $text = $this->$method($text);
                }
 
                return $text;
        }
-       
-       
+
+       /**
+        * Do hard breaks
+        * @param  string $text
+        * @return string
+        */
        protected function doHardBreaks($text) {
-               # Do hard breaks:
-               return preg_replace_callback('/ {2,}\n/', 
-                       array($this, '_doHardBreaks_callback'), $text);
+               if ($this->hard_wrap) {
+                       return preg_replace_callback('/ *\n/',
+                               array($this, '_doHardBreaks_callback'), $text);
+               } else {
+                       return preg_replace_callback('/ {2,}\n/',
+                               array($this, '_doHardBreaks_callback'), $text);
+               }
        }
+
+       /**
+        * Trigger part hashing for the hard break (callback method)
+        * @param  array $matches
+        * @return string
+        */
        protected function _doHardBreaks_callback($matches) {
                return $this->hashPart("<br$this->empty_element_suffix\n");
        }
 
-
+       /**
+        * Turn Markdown link shortcuts into XHTML <a> tags.
+        * @param  string $text
+        * @return string
+        */
        protected function doAnchors($text) {
-       #
-       # Turn Markdown link shortcuts into XHTML <a> tags.
-       #
-               if ($this->in_anchor) return $text;
+               if ($this->in_anchor) {
+                       return $text;
+               }
                $this->in_anchor = true;
-               
-               #
-               # First, handle reference-style links: [link text] [id]
-               #
+
+               // First, handle reference-style links: [link text] [id]
                $text = preg_replace_callback('{
                        (                                       # wrap whole match in $1
                          \[
@@ -536,9 +674,7 @@ class Markdown implements MarkdownInterface {
                        }xs',
                        array($this, '_doAnchors_reference_callback'), $text);
 
-               #
-               # Next, inline-style links: [link text](url "optional title")
-               #
+               // Next, inline-style links: [link text](url "optional title")
                $text = preg_replace_callback('{
                        (                               # wrap whole match in $1
                          \[
@@ -563,11 +699,9 @@ class Markdown implements MarkdownInterface {
                        }xs',
                        array($this, '_doAnchors_inline_callback'), $text);
 
-               #
-               # Last, handle reference-style shortcuts: [link text]
-               # These must come last in case you've also got [link text][1]
-               # or [link text](/foo)
-               #
+               // Last, handle reference-style shortcuts: [link text]
+               // These must come last in case you've also got [link text][1]
+               // or [link text](/foo)
                $text = preg_replace_callback('{
                        (                                       # wrap whole match in $1
                          \[
@@ -580,48 +714,60 @@ class Markdown implements MarkdownInterface {
                $this->in_anchor = false;
                return $text;
        }
+
+       /**
+        * Callback method to parse referenced anchors
+        * @param  string $matches
+        * @return string
+        */
        protected function _doAnchors_reference_callback($matches) {
                $whole_match =  $matches[1];
                $link_text   =  $matches[2];
                $link_id     =& $matches[3];
 
                if ($link_id == "") {
-                       # for shortcut links like [this][] or [this].
+                       // for shortcut links like [this][] or [this].
                        $link_id = $link_text;
                }
-               
-               # lower-case and turn embedded newlines into spaces
+
+               // lower-case and turn embedded newlines into spaces
                $link_id = strtolower($link_id);
                $link_id = preg_replace('{[ ]?\n}', ' ', $link_id);
 
                if (isset($this->urls[$link_id])) {
                        $url = $this->urls[$link_id];
                        $url = $this->encodeURLAttribute($url);
-                       
+
                        $result = "<a href=\"$url\"";
                        if ( isset( $this->titles[$link_id] ) ) {
                                $title = $this->titles[$link_id];
                                $title = $this->encodeAttribute($title);
                                $result .=  " title=\"$title\"";
                        }
-               
+
                        $link_text = $this->runSpanGamut($link_text);
                        $result .= ">$link_text</a>";
                        $result = $this->hashPart($result);
-               }
-               else {
+               } else {
                        $result = $whole_match;
                }
                return $result;
        }
+
+       /**
+        * Callback method to parse inline anchors
+        * @param  string $matches
+        * @return string
+        */
        protected function _doAnchors_inline_callback($matches) {
                $whole_match    =  $matches[1];
                $link_text              =  $this->runSpanGamut($matches[2]);
                $url                    =  $matches[3] == '' ? $matches[4] : $matches[3];
                $title                  =& $matches[7];
 
-               // if the URL was of the form <s p a c e s> it got caught by the HTML
-               // tag parser and hashed. Need to reverse the process before using the URL.
+               // If the URL was of the form <s p a c e s> it got caught by the HTML
+               // tag parser and hashed. Need to reverse the process before using
+               // the URL.
                $unhashed = $this->unhash($url);
                if ($unhashed != $url)
                        $url = preg_replace('/^<(.*)>$/', '\1', $unhashed);
@@ -633,21 +779,20 @@ class Markdown implements MarkdownInterface {
                        $title = $this->encodeAttribute($title);
                        $result .=  " title=\"$title\"";
                }
-               
+
                $link_text = $this->runSpanGamut($link_text);
                $result .= ">$link_text</a>";
 
                return $this->hashPart($result);
        }
 
-
+       /**
+        * Turn Markdown image shortcuts into <img> tags.
+        * @param  string $text
+        * @return string
+        */
        protected function doImages($text) {
-       #
-       # Turn Markdown image shortcuts into <img> tags.
-       #
-               #
-               # First, handle reference-style labeled images: ![alt text][id]
-               #
+               // First, handle reference-style labeled images: ![alt text][id]
                $text = preg_replace_callback('{
                        (                               # wrap whole match in $1
                          !\[
@@ -662,13 +807,11 @@ class Markdown implements MarkdownInterface {
                          \]
 
                        )
-                       }xs', 
+                       }xs',
                        array($this, '_doImages_reference_callback'), $text);
 
-               #
-               # Next, handle inline images:  ![alt text](url "optional title")
-               # Don't forget: encode * and _
-               #
+               // Next, handle inline images:  ![alt text](url "optional title")
+               // Don't forget: encode * and _
                $text = preg_replace_callback('{
                        (                               # wrap whole match in $1
                          !\[
@@ -696,13 +839,19 @@ class Markdown implements MarkdownInterface {
 
                return $text;
        }
+
+       /**
+        * Callback to parse references image tags
+        * @param  array $matches
+        * @return string
+        */
        protected function _doImages_reference_callback($matches) {
                $whole_match = $matches[1];
                $alt_text    = $matches[2];
                $link_id     = strtolower($matches[3]);
 
                if ($link_id == "") {
-                       $link_id = strtolower($alt_text); # for shortcut links like ![this][].
+                       $link_id = strtolower($alt_text); // for shortcut links like ![this][].
                }
 
                $alt_text = $this->encodeAttribute($alt_text);
@@ -716,14 +865,19 @@ class Markdown implements MarkdownInterface {
                        }
                        $result .= $this->empty_element_suffix;
                        $result = $this->hashPart($result);
-               }
-               else {
-                       # If there's no such link ID, leave intact:
+               } else {
+                       // If there's no such link ID, leave intact:
                        $result = $whole_match;
                }
 
                return $result;
        }
+
+       /**
+        * Callback to parse inline image tags
+        * @param  array $matches
+        * @return string
+        */
        protected function _doImages_inline_callback($matches) {
                $whole_match    = $matches[1];
                $alt_text               = $matches[2];
@@ -735,32 +889,38 @@ class Markdown implements MarkdownInterface {
                $result = "<img src=\"$url\" alt=\"$alt_text\"";
                if (isset($title)) {
                        $title = $this->encodeAttribute($title);
-                       $result .=  " title=\"$title\""; # $title already quoted
+                       $result .=  " title=\"$title\""; // $title already quoted
                }
                $result .= $this->empty_element_suffix;
 
                return $this->hashPart($result);
        }
 
-
+       /**
+        * Parse Markdown heading elements to HTML
+        * @param  string $text
+        * @return string
+        */
        protected function doHeaders($text) {
-               # Setext-style headers:
-               #         Header 1
-               #         ========
-               #  
-               #         Header 2
-               #         --------
-               #
+               /**
+                * Setext-style headers:
+                *        Header 1
+                *        ========
+                *
+                *        Header 2
+                *        --------
+                */
                $text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx',
                        array($this, '_doHeaders_callback_setext'), $text);
 
-               # atx-style headers:
-               #       # Header 1
-               #       ## Header 2
-               #       ## Header 2 with closing hashes ##
-               #       ...
-               #       ###### Header 6
-               #
+               /**
+                * atx-style headers:
+                *   # Header 1
+                *   ## Header 2
+                *   ## Header 2 with closing hashes ##
+                *   ...
+                *   ###### Header 6
+                */
                $text = preg_replace_callback('{
                                ^(\#{1,6})      # $1 = string of #\'s
                                [ ]*
@@ -773,29 +933,72 @@ class Markdown implements MarkdownInterface {
 
                return $text;
        }
+
+       /**
+        * Setext header parsing callback
+        * @param  array $matches
+        * @return string
+        */
        protected function _doHeaders_callback_setext($matches) {
-               # Terrible hack to check we haven't found an empty list item.
-               if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1]))
+               // Terrible hack to check we haven't found an empty list item.
+               if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1])) {
                        return $matches[0];
-               
+               }
+
                $level = $matches[2]{0} == '=' ? 1 : 2;
-               $block = "<h$level>".$this->runSpanGamut($matches[1])."</h$level>";
+
+               // ID attribute generation
+               $idAtt = $this->_generateIdFromHeaderValue($matches[1]);
+
+               $block = "<h$level$idAtt>".$this->runSpanGamut($matches[1])."</h$level>";
                return "\n" . $this->hashBlock($block) . "\n\n";
        }
+
+       /**
+        * ATX header parsing callback
+        * @param  array $matches
+        * @return string
+        */
        protected function _doHeaders_callback_atx($matches) {
+               // ID attribute generation
+               $idAtt = $this->_generateIdFromHeaderValue($matches[2]);
+
                $level = strlen($matches[1]);
-               $block = "<h$level>".$this->runSpanGamut($matches[2])."</h$level>";
+               $block = "<h$level$idAtt>".$this->runSpanGamut($matches[2])."</h$level>";
                return "\n" . $this->hashBlock($block) . "\n\n";
        }
 
+       /**
+        * If a header_id_func property is set, we can use it to automatically
+        * generate an id attribute.
+        *
+        * This method returns a string in the form id="foo", or an empty string
+        * otherwise.
+        * @param  string $headerValue
+        * @return string
+        */
+       protected function _generateIdFromHeaderValue($headerValue) {
+               if (!is_callable($this->header_id_func)) {
+                       return "";
+               }
+
+               $idValue = call_user_func($this->header_id_func, $headerValue);
+               if (!$idValue) {
+                       return "";
+               }
+
+               return ' id="' . $this->encodeAttribute($idValue) . '"';
+       }
 
+       /**
+        * Form HTML ordered (numbered) and unordered (bulleted) lists.
+        * @param  string $text
+        * @return string
+        */
        protected function doLists($text) {
-       #
-       # Form HTML ordered (numbered) and unordered (bulleted) lists.
-       #
                $less_than_tab = $this->tab_width - 1;
 
-               # Re-usable patterns to match list item bullets and number markers:
+               // Re-usable patterns to match list item bullets and number markers:
                $marker_ul_re  = '[*+-]';
                $marker_ol_re  = '\d+[\.]';
 
@@ -805,7 +1008,7 @@ class Markdown implements MarkdownInterface {
                        );
 
                foreach ($markers_relist as $marker_re => $other_marker_re) {
-                       # Re-usable pattern to match any entirel ul or ol list:
+                       // Re-usable pattern to match any entirel ul or ol list:
                        $whole_list_re = '
                                (                                                               # $1 = whole list
                                  (                                                             # $2
@@ -832,18 +1035,17 @@ class Markdown implements MarkdownInterface {
                                  )
                                )
                        '; // mx
-                       
-                       # We use a different prefix before nested lists than top-level lists.
-                       See extended comment in _ProcessListItems().
-               
+
+                       // We use a different prefix before nested lists than top-level lists.
+                       //See extended comment in _ProcessListItems().
+
                        if ($this->list_level) {
                                $text = preg_replace_callback('{
                                                ^
                                                '.$whole_list_re.'
                                        }mx',
                                        array($this, '_doLists_callback'), $text);
-                       }
-                       else {
+                       } else {
                                $text = preg_replace_callback('{
                                                (?:(?<=\n)\n|\A\n?) # Must eat the newline
                                                '.$whole_list_re.'
@@ -854,55 +1056,86 @@ class Markdown implements MarkdownInterface {
 
                return $text;
        }
+
+       /**
+        * List parsing callback
+        * @param  array $matches
+        * @return string
+        */
        protected function _doLists_callback($matches) {
-               # Re-usable patterns to match list item bullets and number markers:
+               // Re-usable patterns to match list item bullets and number markers:
                $marker_ul_re  = '[*+-]';
                $marker_ol_re  = '\d+[\.]';
                $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
-               
+               $marker_ol_start_re = '[0-9]+';
+
                $list = $matches[1];
                $list_type = preg_match("/$marker_ul_re/", $matches[4]) ? "ul" : "ol";
-               
+
                $marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re );
-               
+
                $list .= "\n";
                $result = $this->processListItems($list, $marker_any_re);
-               
-               $result = $this->hashBlock("<$list_type>\n" . $result . "</$list_type>");
+
+               $ol_start = 1;
+               if ($this->enhanced_ordered_list) {
+                       // Get the start number for ordered list.
+                       if ($list_type == 'ol') {
+                               $ol_start_array = array();
+                               $ol_start_check = preg_match("/$marker_ol_start_re/", $matches[4], $ol_start_array);
+                               if ($ol_start_check){
+                                       $ol_start = $ol_start_array[0];
+                               }
+                       }
+               }
+
+               if ($ol_start > 1 && $list_type == 'ol'){
+                       $result = $this->hashBlock("<$list_type start=\"$ol_start\">\n" . $result . "</$list_type>");
+               } else {
+                       $result = $this->hashBlock("<$list_type>\n" . $result . "</$list_type>");
+               }
                return "\n". $result ."\n\n";
        }
 
+       /**
+        * Nesting tracker for list levels
+        * @var integer
+        */
        protected $list_level = 0;
 
+       /**
+        * Process the contents of a single ordered or unordered list, splitting it
+        * into individual list items.
+        * @param  string $list_str
+        * @param  string $marker_any_re
+        * @return string
+        */
        protected function processListItems($list_str, $marker_any_re) {
-       #
-       #       Process the contents of a single ordered or unordered list, splitting it
-       #       into individual list items.
-       #
-               # The $this->list_level global keeps track of when we're inside a list.
-               # Each time we enter a list, we increment it; when we leave a list,
-               # we decrement. If it's zero, we're not in a list anymore.
-               #
-               # We do this because when we're not inside a list, we want to treat
-               # something like this:
-               #
-               #               I recommend upgrading to version
-               #               8. Oops, now this line is treated
-               #               as a sub-list.
-               #
-               # As a single paragraph, despite the fact that the second line starts
-               # with a digit-period-space sequence.
-               #
-               # Whereas when we're inside a list (or sub-list), that line will be
-               # treated as the start of a sub-list. What a kludge, huh? This is
-               # an aspect of Markdown's syntax that's hard to parse perfectly
-               # without resorting to mind-reading. Perhaps the solution is to
-               # change the syntax rules such that sub-lists must start with a
-               # starting cardinal number; e.g. "1." or "a.".
-               
+               /**
+                * The $this->list_level global keeps track of when we're inside a list.
+                * Each time we enter a list, we increment it; when we leave a list,
+                * we decrement. If it's zero, we're not in a list anymore.
+                *
+                * We do this because when we're not inside a list, we want to treat
+                * something like this:
+                *
+                *              I recommend upgrading to version
+                *              8. Oops, now this line is treated
+                *              as a sub-list.
+                *
+                * As a single paragraph, despite the fact that the second line starts
+                * with a digit-period-space sequence.
+                *
+                * Whereas when we're inside a list (or sub-list), that line will be
+                * treated as the start of a sub-list. What a kludge, huh? This is
+                * an aspect of Markdown's syntax that's hard to parse perfectly
+                * without resorting to mind-reading. Perhaps the solution is to
+                * change the syntax rules such that sub-lists must start with a
+                * starting cardinal number; e.g. "1." or "a.".
+                */
                $this->list_level++;
 
-               # trim trailing blank lines:
+               // Trim trailing blank lines:
                $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
 
                $list_str = preg_replace_callback('{
@@ -920,6 +1153,12 @@ class Markdown implements MarkdownInterface {
                $this->list_level--;
                return $list_str;
        }
+
+       /**
+        * List item parsing callback
+        * @param  array $matches
+        * @return string
+        */
        protected function _processListItems_callback($matches) {
                $item = $matches[4];
                $leading_line =& $matches[1];
@@ -927,28 +1166,27 @@ class Markdown implements MarkdownInterface {
                $marker_space = $matches[3];
                $tailing_blank_line =& $matches[5];
 
-               if ($leading_line || $tailing_blank_line || 
+               if ($leading_line || $tailing_blank_line ||
                        preg_match('/\n{2,}/', $item))
                {
-                       # Replace marker with the appropriate whitespace indentation
+                       // Replace marker with the appropriate whitespace indentation
                        $item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item;
                        $item = $this->runBlockGamut($this->outdent($item)."\n");
-               }
-               else {
-                       # Recursion for sub-lists:
+               } else {
+                       // Recursion for sub-lists:
                        $item = $this->doLists($this->outdent($item));
-                       $item = preg_replace('/\n+$/', '', $item);
-                       $item = $this->runSpanGamut($item);
+                       $item = $this->formParagraphs($item, false);
                }
 
                return "<li>" . $item . "</li>\n";
        }
 
-
+       /**
+        * Process Markdown `<pre><code>` blocks.
+        * @param  string $text
+        * @return string
+        */
        protected function doCodeBlocks($text) {
-       #
-       #       Process Markdown `<pre><code>` blocks.
-       #
                $text = preg_replace_callback('{
                                (?:\n\n|\A\n?)
                                (                   # $1 = the code block -- one or more lines, starting with a space/tab
@@ -963,106 +1201,141 @@ class Markdown implements MarkdownInterface {
 
                return $text;
        }
+
+       /**
+        * Code block parsing callback
+        * @param  array $matches
+        * @return string
+        */
        protected function _doCodeBlocks_callback($matches) {
                $codeblock = $matches[1];
 
                $codeblock = $this->outdent($codeblock);
-               $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
+               if ($this->code_block_content_func) {
+                       $codeblock = call_user_func($this->code_block_content_func, $codeblock, "");
+               } else {
+                       $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
+               }
 
                # trim leading newlines and trailing newlines
                $codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
 
                $codeblock = "<pre><code>$codeblock\n</code></pre>";
-               return "\n\n".$this->hashBlock($codeblock)."\n\n";
+               return "\n\n" . $this->hashBlock($codeblock) . "\n\n";
        }
 
-
+       /**
+        * Create a code span markup for $code. Called from handleSpanToken.
+        * @param  string $code
+        * @return string
+        */
        protected function makeCodeSpan($code) {
-       #
-       # Create a code span markup for $code. Called from handleSpanToken.
-       #
-               $code = htmlspecialchars(trim($code), ENT_NOQUOTES);
+               if ($this->code_span_content_func) {
+                       $code = call_user_func($this->code_span_content_func, $code);
+               } else {
+                       $code = htmlspecialchars(trim($code), ENT_NOQUOTES);
+               }
                return $this->hashPart("<code>$code</code>");
        }
 
-
+       /**
+        * Define the emphasis operators with their regex matches
+        * @var array
+        */
        protected $em_relist = array(
                ''  => '(?:(?<!\*)\*(?!\*)|(?<!_)_(?!_))(?![\.,:;]?\s)',
                '*' => '(?<![\s*])\*(?!\*)',
                '_' => '(?<![\s_])_(?!_)',
-               );
+       );
+
+       /**
+        * Define the strong operators with their regex matches
+        * @var array
+        */
        protected $strong_relist = array(
                ''   => '(?:(?<!\*)\*\*(?!\*)|(?<!_)__(?!_))(?![\.,:;]?\s)',
                '**' => '(?<![\s*])\*\*(?!\*)',
                '__' => '(?<![\s_])__(?!_)',
-               );
+       );
+
+       /**
+        * Define the emphasis + strong operators with their regex matches
+        * @var array
+        */
        protected $em_strong_relist = array(
                ''    => '(?:(?<!\*)\*\*\*(?!\*)|(?<!_)___(?!_))(?![\.,:;]?\s)',
                '***' => '(?<![\s*])\*\*\*(?!\*)',
                '___' => '(?<![\s_])___(?!_)',
-               );
+       );
+
+       /**
+        * Container for prepared regular expressions
+        * @var array
+        */
        protected $em_strong_prepared_relist;
-       
+
+       /**
+        * Prepare regular expressions for searching emphasis tokens in any
+        * context.
+        * @return void
+        */
        protected function prepareItalicsAndBold() {
-       #
-       # Prepare regular expressions for searching emphasis tokens in any
-       # context.
-       #
                foreach ($this->em_relist as $em => $em_re) {
                        foreach ($this->strong_relist as $strong => $strong_re) {
-                               # Construct list of allowed token expressions.
+                               // Construct list of allowed token expressions.
                                $token_relist = array();
                                if (isset($this->em_strong_relist["$em$strong"])) {
                                        $token_relist[] = $this->em_strong_relist["$em$strong"];
                                }
                                $token_relist[] = $em_re;
                                $token_relist[] = $strong_re;
-                               
-                               # Construct master expression from list.
-                               $token_re = '{('. implode('|', $token_relist) .')}';
+
+                               // Construct master expression from list.
+                               $token_re = '{(' . implode('|', $token_relist) . ')}';
                                $this->em_strong_prepared_relist["$em$strong"] = $token_re;
                        }
                }
        }
-       
+
+       /**
+        * Convert Markdown italics (emphasis) and bold (strong) to HTML
+        * @param  string $text
+        * @return string
+        */
        protected function doItalicsAndBold($text) {
                $token_stack = array('');
                $text_stack = array('');
                $em = '';
                $strong = '';
                $tree_char_em = false;
-               
+
                while (1) {
-                       #
-                       # Get prepared regular expression for seraching emphasis tokens
-                       # in current context.
-                       #
+                       // Get prepared regular expression for seraching emphasis tokens
+                       // in current context.
                        $token_re = $this->em_strong_prepared_relist["$em$strong"];
-                       
-                       #
-                       # Each loop iteration search for the next emphasis token. 
-                       # Each token is then passed to handleSpanToken.
-                       #
+
+                       // Each loop iteration search for the next emphasis token.
+                       // Each token is then passed to handleSpanToken.
                        $parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
                        $text_stack[0] .= $parts[0];
                        $token =& $parts[1];
                        $text =& $parts[2];
-                       
+
                        if (empty($token)) {
-                               # Reached end of text span: empty stack without emitting.
-                               # any more emphasis.
+                               // Reached end of text span: empty stack without emitting.
+                               // any more emphasis.
                                while ($token_stack[0]) {
                                        $text_stack[1] .= array_shift($token_stack);
                                        $text_stack[0] .= array_shift($text_stack);
                                }
                                break;
                        }
-                       
+
                        $token_len = strlen($token);
                        if ($tree_char_em) {
-                               # Reached closing marker while inside a three-char emphasis.
+                               // Reached closing marker while inside a three-char emphasis.
                                if ($token_len == 3) {
-                                       # Three-char closing marker, close em and strong.
+                                       // Three-char closing marker, close em and strong.
                                        array_shift($token_stack);
                                        $span = array_shift($text_stack);
                                        $span = $this->runSpanGamut($span);
@@ -1071,21 +1344,21 @@ class Markdown implements MarkdownInterface {
                                        $em = '';
                                        $strong = '';
                                } else {
-                                       # Other closing marker: close one em or strong and
-                                       # change current token state to match the other
+                                       // Other closing marker: close one em or strong and
+                                       // change current token state to match the other
                                        $token_stack[0] = str_repeat($token{0}, 3-$token_len);
                                        $tag = $token_len == 2 ? "strong" : "em";
                                        $span = $text_stack[0];
                                        $span = $this->runSpanGamut($span);
                                        $span = "<$tag>$span</$tag>";
                                        $text_stack[0] = $this->hashPart($span);
-                                       $$tag = ''; # $$tag stands for $em or $strong
+                                       $$tag = ''; // $$tag stands for $em or $strong
                                }
                                $tree_char_em = false;
                        } else if ($token_len == 3) {
                                if ($em) {
-                                       # Reached closing marker for both em and strong.
-                                       # Closing strong marker:
+                                       // Reached closing marker for both em and strong.
+                                       // Closing strong marker:
                                        for ($i = 0; $i < 2; ++$i) {
                                                $shifted_token = array_shift($token_stack);
                                                $tag = strlen($shifted_token) == 2 ? "strong" : "em";
@@ -1093,11 +1366,11 @@ class Markdown implements MarkdownInterface {
                                                $span = $this->runSpanGamut($span);
                                                $span = "<$tag>$span</$tag>";
                                                $text_stack[0] .= $this->hashPart($span);
-                                               $$tag = ''; # $$tag stands for $em or $strong
+                                               $$tag = ''; // $$tag stands for $em or $strong
                                        }
                                } else {
-                                       # Reached opening three-char emphasis marker. Push on token 
-                                       # stack; will be handled by the special condition above.
+                                       // Reached opening three-char emphasis marker. Push on token
+                                       // stack; will be handled by the special condition above.
                                        $em = $token{0};
                                        $strong = "$em$em";
                                        array_unshift($token_stack, $token);
@@ -1106,12 +1379,12 @@ class Markdown implements MarkdownInterface {
                                }
                        } else if ($token_len == 2) {
                                if ($strong) {
-                                       # Unwind any dangling emphasis marker:
+                                       // Unwind any dangling emphasis marker:
                                        if (strlen($token_stack[0]) == 1) {
                                                $text_stack[1] .= array_shift($token_stack);
                                                $text_stack[0] .= array_shift($text_stack);
                                        }
-                                       # Closing strong marker:
+                                       // Closing strong marker:
                                        array_shift($token_stack);
                                        $span = array_shift($text_stack);
                                        $span = $this->runSpanGamut($span);
@@ -1124,10 +1397,10 @@ class Markdown implements MarkdownInterface {
                                        $strong = $token;
                                }
                        } else {
-                               # Here $token_len == 1
+                               // Here $token_len == 1
                                if ($em) {
                                        if (strlen($token_stack[0]) == 1) {
-                                               # Closing emphasis marker:
+                                               // Closing emphasis marker:
                                                array_shift($token_stack);
                                                $span = array_shift($text_stack);
                                                $span = $this->runSpanGamut($span);
@@ -1147,7 +1420,11 @@ class Markdown implements MarkdownInterface {
                return $text_stack[0];
        }
 
-
+       /**
+        * Parse Markdown blockquotes to HTML
+        * @param  string $text
+        * @return string
+        */
        protected function doBlockQuotes($text) {
                $text = preg_replace_callback('/
                          (                                                             # Wrap whole match in $1
@@ -1163,51 +1440,64 @@ class Markdown implements MarkdownInterface {
 
                return $text;
        }
+
+       /**
+        * Blockquote parsing callback
+        * @param  array $matches
+        * @return string
+        */
        protected function _doBlockQuotes_callback($matches) {
                $bq = $matches[1];
-               # trim one level of quoting - trim whitespace-only lines
+               // trim one level of quoting - trim whitespace-only lines
                $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq);
-               $bq = $this->runBlockGamut($bq);                # recurse
+               $bq = $this->runBlockGamut($bq); // recurse
 
                $bq = preg_replace('/^/m', "  ", $bq);
-               # These leading spaces cause problem with <pre> content, 
-               # so we need to fix that:
-               $bq = preg_replace_callback('{(\s*<pre>.+?</pre>)}sx', 
+               // These leading spaces cause problem with <pre> content,
+               // so we need to fix that:
+               $bq = preg_replace_callback('{(\s*<pre>.+?</pre>)}sx',
                        array($this, '_doBlockQuotes_callback2'), $bq);
 
-               return "\n". $this->hashBlock("<blockquote>\n$bq\n</blockquote>")."\n\n";
+               return "\n" . $this->hashBlock("<blockquote>\n$bq\n</blockquote>") . "\n\n";
        }
+
+       /**
+        * Blockquote parsing callback
+        * @param  array $matches
+        * @return string
+        */
        protected function _doBlockQuotes_callback2($matches) {
                $pre = $matches[1];
                $pre = preg_replace('/^  /m', '', $pre);
                return $pre;
        }
 
-
-       protected function formParagraphs($text) {
-       #
-       #       Params:
-       #               $text - string to process with html <p> tags
-       #
-               # Strip leading and trailing lines:
+       /**
+        * Parse paragraphs
+        *
+        * @param  string $text String to process in paragraphs
+        * @param  boolean $wrap_in_p Whether paragraphs should be wrapped in <p> tags
+        * @return string
+        */
+       protected function formParagraphs($text, $wrap_in_p = true) {
+               // Strip leading and trailing lines:
                $text = preg_replace('/\A\n+|\n+\z/', '', $text);
 
                $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
 
-               #
-               # Wrap <p> tags and unhashify HTML blocks
-               #
+               // Wrap <p> tags and unhashify HTML blocks
                foreach ($grafs as $key => $value) {
                        if (!preg_match('/^B\x1A[0-9]+B$/', $value)) {
-                               # Is a paragraph.
+                               // Is a paragraph.
                                $value = $this->runSpanGamut($value);
-                               $value = preg_replace('/^([ ]*)/', "<p>", $value);
-                               $value .= "</p>";
+                               if ($wrap_in_p) {
+                                       $value = preg_replace('/^([ ]*)/', "<p>", $value);
+                                       $value .= "</p>";
+                               }
                                $grafs[$key] = $this->unhash($value);
-                       }
-                       else {
-                               # Is a block.
-                               # Modify elements of @grafs in-place...
+                       } else {
+                               // Is a block.
+                               // Modify elements of @grafs in-place...
                                $graf = $value;
                                $block = $this->html_hashes[$graf];
                                $graf = $block;
@@ -1232,11 +1522,11 @@ class Markdown implements MarkdownInterface {
 //                             {
 //                                     list(, $div_open, , $div_content, $div_close) = $matches;
 //
-//                                     # We can't call Markdown(), because that resets the hash;
-//                                     # that initialization code should be pulled into its own sub, though.
+//                                     // We can't call Markdown(), because that resets the hash;
+//                                     // that initialization code should be pulled into its own sub, though.
 //                                     $div_content = $this->hashHTMLBlocks($div_content);
-//                                     
-//                                     # Run document gamut methods on the content.
+//
+//                                     // Run document gamut methods on the content.
 //                                     foreach ($this->document_gamut as $method => $priority) {
 //                                             $div_content = $this->$method($div_content);
 //                                     }
@@ -1253,71 +1543,78 @@ class Markdown implements MarkdownInterface {
                return implode("\n\n", $grafs);
        }
 
-
+       /**
+        * Encode text for a double-quoted HTML attribute. This function
+        * is *not* suitable for attributes enclosed in single quotes.
+        * @param  string $text
+        * @return string
+        */
        protected function encodeAttribute($text) {
-       #
-       # Encode text for a double-quoted HTML attribute. This function
-       # is *not* suitable for attributes enclosed in single quotes.
-       #
                $text = $this->encodeAmpsAndAngles($text);
                $text = str_replace('"', '&quot;', $text);
                return $text;
        }
 
-
+       /**
+        * Encode text for a double-quoted HTML attribute containing a URL,
+        * applying the URL filter if set. Also generates the textual
+        * representation for the URL (removing mailto: or tel:) storing it in $text.
+        * This function is *not* suitable for attributes enclosed in single quotes.
+        *
+        * @param  string $url
+        * @param  string &$text Passed by reference
+        * @return string        URL
+        */
        protected function encodeURLAttribute($url, &$text = null) {
-       #
-       # Encode text for a double-quoted HTML attribute containing a URL,
-       # applying the URL filter if set. Also generates the textual
-       # representation for the URL (removing mailto: or tel:) storing it in $text.
-       # This function is *not* suitable for attributes enclosed in single quotes.
-       #
-               if ($this->url_filter_func)
+               if ($this->url_filter_func) {
                        $url = call_user_func($this->url_filter_func, $url);
+               }
 
-               if (preg_match('{^mailto:}i', $url))
+               if (preg_match('{^mailto:}i', $url)) {
                        $url = $this->encodeEntityObfuscatedAttribute($url, $text, 7);
-               else if (preg_match('{^tel:}i', $url))
-               {
+               } else if (preg_match('{^tel:}i', $url)) {
                        $url = $this->encodeAttribute($url);
                        $text = substr($url, 4);
-               }
-               else
-               {
+               } else {
                        $url = $this->encodeAttribute($url);
                        $text = $url;
                }
 
                return $url;
        }
-       
-       
+
+       /**
+        * Smart processing for ampersands and angle brackets that need to
+        * be encoded. Valid character entities are left alone unless the
+        * no-entities mode is set.
+        * @param  string $text
+        * @return string
+        */
        protected function encodeAmpsAndAngles($text) {
-       #
-       # Smart processing for ampersands and angle brackets that need to 
-       # be encoded. Valid character entities are left alone unless the
-       # no-entities mode is set.
-       #
                if ($this->no_entities) {
                        $text = str_replace('&', '&amp;', $text);
                } else {
-                       # Ampersand-encoding based entirely on Nat Irons's Amputator
-                       # MT plugin: <http://bumppo.net/projects/amputator/>
-                       $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/', 
+                       // Ampersand-encoding based entirely on Nat Irons's Amputator
+                       // MT plugin: <http://bumppo.net/projects/amputator/>
+                       $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/',
                                                                '&amp;', $text);
                }
-               # Encode remaining <'s
+               // Encode remaining <'s
                $text = str_replace('<', '&lt;', $text);
 
                return $text;
        }
 
-
+       /**
+        * Parse Markdown automatic links to anchor HTML tags
+        * @param  string $text
+        * @return string
+        */
        protected function doAutoLinks($text) {
                $text = preg_replace_callback('{<((https?|ftp|dict|tel):[^\'">\s]+)>}i',
                        array($this, '_doAutoLinks_url_callback'), $text);
 
-               # Email addresses: <address@domain.foo>
+               // Email addresses: <address@domain.foo>
                $text = preg_replace_callback('{
                        <
                        (?:mailto:)?
@@ -1340,11 +1637,23 @@ class Markdown implements MarkdownInterface {
 
                return $text;
        }
+
+       /**
+        * Parse URL callback
+        * @param  array $matches
+        * @return string
+        */
        protected function _doAutoLinks_url_callback($matches) {
                $url = $this->encodeURLAttribute($matches[1], $text);
                $link = "<a href=\"$url\">$text</a>";
                return $this->hashPart($link);
        }
+
+       /**
+        * Parse email address callback
+        * @param  array $matches
+        * @return string
+        */
        protected function _doAutoLinks_email_callback($matches) {
                $addr = $matches[1];
                $url = $this->encodeURLAttribute("mailto:$addr", $text);
@@ -1352,42 +1661,52 @@ class Markdown implements MarkdownInterface {
                return $this->hashPart($link);
        }
 
-
+       /**
+        * Input: some text to obfuscate, e.g. "mailto:foo@example.com"
+        *
+        * Output: the same text but with most characters encoded as either a
+        *         decimal or hex entity, in the hopes of foiling most address
+        *         harvesting spam bots. E.g.:
+        *
+        *        &#109;&#x61;&#105;&#x6c;&#116;&#x6f;&#58;&#x66;o&#111;
+        *        &#x40;&#101;&#x78;&#97;&#x6d;&#112;&#x6c;&#101;&#46;&#x63;&#111;
+        *        &#x6d;
+        *
+        * Note: the additional output $tail is assigned the same value as the
+        * ouput, minus the number of characters specified by $head_length.
+        *
+        * Based by a filter by Matthew Wickline, posted to BBEdit-Talk.
+        * With some optimizations by Milian Wolff. Forced encoding of HTML
+        * attribute special characters by Allan Odgaard.
+        *
+        * @param  string  $text
+        * @param  string  &$tail
+        * @param  integer $head_length
+        * @return string
+        */
        protected function encodeEntityObfuscatedAttribute($text, &$tail = null, $head_length = 0) {
-       #
-       #       Input: some text to obfuscate, e.g. "mailto:foo@example.com"
-       #
-       #       Output: the same text but with most characters encoded as either a
-       #               decimal or hex entity, in the hopes of foiling most address
-       #               harvesting spam bots. E.g.:
-       #
-       #        &#109;&#x61;&#105;&#x6c;&#116;&#x6f;&#58;&#x66;o&#111;
-       #        &#x40;&#101;&#x78;&#97;&#x6d;&#112;&#x6c;&#101;&#46;&#x63;&#111;
-       #        &#x6d;
-       #
-       #       Note: the additional output $tail is assigned the same value as the
-       #       ouput, minus the number of characters specified by $head_length.
-       #
-       #       Based by a filter by Matthew Wickline, posted to BBEdit-Talk.
-       #   With some optimizations by Milian Wolff. Forced encoding of HTML
-       #       attribute special characters by Allan Odgaard.
-       #
-               if ($text == "") return $tail = "";
+               if ($text == "") {
+                       return $tail = "";
+               }
 
                $chars = preg_split('/(?<!^)(?!$)/', $text);
-               $seed = (int)abs(crc32($text) / strlen($text)); # Deterministic seed.
+               $seed = (int)abs(crc32($text) / strlen($text)); // Deterministic seed.
 
                foreach ($chars as $key => $char) {
                        $ord = ord($char);
-                       # Ignore non-ascii chars.
+                       // Ignore non-ascii chars.
                        if ($ord < 128) {
-                               $r = ($seed * (1 + $key)) % 100; # Pseudo-random function.
-                               # roughly 10% raw, 45% hex, 45% dec
-                               # '@' *must* be encoded. I insist.
-                               # '"' and '>' have to be encoded inside the attribute
-                               if ($r > 90 && strpos('@"&>', $char) === false) /* do nothing */;
-                               else if ($r < 45) $chars[$key] = '&#x'.dechex($ord).';';
-                               else              $chars[$key] = '&#'.$ord.';';
+                               $r = ($seed * (1 + $key)) % 100; // Pseudo-random function.
+                               // roughly 10% raw, 45% hex, 45% dec
+                               // '@' *must* be encoded. I insist.
+                               // '"' and '>' have to be encoded inside the attribute
+                               if ($r > 90 && strpos('@"&>', $char) === false) {
+                                       /* do nothing */
+                               } else if ($r < 45) {
+                                       $chars[$key] = '&#x'.dechex($ord).';';
+                               } else {
+                                       $chars[$key] = '&#'.$ord.';';
+                               }
                        }
                }
 
@@ -1397,14 +1716,15 @@ class Markdown implements MarkdownInterface {
                return $text;
        }
 
-
+       /**
+        * Take the string $str and parse it into tokens, hashing embeded HTML,
+        * escaped characters and handling code spans.
+        * @param  string $str
+        * @return string
+        */
        protected function parseSpan($str) {
-       #
-       # Take the string $str and parse it into tokens, hashing embeded HTML,
-       # escaped characters and handling code spans.
-       #
                $output = '';
-               
+
                $span_re = '{
                                (
                                        \\\\'.$this->escape_chars_re.'
@@ -1432,1720 +1752,145 @@ class Markdown implements MarkdownInterface {
                                }xs';
 
                while (1) {
-                       #
-                       # Each loop iteration seach for either the next tag, the next 
-                       # openning code span marker, or the next escaped character. 
-                       # Each token is then passed to handleSpanToken.
-                       #
+                       // Each loop iteration seach for either the next tag, the next
+                       // openning code span marker, or the next escaped character.
+                       // Each token is then passed to handleSpanToken.
                        $parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE);
-                       
-                       # Create token from text preceding tag.
+
+                       // Create token from text preceding tag.
                        if ($parts[0] != "") {
                                $output .= $parts[0];
                        }
-                       
-                       # Check if we reach the end.
+
+                       // Check if we reach the end.
                        if (isset($parts[1])) {
                                $output .= $this->handleSpanToken($parts[1], $parts[2]);
                                $str = $parts[2];
-                       }
-                       else {
+                       } else {
                                break;
                        }
                }
-               
+
                return $output;
        }
-       
-       
+
+       /**
+        * Handle $token provided by parseSpan by determining its nature and
+        * returning the corresponding value that should replace it.
+        * @param  string $token
+        * @param  string &$str
+        * @return string
+        */
        protected function handleSpanToken($token, &$str) {
-       #
-       # Handle $token provided by parseSpan by determining its nature and 
-       # returning the corresponding value that should replace it.
-       #
                switch ($token{0}) {
                        case "\\":
                                return $this->hashPart("&#". ord($token{1}). ";");
                        case "`":
-                               # Search for end marker in remaining text.
-                               if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm', 
+                               // Search for end marker in remaining text.
+                               if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm',
                                        $str, $matches))
                                {
                                        $str = $matches[2];
                                        $codespan = $this->makeCodeSpan($matches[1]);
                                        return $this->hashPart($codespan);
                                }
-                               return $token; // return as text since no ending marker found.
+                               return $token; // Return as text since no ending marker found.
                        default:
                                return $this->hashPart($token);
                }
        }
 
-
+       /**
+        * Remove one level of line-leading tabs or spaces
+        * @param  string $text
+        * @return string
+        */
        protected function outdent($text) {
-       #
-       # Remove one level of line-leading tabs or spaces
-       #
-               return preg_replace('/^(\t|[ ]{1,'.$this->tab_width.'})/m', '', $text);
+               return preg_replace('/^(\t|[ ]{1,' . $this->tab_width . '})/m', '', $text);
        }
 
 
-       # String length function for detab. `_initDetab` will create a function to 
-       # hanlde UTF-8 if the default function does not exist.
+       /**
+        * String length function for detab. `_initDetab` will create a function to
+        * handle UTF-8 if the default function does not exist.
+        * @var string
+        */
        protected $utf8_strlen = 'mb_strlen';
-       
+
+       /**
+        * Replace tabs with the appropriate amount of spaces.
+        *
+        * For each line we separate the line in blocks delemited by tab characters.
+        * Then we reconstruct every line by adding the  appropriate number of space
+        * between each blocks.
+        *
+        * @param  string $text
+        * @return string
+        */
        protected function detab($text) {
-       #
-       # Replace tabs with the appropriate amount of space.
-       #
-               # For each line we separate the line in blocks delemited by
-               # tab characters. Then we reconstruct every line by adding the 
-               # appropriate number of space between each blocks.
-               
                $text = preg_replace_callback('/^.*\t.*$/m',
                        array($this, '_detab_callback'), $text);
 
                return $text;
        }
+
+       /**
+        * Replace tabs callback
+        * @param  string $matches
+        * @return string
+        */
        protected function _detab_callback($matches) {
                $line = $matches[0];
-               $strlen = $this->utf8_strlen; # strlen function for UTF-8.
-               
-               # Split in blocks.
+               $strlen = $this->utf8_strlen; // strlen function for UTF-8.
+
+               // Split in blocks.
                $blocks = explode("\t", $line);
-               # Add each blocks to the line.
+               // Add each blocks to the line.
                $line = $blocks[0];
-               unset($blocks[0]); # Do not add first block twice.
+               unset($blocks[0]); // Do not add first block twice.
                foreach ($blocks as $block) {
-                       # Calculate amount of space, insert spaces, insert block.
-                       $amount = $this->tab_width - 
+                       // Calculate amount of space, insert spaces, insert block.
+                       $amount = $this->tab_width -
                                $strlen($line, 'UTF-8') % $this->tab_width;
                        $line .= str_repeat(" ", $amount) . $block;
                }
                return $line;
        }
+
+       /**
+        * Check for the availability of the function in the `utf8_strlen` property
+        * (initially `mb_strlen`). If the function is not available, create a
+        * function that will loosely count the number of UTF-8 characters with a
+        * regular expression.
+        * @return void
+        */
        protected function _initDetab() {
-       #
-       # Check for the availability of the function in the `utf8_strlen` property
-       # (initially `mb_strlen`). If the function is not available, create a 
-       # function that will loosely count the number of UTF-8 characters with a
-       # regular expression.
-       #
-               if (function_exists($this->utf8_strlen)) return;
+
+               if (function_exists($this->utf8_strlen)) {
+                       return;
+               }
+
                $this->utf8_strlen = create_function('$text', 'return preg_match_all(
-                       "/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/", 
+                       "/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/",
                        $text, $m);');
        }
 
-
+       /**
+        * Swap back in all the tags hashed by _HashHTMLBlocks.
+        * @param  string $text
+        * @return string
+        */
        protected function unhash($text) {
-       #
-       # Swap back in all the tags hashed by _HashHTMLBlocks.
-       #
-               return preg_replace_callback('/(.)\x1A[0-9]+\1/', 
+               return preg_replace_callback('/(.)\x1A[0-9]+\1/',
                        array($this, '_unhash_callback'), $text);
        }
+
+       /**
+        * Unhashing callback
+        * @param  array $matches
+        * @return string
+        */
        protected function _unhash_callback($matches) {
                return $this->html_hashes[$matches[0]];
        }
-
-}
-
-
-#
-# Temporary Markdown Extra Parser Implementation Class
-#
-# NOTE: DON'T USE THIS CLASS
-# Currently the implementation of of Extra resides here in this temporary class.
-# This makes it easier to propagate the changes between the three different
-# packaging styles of PHP Markdown. When this issue is resolved, this
-# MarkdownExtra_TmpImpl class here will disappear and \Michelf\MarkdownExtra
-# will contain the code. So please use \Michelf\MarkdownExtra and ignore this
-# one.
-#
-
-abstract class _MarkdownExtra_TmpImpl extends \Michelf\Markdown {
-
-       ### Configuration Variables ###
-
-       # Prefix for footnote ids.
-       public $fn_id_prefix = "";
-       
-       # Optional title attribute for footnote links and backlinks.
-       public $fn_link_title = "";
-       public $fn_backlink_title = "";
-       
-       # Optional class attribute for footnote links and backlinks.
-       public $fn_link_class = "footnote-ref";
-       public $fn_backlink_class = "footnote-backref";
-
-       # Class name for table cell alignment (%% replaced left/center/right)
-       # For instance: 'go-%%' becomes 'go-left' or 'go-right' or 'go-center'
-       # If empty, the align attribute is used instead of a class name.
-       public $table_align_class_tmpl = '';
-
-       # Optional class prefix for fenced code block.
-       public $code_class_prefix = "";
-       # Class attribute for code blocks goes on the `code` tag;
-       # setting this to true will put attributes on the `pre` tag instead.
-       public $code_attr_on_pre = false;
-       
-       # Predefined abbreviations.
-       public $predef_abbr = array();
-
-
-       ### Parser Implementation ###
-
-       public function __construct() {
-       #
-       # Constructor function. Initialize the parser object.
-       #
-               # Add extra escapable characters before parent constructor 
-               # initialize the table.
-               $this->escape_chars .= ':|';
-               
-               # Insert extra document, block, and span transformations. 
-               # Parent constructor will do the sorting.
-               $this->document_gamut += array(
-                       "doFencedCodeBlocks" => 5,
-                       "stripFootnotes"     => 15,
-                       "stripAbbreviations" => 25,
-                       "appendFootnotes"    => 50,
-                       );
-               $this->block_gamut += array(
-                       "doFencedCodeBlocks" => 5,
-                       "doTables"           => 15,
-                       "doDefLists"         => 45,
-                       );
-               $this->span_gamut += array(
-                       "doFootnotes"        => 5,
-                       "doAbbreviations"    => 70,
-                       );
-               
-               parent::__construct();
-       }
-       
-       
-       # Extra variables used during extra transformations.
-       protected $footnotes = array();
-       protected $footnotes_ordered = array();
-       protected $footnotes_ref_count = array();
-       protected $footnotes_numbers = array();
-       protected $abbr_desciptions = array();
-       protected $abbr_word_re = '';
-       
-       # Give the current footnote number.
-       protected $footnote_counter = 1;
-       
-       
-       protected function setup() {
-       #
-       # Setting up Extra-specific variables.
-       #
-               parent::setup();
-               
-               $this->footnotes = array();
-               $this->footnotes_ordered = array();
-               $this->footnotes_ref_count = array();
-               $this->footnotes_numbers = array();
-               $this->abbr_desciptions = array();
-               $this->abbr_word_re = '';
-               $this->footnote_counter = 1;
-               
-               foreach ($this->predef_abbr as $abbr_word => $abbr_desc) {
-                       if ($this->abbr_word_re)
-                               $this->abbr_word_re .= '|';
-                       $this->abbr_word_re .= preg_quote($abbr_word);
-                       $this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
-               }
-       }
-       
-       protected function teardown() {
-       #
-       # Clearing Extra-specific variables.
-       #
-               $this->footnotes = array();
-               $this->footnotes_ordered = array();
-               $this->footnotes_ref_count = array();
-               $this->footnotes_numbers = array();
-               $this->abbr_desciptions = array();
-               $this->abbr_word_re = '';
-               
-               parent::teardown();
-       }
-       
-       
-       ### Extra Attribute Parser ###
-
-       # Expression to use to catch attributes (includes the braces)
-       protected $id_class_attr_catch_re = '\{((?:[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,})[ ]*\}';
-       # Expression to use when parsing in a context when no capture is desired
-       protected $id_class_attr_nocatch_re = '\{(?:[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,}[ ]*\}';
-
-       protected function doExtraAttributes($tag_name, $attr) {
-       #
-       # Parse attributes caught by the $this->id_class_attr_catch_re expression
-       # and return the HTML-formatted list of attributes.
-       #
-       # Currently supported attributes are .class and #id.
-       #
-               if (empty($attr)) return "";
-               
-               # Split on components
-               preg_match_all('/[#.a-z][-_:a-zA-Z0-9=]+/', $attr, $matches);
-               $elements = $matches[0];
-
-               # handle classes and ids (only first id taken into account)
-               $classes = array();
-               $attributes = array();
-               $id = false;
-               foreach ($elements as $element) {
-                       if ($element{0} == '.') {
-                               $classes[] = substr($element, 1);
-                       } else if ($element{0} == '#') {
-                               if ($id === false) $id = substr($element, 1);
-                       } else if (strpos($element, '=') > 0) {
-                               $parts = explode('=', $element, 2);
-                               $attributes[] = $parts[0] . '="' . $parts[1] . '"';
-                       }
-               }
-
-               # compose attributes as string
-               $attr_str = "";
-               if (!empty($id)) {
-                       $attr_str .= ' id="'.$id.'"';
-               }
-               if (!empty($classes)) {
-                       $attr_str .= ' class="'.implode(" ", $classes).'"';
-               }
-               if (!$this->no_markup && !empty($attributes)) {
-                       $attr_str .= ' '.implode(" ", $attributes);
-               }
-               return $attr_str;
-       }
-
-
-       protected function stripLinkDefinitions($text) {
-       #
-       # Strips link definitions from text, stores the URLs and titles in
-       # hash references.
-       #
-               $less_than_tab = $this->tab_width - 1;
-
-               # Link defs are in the form: ^[id]: url "optional title"
-               $text = preg_replace_callback('{
-                                                       ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1
-                                                         [ ]*
-                                                         \n?                           # maybe *one* newline
-                                                         [ ]*
-                                                       (?:
-                                                         <(.+?)>                       # url = $2
-                                                       |
-                                                         (\S+?)                        # url = $3
-                                                       )
-                                                         [ ]*
-                                                         \n?                           # maybe one newline
-                                                         [ ]*
-                                                       (?:
-                                                               (?<=\s)                 # lookbehind for whitespace
-                                                               ["(]
-                                                               (.*?)                   # title = $4
-                                                               [")]
-                                                               [ ]*
-                                                       )?      # title is optional
-                                       (?:[ ]* '.$this->id_class_attr_catch_re.' )?  # $5 = extra id & class attr
-                                                       (?:\n+|\Z)
-                       }xm',
-                       array($this, '_stripLinkDefinitions_callback'),
-                       $text);
-               return $text;
-       }
-       protected function _stripLinkDefinitions_callback($matches) {
-               $link_id = strtolower($matches[1]);
-               $url = $matches[2] == '' ? $matches[3] : $matches[2];
-               $this->urls[$link_id] = $url;
-               $this->titles[$link_id] =& $matches[4];
-               $this->ref_attr[$link_id] = $this->doExtraAttributes("", $dummy =& $matches[5]);
-               return ''; # String that will replace the block
-       }
-
-
-       ### HTML Block Parser ###
-       
-       # Tags that are always treated as block tags:
-       protected $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend|article|section|nav|aside|hgroup|header|footer|figcaption|figure';
-                                                  
-       # Tags treated as block tags only if the opening tag is alone on its line:
-       protected $context_block_tags_re = 'script|noscript|style|ins|del|iframe|object|source|track|param|math|svg|canvas|audio|video';
-       
-       # Tags where markdown="1" default to span mode:
-       protected $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address';
-       
-       # Tags which must not have their contents modified, no matter where 
-       # they appear:
-       protected $clean_tags_re = 'script|style|math|svg';
-       
-       # Tags that do not need to be closed.
-       protected $auto_close_tags_re = 'hr|img|param|source|track';
-       
-
-       protected function hashHTMLBlocks($text) {
-       #
-       # Hashify HTML Blocks and "clean tags".
-       #
-       # We only want to do this for block-level HTML tags, such as headers,
-       # lists, and tables. That's because we still want to wrap <p>s around
-       # "paragraphs" that are wrapped in non-block-level tags, such as anchors,
-       # phrase emphasis, and spans. The list of tags we're looking for is
-       # hard-coded.
-       #
-       # This works by calling _HashHTMLBlocks_InMarkdown, which then calls
-       # _HashHTMLBlocks_InHTML when it encounter block tags. When the markdown="1" 
-       # attribute is found within a tag, _HashHTMLBlocks_InHTML calls back
-       #  _HashHTMLBlocks_InMarkdown to handle the Markdown syntax within the tag.
-       # These two functions are calling each other. It's recursive!
-       #
-               if ($this->no_markup)  return $text;
-
-               #
-               # Call the HTML-in-Markdown hasher.
-               #
-               list($text, ) = $this->_hashHTMLBlocks_inMarkdown($text);
-               
-               return $text;
-       }
-       protected function _hashHTMLBlocks_inMarkdown($text, $indent = 0,
-                                                                               $enclosing_tag_re = '', $span = false)
-       {
-       #
-       # Parse markdown text, calling _HashHTMLBlocks_InHTML for block tags.
-       #
-       # *   $indent is the number of space to be ignored when checking for code 
-       #     blocks. This is important because if we don't take the indent into 
-       #     account, something like this (which looks right) won't work as expected:
-       #
-       #     <div>
-       #         <div markdown="1">
-       #         Hello World.  <-- Is this a Markdown code block or text?
-       #         </div>  <-- Is this a Markdown code block or a real tag?
-       #     <div>
-       #
-       #     If you don't like this, just don't indent the tag on which
-       #     you apply the markdown="1" attribute.
-       #
-       # *   If $enclosing_tag_re is not empty, stops at the first unmatched closing 
-       #     tag with that name. Nested tags supported.
-       #
-       # *   If $span is true, text inside must treated as span. So any double 
-       #     newline will be replaced by a single newline so that it does not create 
-       #     paragraphs.
-       #
-       # Returns an array of that form: ( processed text , remaining text )
-       #
-               if ($text === '') return array('', '');
-
-               # Regex to check for the presense of newlines around a block tag.
-               $newline_before_re = '/(?:^\n?|\n\n)*$/';
-               $newline_after_re = 
-                       '{
-                               ^                                               # Start of text following the tag.
-                               (?>[ ]*<!--.*?-->)?             # Optional comment.
-                               [ ]*\n                                  # Must be followed by newline.
-                       }xs';
-               
-               # Regex to match any tag.
-               $block_tag_re =
-                       '{
-                               (                                       # $2: Capture whole tag.
-                                       </?                                     # Any opening or closing tag.
-                                               (?>                             # Tag name.
-                                                       '.$this->block_tags_re.'                        |
-                                                       '.$this->context_block_tags_re.'        |
-                                                       '.$this->clean_tags_re.'                |
-                                                       (?!\s)'.$enclosing_tag_re.'
-                                               )
-                                               (?:
-                                                       (?=[\s"\'/a-zA-Z0-9])   # Allowed characters after tag name.
-                                                       (?>
-                                                               ".*?"           |       # Double quotes (can contain `>`)
-                                                               \'.*?\'         |       # Single quotes (can contain `>`)
-                                                               .+?                             # Anything but quotes and `>`.
-                                                       )*?
-                                               )?
-                                       >                                       # End of tag.
-                               |
-                                       <!--    .*?     -->     # HTML Comment
-                               |
-                                       <\?.*?\?> | <%.*?%>     # Processing instruction
-                               |
-                                       <!\[CDATA\[.*?\]\]>     # CData Block
-                               '. ( !$span ? ' # If not in span.
-                               |
-                                       # Indented code block
-                                       (?: ^[ ]*\n | ^ | \n[ ]*\n )
-                                       [ ]{'.($indent+4).'}[^\n]* \n
-                                       (?>
-                                               (?: [ ]{'.($indent+4).'}[^\n]* | [ ]* ) \n
-                                       )*
-                               |
-                                       # Fenced code block marker
-                                       (?<= ^ | \n )
-                                       [ ]{0,'.($indent+3).'}(?:~{3,}|`{3,})
-                                                                       [ ]*
-                                       (?:
-                                       \.?[-_:a-zA-Z0-9]+ # standalone class name
-                                       |
-                                               '.$this->id_class_attr_nocatch_re.' # extra attributes
-                                       )?
-                                       [ ]*
-                                       (?= \n )
-                               ' : '' ). ' # End (if not is span).
-                               |
-                                       # Code span marker
-                                       # Note, this regex needs to go after backtick fenced
-                                       # code blocks but it should also be kept outside of the
-                                       # "if not in span" condition adding backticks to the parser
-                                       `+
-                               )
-                       }xs';
-
-               
-               $depth = 0;             # Current depth inside the tag tree.
-               $parsed = "";   # Parsed text that will be returned.
-
-               #
-               # Loop through every tag until we find the closing tag of the parent
-               # or loop until reaching the end of text if no parent tag specified.
-               #
-               do {
-                       #
-                       # Split the text using the first $tag_match pattern found.
-                       # Text before  pattern will be first in the array, text after
-                       # pattern will be at the end, and between will be any catches made 
-                       # by the pattern.
-                       #
-                       $parts = preg_split($block_tag_re, $text, 2, 
-                                                               PREG_SPLIT_DELIM_CAPTURE);
-                       
-                       # If in Markdown span mode, add a empty-string span-level hash 
-                       # after each newline to prevent triggering any block element.
-                       if ($span) {
-                               $void = $this->hashPart("", ':');
-                               $newline = "$void\n";
-                               $parts[0] = $void . str_replace("\n", $newline, $parts[0]) . $void;
-                       }
-                       
-                       $parsed .= $parts[0]; # Text before current tag.
-                       
-                       # If end of $text has been reached. Stop loop.
-                       if (count($parts) < 3) {
-                               $text = "";
-                               break;
-                       }
-                       
-                       $tag  = $parts[1]; # Tag to handle.
-                       $text = $parts[2]; # Remaining text after current tag.
-                       $tag_re = preg_quote($tag); # For use in a regular expression.
-                       
-                       #
-                       # Check for: Fenced code block marker.
-                       # Note: need to recheck the whole tag to disambiguate backtick
-                       # fences from code spans
-                       #
-                       if (preg_match('{^\n?([ ]{0,'.($indent+3).'})(~{3,}|`{3,})[ ]*(?:\.?[-_:a-zA-Z0-9]+|'.$this->id_class_attr_nocatch_re.')?[ ]*\n?$}', $tag, $capture)) {
-                               # Fenced code block marker: find matching end marker.
-                               $fence_indent = strlen($capture[1]); # use captured indent in re
-                               $fence_re = $capture[2]; # use captured fence in re
-                               if (preg_match('{^(?>.*\n)*?[ ]{'.($fence_indent).'}'.$fence_re.'[ ]*(?:\n|$)}', $text,
-                                       $matches)) 
-                               {
-                                       # End marker found: pass text unchanged until marker.
-                                       $parsed .= $tag . $matches[0];
-                                       $text = substr($text, strlen($matches[0]));
-                               }
-                               else {
-                                       # No end marker: just skip it.
-                                       $parsed .= $tag;
-                               }
-                       }
-                       #
-                       # Check for: Indented code block.
-                       #
-                       else if ($tag{0} == "\n" || $tag{0} == " ") {
-                               # Indented code block: pass it unchanged, will be handled 
-                               # later.
-                               $parsed .= $tag;
-                       }
-                       #
-                       # Check for: Code span marker
-                       # Note: need to check this after backtick fenced code blocks
-                       #
-                       else if ($tag{0} == "`") {
-                               # Find corresponding end marker.
-                               $tag_re = preg_quote($tag);
-                               if (preg_match('{^(?>.+?|\n(?!\n))*?(?<!`)'.$tag_re.'(?!`)}',
-                                       $text, $matches))
-                               {
-                                       # End marker found: pass text unchanged until marker.
-                                       $parsed .= $tag . $matches[0];
-                                       $text = substr($text, strlen($matches[0]));
-                               }
-                               else {
-                                       # Unmatched marker: just skip it.
-                                       $parsed .= $tag;
-                               }
-                       }
-                       #
-                       # Check for: Opening Block level tag or
-                       #            Opening Context Block tag (like ins and del) 
-                       #               used as a block tag (tag is alone on it's line).
-                       #
-                       else if (preg_match('{^<(?:'.$this->block_tags_re.')\b}', $tag) ||
-                               (       preg_match('{^<(?:'.$this->context_block_tags_re.')\b}', $tag) &&
-                                       preg_match($newline_before_re, $parsed) &&
-                                       preg_match($newline_after_re, $text)    )
-                               )
-                       {
-                               # Need to parse tag and following text using the HTML parser.
-                               list($block_text, $text) = 
-                                       $this->_hashHTMLBlocks_inHTML($tag . $text, "hashBlock", true);
-                               
-                               # Make sure it stays outside of any paragraph by adding newlines.
-                               $parsed .= "\n\n$block_text\n\n";
-                       }
-                       #
-                       # Check for: Clean tag (like script, math)
-                       #            HTML Comments, processing instructions.
-                       #
-                       else if (preg_match('{^<(?:'.$this->clean_tags_re.')\b}', $tag) ||
-                               $tag{1} == '!' || $tag{1} == '?')
-                       {
-                               # Need to parse tag and following text using the HTML parser.
-                               # (don't check for markdown attribute)
-                               list($block_text, $text) = 
-                                       $this->_hashHTMLBlocks_inHTML($tag . $text, "hashClean", false);
-                               
-                               $parsed .= $block_text;
-                       }
-                       #
-                       # Check for: Tag with same name as enclosing tag.
-                       #
-                       else if ($enclosing_tag_re !== '' &&
-                               # Same name as enclosing tag.
-                               preg_match('{^</?(?:'.$enclosing_tag_re.')\b}', $tag))
-                       {
-                               #
-                               # Increase/decrease nested tag count.
-                               #
-                               if ($tag{1} == '/')                                             $depth--;
-                               else if ($tag{strlen($tag)-2} != '/')   $depth++;
-
-                               if ($depth < 0) {
-                                       #
-                                       # Going out of parent element. Clean up and break so we
-                                       # return to the calling function.
-                                       #
-                                       $text = $tag . $text;
-                                       break;
-                               }
-                               
-                               $parsed .= $tag;
-                       }
-                       else {
-                               $parsed .= $tag;
-                       }
-               } while ($depth >= 0);
-               
-               return array($parsed, $text);
-       }
-       protected function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) {
-       #
-       # Parse HTML, calling _HashHTMLBlocks_InMarkdown for block tags.
-       #
-       # *   Calls $hash_method to convert any blocks.
-       # *   Stops when the first opening tag closes.
-       # *   $md_attr indicate if the use of the `markdown="1"` attribute is allowed.
-       #     (it is not inside clean tags)
-       #
-       # Returns an array of that form: ( processed text , remaining text )
-       #
-               if ($text === '') return array('', '');
-               
-               # Regex to match `markdown` attribute inside of a tag.
-               $markdown_attr_re = '
-                       {
-                               \s*                     # Eat whitespace before the `markdown` attribute
-                               markdown
-                               \s*=\s*
-                               (?>
-                                       (["\'])         # $1: quote delimiter           
-                                       (.*?)           # $2: attribute value
-                                       \1                      # matching delimiter    
-                               |
-                                       ([^\s>]*)       # $3: unquoted attribute value
-                               )
-                               ()                              # $4: make $3 always defined (avoid warnings)
-                       }xs';
-               
-               # Regex to match any tag.
-               $tag_re = '{
-                               (                                       # $2: Capture whole tag.
-                                       </?                                     # Any opening or closing tag.
-                                               [\w:$]+                 # Tag name.
-                                               (?:
-                                                       (?=[\s"\'/a-zA-Z0-9])   # Allowed characters after tag name.
-                                                       (?>
-                                                               ".*?"           |       # Double quotes (can contain `>`)
-                                                               \'.*?\'         |       # Single quotes (can contain `>`)
-                                                               .+?                             # Anything but quotes and `>`.
-                                                       )*?
-                                               )?
-                                       >                                       # End of tag.
-                               |
-                                       <!--    .*?     -->     # HTML Comment
-                               |
-                                       <\?.*?\?> | <%.*?%>     # Processing instruction
-                               |
-                                       <!\[CDATA\[.*?\]\]>     # CData Block
-                               )
-                       }xs';
-               
-               $original_text = $text;         # Save original text in case of faliure.
-               
-               $depth          = 0;    # Current depth inside the tag tree.
-               $block_text     = "";   # Temporary text holder for current text.
-               $parsed         = "";   # Parsed text that will be returned.
-
-               #
-               # Get the name of the starting tag.
-               # (This pattern makes $base_tag_name_re safe without quoting.)
-               #
-               if (preg_match('/^<([\w:$]*)\b/', $text, $matches))
-                       $base_tag_name_re = $matches[1];
-
-               #
-               # Loop through every tag until we find the corresponding closing tag.
-               #
-               do {
-                       #
-                       # Split the text using the first $tag_match pattern found.
-                       # Text before  pattern will be first in the array, text after
-                       # pattern will be at the end, and between will be any catches made 
-                       # by the pattern.
-                       #
-                       $parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
-                       
-                       if (count($parts) < 3) {
-                               #
-                               # End of $text reached with unbalenced tag(s).
-                               # In that case, we return original text unchanged and pass the
-                               # first character as filtered to prevent an infinite loop in the 
-                               # parent function.
-                               #
-                               return array($original_text{0}, substr($original_text, 1));
-                       }
-                       
-                       $block_text .= $parts[0]; # Text before current tag.
-                       $tag         = $parts[1]; # Tag to handle.
-                       $text        = $parts[2]; # Remaining text after current tag.
-                       
-                       #
-                       # Check for: Auto-close tag (like <hr/>)
-                       #                        Comments and Processing Instructions.
-                       #
-                       if (preg_match('{^</?(?:'.$this->auto_close_tags_re.')\b}', $tag) ||
-                               $tag{1} == '!' || $tag{1} == '?')
-                       {
-                               # Just add the tag to the block as if it was text.
-                               $block_text .= $tag;
-                       }
-                       else {
-                               #
-                               # Increase/decrease nested tag count. Only do so if
-                               # the tag's name match base tag's.
-                               #
-                               if (preg_match('{^</?'.$base_tag_name_re.'\b}', $tag)) {
-                                       if ($tag{1} == '/')                                             $depth--;
-                                       else if ($tag{strlen($tag)-2} != '/')   $depth++;
-                               }
-                               
-                               #
-                               # Check for `markdown="1"` attribute and handle it.
-                               #
-                               if ($md_attr && 
-                                       preg_match($markdown_attr_re, $tag, $attr_m) &&
-                                       preg_match('/^1|block|span$/', $attr_m[2] . $attr_m[3]))
-                               {
-                                       # Remove `markdown` attribute from opening tag.
-                                       $tag = preg_replace($markdown_attr_re, '', $tag);
-                                       
-                                       # Check if text inside this tag must be parsed in span mode.
-                                       $this->mode = $attr_m[2] . $attr_m[3];
-                                       $span_mode = $this->mode == 'span' || $this->mode != 'block' &&
-                                               preg_match('{^<(?:'.$this->contain_span_tags_re.')\b}', $tag);
-                                       
-                                       # Calculate indent before tag.
-                                       if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) {
-                                               $strlen = $this->utf8_strlen;
-                                               $indent = $strlen($matches[1], 'UTF-8');
-                                       } else {
-                                               $indent = 0;
-                                       }
-                                       
-                                       # End preceding block with this tag.
-                                       $block_text .= $tag;
-                                       $parsed .= $this->$hash_method($block_text);
-                                       
-                                       # Get enclosing tag name for the ParseMarkdown function.
-                                       # (This pattern makes $tag_name_re safe without quoting.)
-                                       preg_match('/^<([\w:$]*)\b/', $tag, $matches);
-                                       $tag_name_re = $matches[1];
-                                       
-                                       # Parse the content using the HTML-in-Markdown parser.
-                                       list ($block_text, $text)
-                                               = $this->_hashHTMLBlocks_inMarkdown($text, $indent, 
-                                                       $tag_name_re, $span_mode);
-                                       
-                                       # Outdent markdown text.
-                                       if ($indent > 0) {
-                                               $block_text = preg_replace("/^[ ]{1,$indent}/m", "", 
-                                                                                                       $block_text);
-                                       }
-                                       
-                                       # Append tag content to parsed text.
-                                       if (!$span_mode)        $parsed .= "\n\n$block_text\n\n";
-                                       else                            $parsed .= "$block_text";
-                                       
-                                       # Start over with a new block.
-                                       $block_text = "";
-                               }
-                               else $block_text .= $tag;
-                       }
-                       
-               } while ($depth > 0);
-               
-               #
-               # Hash last block text that wasn't processed inside the loop.
-               #
-               $parsed .= $this->$hash_method($block_text);
-               
-               return array($parsed, $text);
-       }
-
-
-       protected function hashClean($text) {
-       #
-       # Called whenever a tag must be hashed when a function inserts a "clean" tag
-       # in $text, it passes through this function and is automaticaly escaped, 
-       # blocking invalid nested overlap.
-       #
-               return $this->hashPart($text, 'C');
-       }
-
-
-       protected function doAnchors($text) {
-       #
-       # Turn Markdown link shortcuts into XHTML <a> tags.
-       #
-               if ($this->in_anchor) return $text;
-               $this->in_anchor = true;
-               
-               #
-               # First, handle reference-style links: [link text] [id]
-               #
-               $text = preg_replace_callback('{
-                       (                                       # wrap whole match in $1
-                         \[
-                               ('.$this->nested_brackets_re.') # link text = $2
-                         \]
-
-                         [ ]?                          # one optional space
-                         (?:\n[ ]*)?           # one optional newline followed by spaces
-
-                         \[
-                               (.*?)           # id = $3
-                         \]
-                       )
-                       }xs',
-                       array($this, '_doAnchors_reference_callback'), $text);
-
-               #
-               # Next, inline-style links: [link text](url "optional title")
-               #
-               $text = preg_replace_callback('{
-                       (                               # wrap whole match in $1
-                         \[
-                               ('.$this->nested_brackets_re.') # link text = $2
-                         \]
-                         \(                    # literal paren
-                               [ \n]*
-                               (?:
-                                       <(.+?)> # href = $3
-                               |
-                                       ('.$this->nested_url_parenthesis_re.')  # href = $4
-                               )
-                               [ \n]*
-                               (                       # $5
-                                 ([\'"])       # quote char = $6
-                                 (.*?)         # Title = $7
-                                 \6            # matching quote
-                                 [ \n]*        # ignore any spaces/tabs between closing quote and )
-                               )?                      # title is optional
-                         \)
-                         (?:[ ]? '.$this->id_class_attr_catch_re.' )?   # $8 = id/class attributes
-                       )
-                       }xs',
-                       array($this, '_doAnchors_inline_callback'), $text);
-
-               #
-               # Last, handle reference-style shortcuts: [link text]
-               # These must come last in case you've also got [link text][1]
-               # or [link text](/foo)
-               #
-               $text = preg_replace_callback('{
-                       (                                       # wrap whole match in $1
-                         \[
-                               ([^\[\]]+)              # link text = $2; can\'t contain [ or ]
-                         \]
-                       )
-                       }xs',
-                       array($this, '_doAnchors_reference_callback'), $text);
-
-               $this->in_anchor = false;
-               return $text;
-       }
-       protected function _doAnchors_reference_callback($matches) {
-               $whole_match =  $matches[1];
-               $link_text   =  $matches[2];
-               $link_id     =& $matches[3];
-
-               if ($link_id == "") {
-                       # for shortcut links like [this][] or [this].
-                       $link_id = $link_text;
-               }
-               
-               # lower-case and turn embedded newlines into spaces
-               $link_id = strtolower($link_id);
-               $link_id = preg_replace('{[ ]?\n}', ' ', $link_id);
-
-               if (isset($this->urls[$link_id])) {
-                       $url = $this->urls[$link_id];
-                       $url = $this->encodeURLAttribute($url);
-                       
-                       $result = "<a href=\"$url\"";
-                       if ( isset( $this->titles[$link_id] ) ) {
-                               $title = $this->titles[$link_id];
-                               $title = $this->encodeAttribute($title);
-                               $result .=  " title=\"$title\"";
-                       }
-                       if (isset($this->ref_attr[$link_id]))
-                               $result .= $this->ref_attr[$link_id];
-               
-                       $link_text = $this->runSpanGamut($link_text);
-                       $result .= ">$link_text</a>";
-                       $result = $this->hashPart($result);
-               }
-               else {
-                       $result = $whole_match;
-               }
-               return $result;
-       }
-       protected function _doAnchors_inline_callback($matches) {
-               $whole_match    =  $matches[1];
-               $link_text              =  $this->runSpanGamut($matches[2]);
-               $url                    =  $matches[3] == '' ? $matches[4] : $matches[3];
-               $title                  =& $matches[7];
-               $attr  = $this->doExtraAttributes("a", $dummy =& $matches[8]);
-
-               // if the URL was of the form <s p a c e s> it got caught by the HTML
-               // tag parser and hashed. Need to reverse the process before using the URL.
-               $unhashed = $this->unhash($url);
-               if ($unhashed != $url)
-                       $url = preg_replace('/^<(.*)>$/', '\1', $unhashed);
-
-               $url = $this->encodeURLAttribute($url);
-
-               $result = "<a href=\"$url\"";
-               if (isset($title)) {
-                       $title = $this->encodeAttribute($title);
-                       $result .=  " title=\"$title\"";
-               }
-               $result .= $attr;
-               
-               $link_text = $this->runSpanGamut($link_text);
-               $result .= ">$link_text</a>";
-
-               return $this->hashPart($result);
-       }
-
-
-       protected function doImages($text) {
-       #
-       # Turn Markdown image shortcuts into <img> tags.
-       #
-               #
-               # First, handle reference-style labeled images: ![alt text][id]
-               #
-               $text = preg_replace_callback('{
-                       (                               # wrap whole match in $1
-                         !\[
-                               ('.$this->nested_brackets_re.')         # alt text = $2
-                         \]
-
-                         [ ]?                          # one optional space
-                         (?:\n[ ]*)?           # one optional newline followed by spaces
-
-                         \[
-                               (.*?)           # id = $3
-                         \]
-
-                       )
-                       }xs', 
-                       array($this, '_doImages_reference_callback'), $text);
-
-               #
-               # Next, handle inline images:  ![alt text](url "optional title")
-               # Don't forget: encode * and _
-               #
-               $text = preg_replace_callback('{
-                       (                               # wrap whole match in $1
-                         !\[
-                               ('.$this->nested_brackets_re.')         # alt text = $2
-                         \]
-                         \s?                   # One optional whitespace character
-                         \(                    # literal paren
-                               [ \n]*
-                               (?:
-                                       <(\S*)> # src url = $3
-                               |
-                                       ('.$this->nested_url_parenthesis_re.')  # src url = $4
-                               )
-                               [ \n]*
-                               (                       # $5
-                                 ([\'"])       # quote char = $6
-                                 (.*?)         # title = $7
-                                 \6            # matching quote
-                                 [ \n]*
-                               )?                      # title is optional
-                         \)
-                         (?:[ ]? '.$this->id_class_attr_catch_re.' )?   # $8 = id/class attributes
-                       )
-                       }xs',
-                       array($this, '_doImages_inline_callback'), $text);
-
-               return $text;
-       }
-       protected function _doImages_reference_callback($matches) {
-               $whole_match = $matches[1];
-               $alt_text    = $matches[2];
-               $link_id     = strtolower($matches[3]);
-
-               if ($link_id == "") {
-                       $link_id = strtolower($alt_text); # for shortcut links like ![this][].
-               }
-
-               $alt_text = $this->encodeAttribute($alt_text);
-               if (isset($this->urls[$link_id])) {
-                       $url = $this->encodeURLAttribute($this->urls[$link_id]);
-                       $result = "<img src=\"$url\" alt=\"$alt_text\"";
-                       if (isset($this->titles[$link_id])) {
-                               $title = $this->titles[$link_id];
-                               $title = $this->encodeAttribute($title);
-                               $result .=  " title=\"$title\"";
-                       }
-                       if (isset($this->ref_attr[$link_id]))
-                               $result .= $this->ref_attr[$link_id];
-                       $result .= $this->empty_element_suffix;
-                       $result = $this->hashPart($result);
-               }
-               else {
-                       # If there's no such link ID, leave intact:
-                       $result = $whole_match;
-               }
-
-               return $result;
-       }
-       protected function _doImages_inline_callback($matches) {
-               $whole_match    = $matches[1];
-               $alt_text               = $matches[2];
-               $url                    = $matches[3] == '' ? $matches[4] : $matches[3];
-               $title                  =& $matches[7];
-               $attr  = $this->doExtraAttributes("img", $dummy =& $matches[8]);
-
-               $alt_text = $this->encodeAttribute($alt_text);
-               $url = $this->encodeURLAttribute($url);
-               $result = "<img src=\"$url\" alt=\"$alt_text\"";
-               if (isset($title)) {
-                       $title = $this->encodeAttribute($title);
-                       $result .=  " title=\"$title\""; # $title already quoted
-               }
-               $result .= $attr;
-               $result .= $this->empty_element_suffix;
-
-               return $this->hashPart($result);
-       }
-
-
-       protected function doHeaders($text) {
-       #
-       # Redefined to add id and class attribute support.
-       #
-               # Setext-style headers:
-               #         Header 1  {#header1}
-               #         ========
-               #  
-               #         Header 2  {#header2 .class1 .class2}
-               #         --------
-               #
-               $text = preg_replace_callback(
-                       '{
-                               (^.+?)                                                          # $1: Header text
-                               (?:[ ]+ '.$this->id_class_attr_catch_re.' )?     # $3 = id/class attributes
-                               [ ]*\n(=+|-+)[ ]*\n+                            # $3: Header footer
-                       }mx',
-                       array($this, '_doHeaders_callback_setext'), $text);
-
-               # atx-style headers:
-               #       # Header 1        {#header1}
-               #       ## Header 2       {#header2}
-               #       ## Header 2 with closing hashes ##  {#header3.class1.class2}
-               #       ...
-               #       ###### Header 6   {.class2}
-               #
-               $text = preg_replace_callback('{
-                               ^(\#{1,6})      # $1 = string of #\'s
-                               [ ]*
-                               (.+?)           # $2 = Header text
-                               [ ]*
-                               \#*                     # optional closing #\'s (not counted)
-                               (?:[ ]+ '.$this->id_class_attr_catch_re.' )?     # $3 = id/class attributes
-                               [ ]*
-                               \n+
-                       }xm',
-                       array($this, '_doHeaders_callback_atx'), $text);
-
-               return $text;
-       }
-       protected function _doHeaders_callback_setext($matches) {
-               if ($matches[3] == '-' && preg_match('{^- }', $matches[1]))
-                       return $matches[0];
-               $level = $matches[3]{0} == '=' ? 1 : 2;
-               $attr  = $this->doExtraAttributes("h$level", $dummy =& $matches[2]);
-               $block = "<h$level$attr>".$this->runSpanGamut($matches[1])."</h$level>";
-               return "\n" . $this->hashBlock($block) . "\n\n";
-       }
-       protected function _doHeaders_callback_atx($matches) {
-               $level = strlen($matches[1]);
-               $attr  = $this->doExtraAttributes("h$level", $dummy =& $matches[3]);
-               $block = "<h$level$attr>".$this->runSpanGamut($matches[2])."</h$level>";
-               return "\n" . $this->hashBlock($block) . "\n\n";
-       }
-
-
-       protected function doTables($text) {
-       #
-       # Form HTML tables.
-       #
-               $less_than_tab = $this->tab_width - 1;
-               #
-               # Find tables with leading pipe.
-               #
-               #       | Header 1 | Header 2
-               #       | -------- | --------
-               #       | Cell 1   | Cell 2
-               #       | Cell 3   | Cell 4
-               #
-               $text = preg_replace_callback('
-                       {
-                               ^                                                       # Start of a line
-                               [ ]{0,'.$less_than_tab.'}       # Allowed whitespace.
-                               [|]                                                     # Optional leading pipe (present)
-                               (.+) \n                                         # $1: Header row (at least one pipe)
-                               
-                               [ ]{0,'.$less_than_tab.'}       # Allowed whitespace.
-                               [|] ([ ]*[-:]+[-| :]*) \n       # $2: Header underline
-                               
-                               (                                                       # $3: Cells
-                                       (?>
-                                               [ ]*                            # Allowed whitespace.
-                                               [|] .* \n                       # Row content.
-                                       )*
-                               )
-                               (?=\n|\Z)                                       # Stop at final double newline.
-                       }xm',
-                       array($this, '_doTable_leadingPipe_callback'), $text);
-               
-               #
-               # Find tables without leading pipe.
-               #
-               #       Header 1 | Header 2
-               #       -------- | --------
-               #       Cell 1   | Cell 2
-               #       Cell 3   | Cell 4
-               #
-               $text = preg_replace_callback('
-                       {
-                               ^                                                       # Start of a line
-                               [ ]{0,'.$less_than_tab.'}       # Allowed whitespace.
-                               (\S.*[|].*) \n                          # $1: Header row (at least one pipe)
-                               
-                               [ ]{0,'.$less_than_tab.'}       # Allowed whitespace.
-                               ([-:]+[ ]*[|][-| :]*) \n        # $2: Header underline
-                               
-                               (                                                       # $3: Cells
-                                       (?>
-                                               .* [|] .* \n            # Row content
-                                       )*
-                               )
-                               (?=\n|\Z)                                       # Stop at final double newline.
-                       }xm',
-                       array($this, '_DoTable_callback'), $text);
-
-               return $text;
-       }
-       protected function _doTable_leadingPipe_callback($matches) {
-               $head           = $matches[1];
-               $underline      = $matches[2];
-               $content        = $matches[3];
-               
-               # Remove leading pipe for each row.
-               $content        = preg_replace('/^ *[|]/m', '', $content);
-               
-               return $this->_doTable_callback(array($matches[0], $head, $underline, $content));
-       }
-       protected function _doTable_makeAlignAttr($alignname)
-       {
-               if (empty($this->table_align_class_tmpl))
-                       return " align=\"$alignname\"";
-
-               $classname = str_replace('%%', $alignname, $this->table_align_class_tmpl);
-               return " class=\"$classname\"";
-       }
-       protected function _doTable_callback($matches) {
-               $head           = $matches[1];
-               $underline      = $matches[2];
-               $content        = $matches[3];
-
-               # Remove any tailing pipes for each line.
-               $head           = preg_replace('/[|] *$/m', '', $head);
-               $underline      = preg_replace('/[|] *$/m', '', $underline);
-               $content        = preg_replace('/[|] *$/m', '', $content);
-               
-               # Reading alignement from header underline.
-               $separators     = preg_split('/ *[|] */', $underline);
-               foreach ($separators as $n => $s) {
-                       if (preg_match('/^ *-+: *$/', $s))
-                               $attr[$n] = $this->_doTable_makeAlignAttr('right');
-                       else if (preg_match('/^ *:-+: *$/', $s))
-                               $attr[$n] = $this->_doTable_makeAlignAttr('center');
-                       else if (preg_match('/^ *:-+ *$/', $s))
-                               $attr[$n] = $this->_doTable_makeAlignAttr('left');
-                       else
-                               $attr[$n] = '';
-               }
-               
-               # Parsing span elements, including code spans, character escapes, 
-               # and inline HTML tags, so that pipes inside those gets ignored.
-               $head           = $this->parseSpan($head);
-               $headers        = preg_split('/ *[|] */', $head);
-               $col_count      = count($headers);
-               $attr       = array_pad($attr, $col_count, '');
-               
-               # Write column headers.
-               $text = "<table>\n";
-               $text .= "<thead>\n";
-               $text .= "<tr>\n";
-               foreach ($headers as $n => $header)
-                       $text .= "  <th$attr[$n]>".$this->runSpanGamut(trim($header))."</th>\n";
-               $text .= "</tr>\n";
-               $text .= "</thead>\n";
-               
-               # Split content by row.
-               $rows = explode("\n", trim($content, "\n"));
-               
-               $text .= "<tbody>\n";
-               foreach ($rows as $row) {
-                       # Parsing span elements, including code spans, character escapes, 
-                       # and inline HTML tags, so that pipes inside those gets ignored.
-                       $row = $this->parseSpan($row);
-                       
-                       # Split row by cell.
-                       $row_cells = preg_split('/ *[|] */', $row, $col_count);
-                       $row_cells = array_pad($row_cells, $col_count, '');
-                       
-                       $text .= "<tr>\n";
-                       foreach ($row_cells as $n => $cell)
-                               $text .= "  <td$attr[$n]>".$this->runSpanGamut(trim($cell))."</td>\n";
-                       $text .= "</tr>\n";
-               }
-               $text .= "</tbody>\n";
-               $text .= "</table>";
-               
-               return $this->hashBlock($text) . "\n";
-       }
-
-       
-       protected function doDefLists($text) {
-       #
-       # Form HTML definition lists.
-       #
-               $less_than_tab = $this->tab_width - 1;
-
-               # Re-usable pattern to match any entire dl list:
-               $whole_list_re = '(?>
-                       (                                                               # $1 = whole list
-                         (                                                             # $2
-                               [ ]{0,'.$less_than_tab.'}
-                               ((?>.*\S.*\n)+)                         # $3 = defined term
-                               \n?
-                               [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
-                         )
-                         (?s:.+?)
-                         (                                                             # $4
-                                 \z
-                               |
-                                 \n{2,}
-                                 (?=\S)
-                                 (?!                                           # Negative lookahead for another term
-                                       [ ]{0,'.$less_than_tab.'}
-                                       (?: \S.*\n )+?                  # defined term
-                                       \n?
-                                       [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
-                                 )
-                                 (?!                                           # Negative lookahead for another definition
-                                       [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
-                                 )
-                         )
-                       )
-               )'; // mx
-
-               $text = preg_replace_callback('{
-                               (?>\A\n?|(?<=\n\n))
-                               '.$whole_list_re.'
-                       }mx',
-                       array($this, '_doDefLists_callback'), $text);
-
-               return $text;
-       }
-       protected function _doDefLists_callback($matches) {
-               # Re-usable patterns to match list item bullets and number markers:
-               $list = $matches[1];
-               
-               # Turn double returns into triple returns, so that we can make a
-               # paragraph for the last item in a list, if necessary:
-               $result = trim($this->processDefListItems($list));
-               $result = "<dl>\n" . $result . "\n</dl>";
-               return $this->hashBlock($result) . "\n\n";
-       }
-
-
-       protected function processDefListItems($list_str) {
-       #
-       #       Process the contents of a single definition list, splitting it
-       #       into individual term and definition list items.
-       #
-               $less_than_tab = $this->tab_width - 1;
-               
-               # trim trailing blank lines:
-               $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
-
-               # Process definition terms.
-               $list_str = preg_replace_callback('{
-                       (?>\A\n?|\n\n+)                                 # leading line
-                       (                                                               # definition terms = $1
-                               [ ]{0,'.$less_than_tab.'}       # leading whitespace
-                               (?!\:[ ]|[ ])                           # negative lookahead for a definition
-                                                                                       #   mark (colon) or more whitespace.
-                               (?> \S.* \n)+?                          # actual term (not whitespace). 
-                       )                       
-                       (?=\n?[ ]{0,3}:[ ])                             # lookahead for following line feed 
-                                                                                       #   with a definition mark.
-                       }xm',
-                       array($this, '_processDefListItems_callback_dt'), $list_str);
-
-               # Process actual definitions.
-               $list_str = preg_replace_callback('{
-                       \n(\n+)?                                                # leading line = $1
-                       (                                                               # marker space = $2
-                               [ ]{0,'.$less_than_tab.'}       # whitespace before colon
-                               \:[ ]+                                          # definition mark (colon)
-                       )
-                       ((?s:.+?))                                              # definition text = $3
-                       (?= \n+                                                 # stop at next definition mark,
-                               (?:                                                     # next term or end of text
-                                       [ ]{0,'.$less_than_tab.'} \:[ ] |
-                                       <dt> | \z
-                               )                                               
-                       )                                       
-                       }xm',
-                       array($this, '_processDefListItems_callback_dd'), $list_str);
-
-               return $list_str;
-       }
-       protected function _processDefListItems_callback_dt($matches) {
-               $terms = explode("\n", trim($matches[1]));
-               $text = '';
-               foreach ($terms as $term) {
-                       $term = $this->runSpanGamut(trim($term));
-                       $text .= "\n<dt>" . $term . "</dt>";
-               }
-               return $text . "\n";
-       }
-       protected function _processDefListItems_callback_dd($matches) {
-               $leading_line   = $matches[1];
-               $marker_space   = $matches[2];
-               $def                    = $matches[3];
-
-               if ($leading_line || preg_match('/\n{2,}/', $def)) {
-                       # Replace marker with the appropriate whitespace indentation
-                       $def = str_repeat(' ', strlen($marker_space)) . $def;
-                       $def = $this->runBlockGamut($this->outdent($def . "\n\n"));
-                       $def = "\n". $def ."\n";
-               }
-               else {
-                       $def = rtrim($def);
-                       $def = $this->runSpanGamut($this->outdent($def));
-               }
-
-               return "\n<dd>" . $def . "</dd>\n";
-       }
-
-
-       protected function doFencedCodeBlocks($text) {
-       #
-       # Adding the fenced code block syntax to regular Markdown:
-       #
-       # ~~~
-       # Code block
-       # ~~~
-       #
-               $less_than_tab = $this->tab_width;
-               
-               $text = preg_replace_callback('{
-                               (?:\n|\A)
-                               # 1: Opening marker
-                               (
-                                       (?:~{3,}|`{3,}) # 3 or more tildes/backticks.
-                               )
-                               [ ]*
-                               (?:
-                                       \.?([-_:a-zA-Z0-9]+) # 2: standalone class name
-                               |
-                                       '.$this->id_class_attr_catch_re.' # 3: Extra attributes
-                               )?
-                               [ ]* \n # Whitespace and newline following marker.
-                               
-                               # 4: Content
-                               (
-                                       (?>
-                                               (?!\1 [ ]* \n)  # Not a closing marker.
-                                               .*\n+
-                                       )+
-                               )
-                               
-                               # Closing marker.
-                               \1 [ ]* (?= \n )
-                       }xm',
-                       array($this, '_doFencedCodeBlocks_callback'), $text);
-
-               return $text;
-       }
-       protected function _doFencedCodeBlocks_callback($matches) {
-               $classname =& $matches[2];
-               $attrs     =& $matches[3];
-               $codeblock = $matches[4];
-               $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
-               $codeblock = preg_replace_callback('/^\n+/',
-                       array($this, '_doFencedCodeBlocks_newlines'), $codeblock);
-
-               if ($classname != "") {
-                       if ($classname{0} == '.')
-                               $classname = substr($classname, 1);
-                       $attr_str = ' class="'.$this->code_class_prefix.$classname.'"';
-               } else {
-                       $attr_str = $this->doExtraAttributes($this->code_attr_on_pre ? "pre" : "code", $attrs);
-               }
-               $pre_attr_str  = $this->code_attr_on_pre ? $attr_str : '';
-               $code_attr_str = $this->code_attr_on_pre ? '' : $attr_str;
-               $codeblock  = "<pre$pre_attr_str><code$code_attr_str>$codeblock</code></pre>";
-               
-               return "\n\n".$this->hashBlock($codeblock)."\n\n";
-       }
-       protected function _doFencedCodeBlocks_newlines($matches) {
-               return str_repeat("<br$this->empty_element_suffix", 
-                       strlen($matches[0]));
-       }
-
-
-       #
-       # Redefining emphasis markers so that emphasis by underscore does not
-       # work in the middle of a word.
-       #
-       protected $em_relist = array(
-               ''  => '(?:(?<!\*)\*(?!\*)|(?<![a-zA-Z0-9_])_(?!_))(?![\.,:;]?\s)',
-               '*' => '(?<![\s*])\*(?!\*)',
-               '_' => '(?<![\s_])_(?![a-zA-Z0-9_])',
-               );
-       protected $strong_relist = array(
-               ''   => '(?:(?<!\*)\*\*(?!\*)|(?<![a-zA-Z0-9_])__(?!_))(?![\.,:;]?\s)',
-               '**' => '(?<![\s*])\*\*(?!\*)',
-               '__' => '(?<![\s_])__(?![a-zA-Z0-9_])',
-               );
-       protected $em_strong_relist = array(
-               ''    => '(?:(?<!\*)\*\*\*(?!\*)|(?<![a-zA-Z0-9_])___(?!_))(?![\.,:;]?\s)',
-               '***' => '(?<![\s*])\*\*\*(?!\*)',
-               '___' => '(?<![\s_])___(?![a-zA-Z0-9_])',
-               );
-
-
-       protected function formParagraphs($text) {
-       #
-       #       Params:
-       #               $text - string to process with html <p> tags
-       #
-               # Strip leading and trailing lines:
-               $text = preg_replace('/\A\n+|\n+\z/', '', $text);
-               
-               $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
-
-               #
-               # Wrap <p> tags and unhashify HTML blocks
-               #
-               foreach ($grafs as $key => $value) {
-                       $value = trim($this->runSpanGamut($value));
-                       
-                       # Check if this should be enclosed in a paragraph.
-                       # Clean tag hashes & block tag hashes are left alone.
-                       $is_p = !preg_match('/^B\x1A[0-9]+B|^C\x1A[0-9]+C$/', $value);
-                       
-                       if ($is_p) {
-                               $value = "<p>$value</p>";
-                       }
-                       $grafs[$key] = $value;
-               }
-               
-               # Join grafs in one text, then unhash HTML tags. 
-               $text = implode("\n\n", $grafs);
-               
-               # Finish by removing any tag hashes still present in $text.
-               $text = $this->unhash($text);
-               
-               return $text;
-       }
-       
-       
-       ### Footnotes
-       
-       protected function stripFootnotes($text) {
-       #
-       # Strips link definitions from text, stores the URLs and titles in
-       # hash references.
-       #
-               $less_than_tab = $this->tab_width - 1;
-
-               # Link defs are in the form: [^id]: url "optional title"
-               $text = preg_replace_callback('{
-                       ^[ ]{0,'.$less_than_tab.'}\[\^(.+?)\][ ]?:      # note_id = $1
-                         [ ]*
-                         \n?                                   # maybe *one* newline
-                       (                                               # text = $2 (no blank lines allowed)
-                               (?:                                     
-                                       .+                              # actual text
-                               |
-                                       \n                              # newlines but 
-                                       (?!\[.+?\][ ]?:\s)# negative lookahead for footnote or link definition marker.
-                                       (?!\n+[ ]{0,3}\S)# ensure line is not blank and followed 
-                                                                       # by non-indented content
-                               )*
-                       )               
-                       }xm',
-                       array($this, '_stripFootnotes_callback'),
-                       $text);
-               return $text;
-       }
-       protected function _stripFootnotes_callback($matches) {
-               $note_id = $this->fn_id_prefix . $matches[1];
-               $this->footnotes[$note_id] = $this->outdent($matches[2]);
-               return ''; # String that will replace the block
-       }
-
-
-       protected function doFootnotes($text) {
-       #
-       # Replace footnote references in $text [^id] with a special text-token 
-       # which will be replaced by the actual footnote marker in appendFootnotes.
-       #
-               if (!$this->in_anchor) {
-                       $text = preg_replace('{\[\^(.+?)\]}', "F\x1Afn:\\1\x1A:", $text);
-               }
-               return $text;
-       }
-
-       
-       protected function appendFootnotes($text) {
-       #
-       # Append footnote list to text.
-       #
-               $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', 
-                       array($this, '_appendFootnotes_callback'), $text);
-       
-               if (!empty($this->footnotes_ordered)) {
-                       $text .= "\n\n";
-                       $text .= "<div class=\"footnotes\">\n";
-                       $text .= "<hr". $this->empty_element_suffix ."\n";
-                       $text .= "<ol>\n\n";
-
-                       $attr = "";
-                       if ($this->fn_backlink_class != "") {
-                               $class = $this->fn_backlink_class;
-                               $class = $this->encodeAttribute($class);
-                               $attr .= " class=\"$class\"";
-                       }
-                       if ($this->fn_backlink_title != "") {
-                               $title = $this->fn_backlink_title;
-                               $title = $this->encodeAttribute($title);
-                               $attr .= " title=\"$title\"";
-                       }
-                       $num = 0;
-                       
-                       while (!empty($this->footnotes_ordered)) {
-                               $footnote = reset($this->footnotes_ordered);
-                               $note_id = key($this->footnotes_ordered);
-                               unset($this->footnotes_ordered[$note_id]);
-                               $ref_count = $this->footnotes_ref_count[$note_id];
-                               unset($this->footnotes_ref_count[$note_id]);
-                               unset($this->footnotes[$note_id]);
-                               
-                               $footnote .= "\n"; # Need to append newline before parsing.
-                               $footnote = $this->runBlockGamut("$footnote\n");                                
-                               $footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', 
-                                       array($this, '_appendFootnotes_callback'), $footnote);
-                               
-                               $attr = str_replace("%%", ++$num, $attr);
-                               $note_id = $this->encodeAttribute($note_id);
-
-                               # Prepare backlink, multiple backlinks if multiple references
-                               $backlink = "<a href=\"#fnref:$note_id\"$attr>&#8617;</a>";
-                               for ($ref_num = 2; $ref_num <= $ref_count; ++$ref_num) {
-                                       $backlink .= " <a href=\"#fnref$ref_num:$note_id\"$attr>&#8617;</a>";
-                               }
-                               # Add backlink to last paragraph; create new paragraph if needed.
-                               if (preg_match('{</p>$}', $footnote)) {
-                                       $footnote = substr($footnote, 0, -4) . "&#160;$backlink</p>";
-                               } else {
-                                       $footnote .= "\n\n<p>$backlink</p>";
-                               }
-                               
-                               $text .= "<li id=\"fn:$note_id\">\n";
-                               $text .= $footnote . "\n";
-                               $text .= "</li>\n\n";
-                       }
-                       
-                       $text .= "</ol>\n";
-                       $text .= "</div>";
-               }
-               return $text;
-       }
-       protected function _appendFootnotes_callback($matches) {
-               $node_id = $this->fn_id_prefix . $matches[1];
-               
-               # Create footnote marker only if it has a corresponding footnote *and*
-               # the footnote hasn't been used by another marker.
-               if (isset($this->footnotes[$node_id])) {
-                       $num =& $this->footnotes_numbers[$node_id];
-                       if (!isset($num)) {
-                               # Transfer footnote content to the ordered list and give it its
-                               # number
-                               $this->footnotes_ordered[$node_id] = $this->footnotes[$node_id];
-                               $this->footnotes_ref_count[$node_id] = 1;
-                               $num = $this->footnote_counter++;
-                               $ref_count_mark = '';
-                       } else {
-                               $ref_count_mark = $this->footnotes_ref_count[$node_id] += 1;
-                       }
-
-                       $attr = "";
-                       if ($this->fn_link_class != "") {
-                               $class = $this->fn_link_class;
-                               $class = $this->encodeAttribute($class);
-                               $attr .= " class=\"$class\"";
-                       }
-                       if ($this->fn_link_title != "") {
-                               $title = $this->fn_link_title;
-                               $title = $this->encodeAttribute($title);
-                               $attr .= " title=\"$title\"";
-                       }
-                       
-                       $attr = str_replace("%%", $num, $attr);
-                       $node_id = $this->encodeAttribute($node_id);
-                       
-                       return
-                               "<sup id=\"fnref$ref_count_mark:$node_id\">".
-                               "<a href=\"#fn:$node_id\"$attr>$num</a>".
-                               "</sup>";
-               }
-               
-               return "[^".$matches[1]."]";
-       }
-               
-       
-       ### Abbreviations ###
-       
-       protected function stripAbbreviations($text) {
-       #
-       # Strips abbreviations from text, stores titles in hash references.
-       #
-               $less_than_tab = $this->tab_width - 1;
-
-               # Link defs are in the form: [id]*: url "optional title"
-               $text = preg_replace_callback('{
-                       ^[ ]{0,'.$less_than_tab.'}\*\[(.+?)\][ ]?:      # abbr_id = $1
-                       (.*)                                    # text = $2 (no blank lines allowed)    
-                       }xm',
-                       array($this, '_stripAbbreviations_callback'),
-                       $text);
-               return $text;
-       }
-       protected function _stripAbbreviations_callback($matches) {
-               $abbr_word = $matches[1];
-               $abbr_desc = $matches[2];
-               if ($this->abbr_word_re)
-                       $this->abbr_word_re .= '|';
-               $this->abbr_word_re .= preg_quote($abbr_word);
-               $this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
-               return ''; # String that will replace the block
-       }
-       
-       
-       protected function doAbbreviations($text) {
-       #
-       # Find defined abbreviations in text and wrap them in <abbr> elements.
-       #
-               if ($this->abbr_word_re) {
-                       // cannot use the /x modifier because abbr_word_re may 
-                       // contain significant spaces:
-                       $text = preg_replace_callback('{'.
-                               '(?<![\w\x1A])'.
-                               '(?:'.$this->abbr_word_re.')'.
-                               '(?![\w\x1A])'.
-                               '}', 
-                               array($this, '_doAbbreviations_callback'), $text);
-               }
-               return $text;
-       }
-       protected function _doAbbreviations_callback($matches) {
-               $abbr = $matches[0];
-               if (isset($this->abbr_desciptions[$abbr])) {
-                       $desc = $this->abbr_desciptions[$abbr];
-                       if (empty($desc)) {
-                               return $this->hashPart("<abbr>$abbr</abbr>");
-                       } else {
-                               $desc = $this->encodeAttribute($desc);
-                               return $this->hashPart("<abbr title=\"$desc\">$abbr</abbr>");
-                       }
-               } else {
-                       return $matches[0];
-               }
-       }
-
 }
index e11b1ef9713d86335b0c8266b666126d8fb61a4c..d09bd7a4801cae3eb8e544eb421b8231d4b31e4d 100644 (file)
@@ -1,10 +1,10 @@
 <?php
 
-# Use this file if you cannot use class autoloading. It will include all the
-# files needed for the MarkdownExtra parser.
-#
-# Take a look at the PSR-0-compatible class autoloading implementation
-# in the Readme.php file if you want a simple autoloader setup.
+// Use this file if you cannot use class autoloading. It will include all the
+// files needed for the MarkdownExtra parser.
+//
+// Take a look at the PSR-0-compatible class autoloading implementation
+// in the Readme.php file if you want a simple autoloader setup.
 
 require_once dirname(__FILE__) . '/MarkdownInterface.php';
 require_once dirname(__FILE__) . '/Markdown.php';
index 89822e4c20cc5d97a5aa5b0276ac0a3203dc8448..c406e8e43a4ef8e0a3e19adf82c58778113e6594 100644 (file)
 <?php
-#
-# Markdown Extra  -  A text-to-HTML conversion tool for web writers
-#
-# PHP Markdown Extra
-# Copyright (c) 2004-2014 Michel Fortin  
-# <http://michelf.com/projects/php-markdown/>
-#
-# Original Markdown
-# Copyright (c) 2004-2006 John Gruber  
-# <http://daringfireball.net/projects/markdown/>
-#
+/**
+ * Markdown Extra - A text-to-HTML conversion tool for web writers
+ *
+ * @package   php-markdown
+ * @author    Michel Fortin <michel.fortin@michelf.com>
+ * @copyright 2004-2016 Michel Fortin <https://michelf.com/projects/php-markdown/>
+ * @copyright (Original Markdown) 2004-2006 John Gruber <https://daringfireball.net/projects/markdown/>
+ */
+
 namespace Michelf;
 
+/**
+ * Markdown Extra Parser Class
+ */
+class MarkdownExtra extends \Michelf\Markdown {
+       /**
+        * Configuration variables
+        */
 
-# Just force Michelf/Markdown.php to load. This is needed to load
-# the temporary implementation class. See below for details.
-\Michelf\Markdown::MARKDOWNLIB_VERSION;
+       /**
+        * Prefix for footnote ids.
+        * @var string
+        */
+       public $fn_id_prefix = "";
+       
+       /**
+        * Optional title attribute for footnote links and backlinks.
+        * @var string
+        */
+       public $fn_link_title     = "";
+       public $fn_backlink_title = "";
+       
+       /**
+        * Optional class attribute for footnote links and backlinks.
+        * @var string
+        */
+       public $fn_link_class     = "footnote-ref";
+       public $fn_backlink_class = "footnote-backref";
 
-#
-# Markdown Extra Parser Class
-#
-# Note: Currently the implementation resides in the temporary class
-# \Michelf\MarkdownExtra_TmpImpl (in the same file as \Michelf\Markdown).
-# This makes it easier to propagate the changes between the three different
-# packaging styles of PHP Markdown. Once this issue is resolved, the
-# _MarkdownExtra_TmpImpl will disappear and this one will contain the code.
-#
+       /**
+        * Content to be displayed within footnote backlinks. The default is '↩';
+        * the U+FE0E on the end is a Unicode variant selector used to prevent iOS
+        * from displaying the arrow character as an emoji.
+        * @var string
+        */
+       public $fn_backlink_html = '&#8617;&#xFE0E;';
 
-class MarkdownExtra extends \Michelf\_MarkdownExtra_TmpImpl {
+       /**
+        * Class name for table cell alignment (%% replaced left/center/right)
+        * For instance: 'go-%%' becomes 'go-left' or 'go-right' or 'go-center'
+        * If empty, the align attribute is used instead of a class name.
+        * @var string
+        */
+       public $table_align_class_tmpl = '';
 
-       ### Parser Implementation ###
+       /**
+        * Optional class prefix for fenced code block.
+        * @var string
+        */
+       public $code_class_prefix = "";
 
-       # Temporarily, the implemenation is in the _MarkdownExtra_TmpImpl class.
-       # See note above.
+       /**
+        * Class attribute for code blocks goes on the `code` tag;
+        * setting this to true will put attributes on the `pre` tag instead.
+        * @var boolean
+        */
+       public $code_attr_on_pre = false;
 
-}
+       /**
+        * Predefined abbreviations.
+        * @var array
+        */
+       public $predef_abbr = array();
+
+       /**
+        * Parser implementation
+        */
+       
+       /**
+        * Constructor function. Initialize the parser object.
+        * @return void
+        */
+       public function __construct() {
+               // Add extra escapable characters before parent constructor 
+               // initialize the table.
+               $this->escape_chars .= ':|';
+               
+               // Insert extra document, block, and span transformations. 
+               // Parent constructor will do the sorting.
+               $this->document_gamut += array(
+                       "doFencedCodeBlocks" => 5,
+                       "stripFootnotes"     => 15,
+                       "stripAbbreviations" => 25,
+                       "appendFootnotes"    => 50,
+               );
+               $this->block_gamut += array(
+                       "doFencedCodeBlocks" => 5,
+                       "doTables"           => 15,
+                       "doDefLists"         => 45,
+               );
+               $this->span_gamut += array(
+                       "doFootnotes"        => 5,
+                       "doAbbreviations"    => 70,
+               );
+               
+               $this->enhanced_ordered_list = true;
+               parent::__construct();
+       }
+       
+       
+       /**
+        * Extra variables used during extra transformations.
+        * @var array
+        */
+       protected $footnotes = array();
+       protected $footnotes_ordered = array();
+       protected $footnotes_ref_count = array();
+       protected $footnotes_numbers = array();
+       protected $abbr_desciptions = array();
+       /** @var string */
+       protected $abbr_word_re = '';
+       
+       /**
+        * Give the current footnote number.
+        * @var integer
+        */
+       protected $footnote_counter = 1;
+       
+       /**
+        * Setting up Extra-specific variables.
+        */
+       protected function setup() {
+               parent::setup();
+               
+               $this->footnotes = array();
+               $this->footnotes_ordered = array();
+               $this->footnotes_ref_count = array();
+               $this->footnotes_numbers = array();
+               $this->abbr_desciptions = array();
+               $this->abbr_word_re = '';
+               $this->footnote_counter = 1;
+               
+               foreach ($this->predef_abbr as $abbr_word => $abbr_desc) {
+                       if ($this->abbr_word_re)
+                               $this->abbr_word_re .= '|';
+                       $this->abbr_word_re .= preg_quote($abbr_word);
+                       $this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
+               }
+       }
+
+       /**
+        * Clearing Extra-specific variables.
+        */
+       protected function teardown() {
+               $this->footnotes = array();
+               $this->footnotes_ordered = array();
+               $this->footnotes_ref_count = array();
+               $this->footnotes_numbers = array();
+               $this->abbr_desciptions = array();
+               $this->abbr_word_re = '';
+               
+               parent::teardown();
+       }
+       
+       
+       /**
+        * Extra attribute parser
+        */
+
+       /**
+        * Expression to use to catch attributes (includes the braces)
+        * @var string
+        */
+       protected $id_class_attr_catch_re = '\{((?>[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,})[ ]*\}';
+
+       /**
+        * Expression to use when parsing in a context when no capture is desired
+        * @var string
+        */
+       protected $id_class_attr_nocatch_re = '\{(?>[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,}[ ]*\}';
+
+       /**
+        * Parse attributes caught by the $this->id_class_attr_catch_re expression
+        * and return the HTML-formatted list of attributes.
+        *
+        * Currently supported attributes are .class and #id.
+        *
+        * In addition, this method also supports supplying a default Id value,
+        * which will be used to populate the id attribute in case it was not
+        * overridden.
+        * @param  string $tag_name
+        * @param  string $attr
+        * @param  mixed  $defaultIdValue
+        * @param  array  $classes
+        * @return string
+        */
+       protected function doExtraAttributes($tag_name, $attr, $defaultIdValue = null, $classes = array()) {
+               if (empty($attr) && !$defaultIdValue && empty($classes)) return "";
+               
+               // Split on components
+               preg_match_all('/[#.a-z][-_:a-zA-Z0-9=]+/', $attr, $matches);
+               $elements = $matches[0];
+
+               // Handle classes and IDs (only first ID taken into account)
+               $attributes = array();
+               $id = false;
+               foreach ($elements as $element) {
+                       if ($element{0} == '.') {
+                               $classes[] = substr($element, 1);
+                       } else if ($element{0} == '#') {
+                               if ($id === false) $id = substr($element, 1);
+                       } else if (strpos($element, '=') > 0) {
+                               $parts = explode('=', $element, 2);
+                               $attributes[] = $parts[0] . '="' . $parts[1] . '"';
+                       }
+               }
+
+               if (!$id) $id = $defaultIdValue;
+
+               // Compose attributes as string
+               $attr_str = "";
+               if (!empty($id)) {
+                       $attr_str .= ' id="'.$this->encodeAttribute($id) .'"';
+               }
+               if (!empty($classes)) {
+                       $attr_str .= ' class="'. implode(" ", $classes) . '"';
+               }
+               if (!$this->no_markup && !empty($attributes)) {
+                       $attr_str .= ' '.implode(" ", $attributes);
+               }
+               return $attr_str;
+       }
+
+       /**
+        * Strips link definitions from text, stores the URLs and titles in
+        * hash references.
+        * @param  string $text
+        * @return string
+        */
+       protected function stripLinkDefinitions($text) {
+               $less_than_tab = $this->tab_width - 1;
+
+               // Link defs are in the form: ^[id]: url "optional title"
+               $text = preg_replace_callback('{
+                                                       ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1
+                                                         [ ]*
+                                                         \n?                           # maybe *one* newline
+                                                         [ ]*
+                                                       (?:
+                                                         <(.+?)>                       # url = $2
+                                                       |
+                                                         (\S+?)                        # url = $3
+                                                       )
+                                                         [ ]*
+                                                         \n?                           # maybe one newline
+                                                         [ ]*
+                                                       (?:
+                                                               (?<=\s)                 # lookbehind for whitespace
+                                                               ["(]
+                                                               (.*?)                   # title = $4
+                                                               [")]
+                                                               [ ]*
+                                                       )?      # title is optional
+                                       (?:[ ]* '.$this->id_class_attr_catch_re.' )?  # $5 = extra id & class attr
+                                                       (?:\n+|\Z)
+                       }xm',
+                       array($this, '_stripLinkDefinitions_callback'),
+                       $text);
+               return $text;
+       }
+
+       /**
+        * Strip link definition callback
+        * @param  array $matches
+        * @return string
+        */
+       protected function _stripLinkDefinitions_callback($matches) {
+               $link_id = strtolower($matches[1]);
+               $url = $matches[2] == '' ? $matches[3] : $matches[2];
+               $this->urls[$link_id] = $url;
+               $this->titles[$link_id] =& $matches[4];
+               $this->ref_attr[$link_id] = $this->doExtraAttributes("", $dummy =& $matches[5]);
+               return ''; // String that will replace the block
+       }
+
+
+       /**
+        * HTML block parser
+        */
+       
+       /**
+        * Tags that are always treated as block tags
+        * @var string
+        */
+       protected $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend|article|section|nav|aside|hgroup|header|footer|figcaption|figure';
+                                                  
+       /**
+        * Tags treated as block tags only if the opening tag is alone on its line
+        * @var string
+        */
+       protected $context_block_tags_re = 'script|noscript|style|ins|del|iframe|object|source|track|param|math|svg|canvas|audio|video';
+       
+       /**
+        * Tags where markdown="1" default to span mode:
+        * @var string
+        */
+       protected $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address';
+       
+       /**
+        * Tags which must not have their contents modified, no matter where
+        * they appear
+        * @var string
+        */
+       protected $clean_tags_re = 'script|style|math|svg';
+       
+       /**
+        * Tags that do not need to be closed.
+        * @var string
+        */
+       protected $auto_close_tags_re = 'hr|img|param|source|track';
+       
+       /**
+        * Hashify HTML Blocks and "clean tags".
+        *
+        * We only want to do this for block-level HTML tags, such as headers,
+        * lists, and tables. That's because we still want to wrap <p>s around
+        * "paragraphs" that are wrapped in non-block-level tags, such as anchors,
+        * phrase emphasis, and spans. The list of tags we're looking for is
+        * hard-coded.
+        *
+        * This works by calling _HashHTMLBlocks_InMarkdown, which then calls
+        * _HashHTMLBlocks_InHTML when it encounter block tags. When the markdown="1" 
+        * attribute is found within a tag, _HashHTMLBlocks_InHTML calls back
+        *  _HashHTMLBlocks_InMarkdown to handle the Markdown syntax within the tag.
+        * These two functions are calling each other. It's recursive!
+        * @param  string $text
+        * @return string
+        */
+       protected function hashHTMLBlocks($text) {
+               if ($this->no_markup) {
+                       return $text;
+               }
+
+               // Call the HTML-in-Markdown hasher.
+               list($text, ) = $this->_hashHTMLBlocks_inMarkdown($text);
+               
+               return $text;
+       }
+
+       /**
+        * Parse markdown text, calling _HashHTMLBlocks_InHTML for block tags.
+        *
+        * *   $indent is the number of space to be ignored when checking for code 
+        *     blocks. This is important because if we don't take the indent into 
+        *     account, something like this (which looks right) won't work as expected:
+        *
+        *     <div>
+        *         <div markdown="1">
+        *         Hello World.  <-- Is this a Markdown code block or text?
+        *         </div>  <-- Is this a Markdown code block or a real tag?
+        *     <div>
+        *
+        *     If you don't like this, just don't indent the tag on which
+        *     you apply the markdown="1" attribute.
+        *
+        * *   If $enclosing_tag_re is not empty, stops at the first unmatched closing 
+        *     tag with that name. Nested tags supported.
+        *
+        * *   If $span is true, text inside must treated as span. So any double 
+        *     newline will be replaced by a single newline so that it does not create 
+        *     paragraphs.
+        *
+        * Returns an array of that form: ( processed text , remaining text )
+        *
+        * @param  string  $text
+        * @param  integer $indent
+        * @param  string  $enclosing_tag_re
+        * @param  boolean $span
+        * @return array
+        */
+       protected function _hashHTMLBlocks_inMarkdown($text, $indent = 0,
+                                                                               $enclosing_tag_re = '', $span = false)
+       {
+       
+               if ($text === '') return array('', '');
+
+               // Regex to check for the presense of newlines around a block tag.
+               $newline_before_re = '/(?:^\n?|\n\n)*$/';
+               $newline_after_re = 
+                       '{
+                               ^                                               # Start of text following the tag.
+                               (?>[ ]*<!--.*?-->)?             # Optional comment.
+                               [ ]*\n                                  # Must be followed by newline.
+                       }xs';
+               
+               // Regex to match any tag.
+               $block_tag_re =
+                       '{
+                               (                                       # $2: Capture whole tag.
+                                       </?                                     # Any opening or closing tag.
+                                               (?>                             # Tag name.
+                                                       ' . $this->block_tags_re . '                    |
+                                                       ' . $this->context_block_tags_re . '    |
+                                                       ' . $this->clean_tags_re . '            |
+                                                       (?!\s)'.$enclosing_tag_re . '
+                                               )
+                                               (?:
+                                                       (?=[\s"\'/a-zA-Z0-9])   # Allowed characters after tag name.
+                                                       (?>
+                                                               ".*?"           |       # Double quotes (can contain `>`)
+                                                               \'.*?\'         |       # Single quotes (can contain `>`)
+                                                               .+?                             # Anything but quotes and `>`.
+                                                       )*?
+                                               )?
+                                       >                                       # End of tag.
+                               |
+                                       <!--    .*?     -->     # HTML Comment
+                               |
+                                       <\?.*?\?> | <%.*?%>     # Processing instruction
+                               |
+                                       <!\[CDATA\[.*?\]\]>     # CData Block
+                               ' . ( !$span ? ' # If not in span.
+                               |
+                                       # Indented code block
+                                       (?: ^[ ]*\n | ^ | \n[ ]*\n )
+                                       [ ]{' . ($indent + 4) . '}[^\n]* \n
+                                       (?>
+                                               (?: [ ]{' . ($indent + 4) . '}[^\n]* | [ ]* ) \n
+                                       )*
+                               |
+                                       # Fenced code block marker
+                                       (?<= ^ | \n )
+                                       [ ]{0,' . ($indent + 3) . '}(?:~{3,}|`{3,})
+                                       [ ]*
+                                       (?: \.?[-_:a-zA-Z0-9]+ )? # standalone class name
+                                       [ ]*
+                                       (?: ' . $this->id_class_attr_nocatch_re . ' )? # extra attributes
+                                       [ ]*
+                                       (?= \n )
+                               ' : '' ) . ' # End (if not is span).
+                               |
+                                       # Code span marker
+                                       # Note, this regex needs to go after backtick fenced
+                                       # code blocks but it should also be kept outside of the
+                                       # "if not in span" condition adding backticks to the parser
+                                       `+
+                               )
+                       }xs';
+
+               
+               $depth = 0;             // Current depth inside the tag tree.
+               $parsed = "";   // Parsed text that will be returned.
+
+               // Loop through every tag until we find the closing tag of the parent
+               // or loop until reaching the end of text if no parent tag specified.
+               do {
+                       // Split the text using the first $tag_match pattern found.
+                       // Text before  pattern will be first in the array, text after
+                       // pattern will be at the end, and between will be any catches made 
+                       // by the pattern.
+                       $parts = preg_split($block_tag_re, $text, 2, 
+                                                               PREG_SPLIT_DELIM_CAPTURE);
+                       
+                       // If in Markdown span mode, add a empty-string span-level hash 
+                       // after each newline to prevent triggering any block element.
+                       if ($span) {
+                               $void = $this->hashPart("", ':');
+                               $newline = "\n$void";
+                               $parts[0] = $void . str_replace("\n", $newline, $parts[0]) . $void;
+                       }
+                       
+                       $parsed .= $parts[0]; // Text before current tag.
+                       
+                       // If end of $text has been reached. Stop loop.
+                       if (count($parts) < 3) {
+                               $text = "";
+                               break;
+                       }
+                       
+                       $tag  = $parts[1]; // Tag to handle.
+                       $text = $parts[2]; // Remaining text after current tag.
+                       $tag_re = preg_quote($tag); // For use in a regular expression.
+                       
+                       // Check for: Fenced code block marker.
+                       // Note: need to recheck the whole tag to disambiguate backtick
+                       // fences from code spans
+                       if (preg_match('{^\n?([ ]{0,' . ($indent + 3) . '})(~{3,}|`{3,})[ ]*(?:\.?[-_:a-zA-Z0-9]+)?[ ]*(?:' . $this->id_class_attr_nocatch_re . ')?[ ]*\n?$}', $tag, $capture)) {
+                               // Fenced code block marker: find matching end marker.
+                               $fence_indent = strlen($capture[1]); // use captured indent in re
+                               $fence_re = $capture[2]; // use captured fence in re
+                               if (preg_match('{^(?>.*\n)*?[ ]{' . ($fence_indent) . '}' . $fence_re . '[ ]*(?:\n|$)}', $text,
+                                       $matches)) 
+                               {
+                                       // End marker found: pass text unchanged until marker.
+                                       $parsed .= $tag . $matches[0];
+                                       $text = substr($text, strlen($matches[0]));
+                               }
+                               else {
+                                       // No end marker: just skip it.
+                                       $parsed .= $tag;
+                               }
+                       }
+                       // Check for: Indented code block.
+                       else if ($tag{0} == "\n" || $tag{0} == " ") {
+                               // Indented code block: pass it unchanged, will be handled 
+                               // later.
+                               $parsed .= $tag;
+                       }
+                       // Check for: Code span marker
+                       // Note: need to check this after backtick fenced code blocks
+                       else if ($tag{0} == "`") {
+                               // Find corresponding end marker.
+                               $tag_re = preg_quote($tag);
+                               if (preg_match('{^(?>.+?|\n(?!\n))*?(?<!`)' . $tag_re . '(?!`)}',
+                                       $text, $matches))
+                               {
+                                       // End marker found: pass text unchanged until marker.
+                                       $parsed .= $tag . $matches[0];
+                                       $text = substr($text, strlen($matches[0]));
+                               }
+                               else {
+                                       // Unmatched marker: just skip it.
+                                       $parsed .= $tag;
+                               }
+                       }
+                       // Check for: Opening Block level tag or
+                       //            Opening Context Block tag (like ins and del) 
+                       //               used as a block tag (tag is alone on it's line).
+                       else if (preg_match('{^<(?:' . $this->block_tags_re . ')\b}', $tag) ||
+                               (       preg_match('{^<(?:' . $this->context_block_tags_re . ')\b}', $tag) &&
+                                       preg_match($newline_before_re, $parsed) &&
+                                       preg_match($newline_after_re, $text)    )
+                               )
+                       {
+                               // Need to parse tag and following text using the HTML parser.
+                               list($block_text, $text) = 
+                                       $this->_hashHTMLBlocks_inHTML($tag . $text, "hashBlock", true);
+                               
+                               // Make sure it stays outside of any paragraph by adding newlines.
+                               $parsed .= "\n\n$block_text\n\n";
+                       }
+                       // Check for: Clean tag (like script, math)
+                       //            HTML Comments, processing instructions.
+                       else if (preg_match('{^<(?:' . $this->clean_tags_re . ')\b}', $tag) ||
+                               $tag{1} == '!' || $tag{1} == '?')
+                       {
+                               // Need to parse tag and following text using the HTML parser.
+                               // (don't check for markdown attribute)
+                               list($block_text, $text) = 
+                                       $this->_hashHTMLBlocks_inHTML($tag . $text, "hashClean", false);
+                               
+                               $parsed .= $block_text;
+                       }
+                       // Check for: Tag with same name as enclosing tag.
+                       else if ($enclosing_tag_re !== '' &&
+                               // Same name as enclosing tag.
+                               preg_match('{^</?(?:' . $enclosing_tag_re . ')\b}', $tag))
+                       {
+                               // Increase/decrease nested tag count.
+                               if ($tag{1} == '/')                                             $depth--;
+                               else if ($tag{strlen($tag)-2} != '/')   $depth++;
+
+                               if ($depth < 0) {
+                                       // Going out of parent element. Clean up and break so we
+                                       // return to the calling function.
+                                       $text = $tag . $text;
+                                       break;
+                               }
+                               
+                               $parsed .= $tag;
+                       }
+                       else {
+                               $parsed .= $tag;
+                       }
+               } while ($depth >= 0);
+               
+               return array($parsed, $text);
+       }
+
+       /**
+        * Parse HTML, calling _HashHTMLBlocks_InMarkdown for block tags.
+        *
+        * *   Calls $hash_method to convert any blocks.
+        * *   Stops when the first opening tag closes.
+        * *   $md_attr indicate if the use of the `markdown="1"` attribute is allowed.
+        *     (it is not inside clean tags)
+        *
+        * Returns an array of that form: ( processed text , remaining text )
+        * @param  string $text
+        * @param  string $hash_method
+        * @param  string $md_attr
+        * @return array
+        */
+       protected function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) {
+               if ($text === '') return array('', '');
+               
+               // Regex to match `markdown` attribute inside of a tag.
+               $markdown_attr_re = '
+                       {
+                               \s*                     # Eat whitespace before the `markdown` attribute
+                               markdown
+                               \s*=\s*
+                               (?>
+                                       (["\'])         # $1: quote delimiter           
+                                       (.*?)           # $2: attribute value
+                                       \1                      # matching delimiter    
+                               |
+                                       ([^\s>]*)       # $3: unquoted attribute value
+                               )
+                               ()                              # $4: make $3 always defined (avoid warnings)
+                       }xs';
+               
+               // Regex to match any tag.
+               $tag_re = '{
+                               (                                       # $2: Capture whole tag.
+                                       </?                                     # Any opening or closing tag.
+                                               [\w:$]+                 # Tag name.
+                                               (?:
+                                                       (?=[\s"\'/a-zA-Z0-9])   # Allowed characters after tag name.
+                                                       (?>
+                                                               ".*?"           |       # Double quotes (can contain `>`)
+                                                               \'.*?\'         |       # Single quotes (can contain `>`)
+                                                               .+?                             # Anything but quotes and `>`.
+                                                       )*?
+                                               )?
+                                       >                                       # End of tag.
+                               |
+                                       <!--    .*?     -->     # HTML Comment
+                               |
+                                       <\?.*?\?> | <%.*?%>     # Processing instruction
+                               |
+                                       <!\[CDATA\[.*?\]\]>     # CData Block
+                               )
+                       }xs';
+               
+               $original_text = $text;         // Save original text in case of faliure.
+               
+               $depth          = 0;    // Current depth inside the tag tree.
+               $block_text     = "";   // Temporary text holder for current text.
+               $parsed         = "";   // Parsed text that will be returned.
+
+               // Get the name of the starting tag.
+               // (This pattern makes $base_tag_name_re safe without quoting.)
+               if (preg_match('/^<([\w:$]*)\b/', $text, $matches))
+                       $base_tag_name_re = $matches[1];
+
+               // Loop through every tag until we find the corresponding closing tag.
+               do {
+                       // Split the text using the first $tag_match pattern found.
+                       // Text before  pattern will be first in the array, text after
+                       // pattern will be at the end, and between will be any catches made 
+                       // by the pattern.
+                       $parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
+                       
+                       if (count($parts) < 3) {
+                               // End of $text reached with unbalenced tag(s).
+                               // In that case, we return original text unchanged and pass the
+                               // first character as filtered to prevent an infinite loop in the 
+                               // parent function.
+                               return array($original_text{0}, substr($original_text, 1));
+                       }
+                       
+                       $block_text .= $parts[0]; // Text before current tag.
+                       $tag         = $parts[1]; // Tag to handle.
+                       $text        = $parts[2]; // Remaining text after current tag.
+                       
+                       // Check for: Auto-close tag (like <hr/>)
+                       //                       Comments and Processing Instructions.
+                       if (preg_match('{^</?(?:' . $this->auto_close_tags_re . ')\b}', $tag) ||
+                               $tag{1} == '!' || $tag{1} == '?')
+                       {
+                               // Just add the tag to the block as if it was text.
+                               $block_text .= $tag;
+                       }
+                       else {
+                               // Increase/decrease nested tag count. Only do so if
+                               // the tag's name match base tag's.
+                               if (preg_match('{^</?' . $base_tag_name_re . '\b}', $tag)) {
+                                       if ($tag{1} == '/')                                             $depth--;
+                                       else if ($tag{strlen($tag)-2} != '/')   $depth++;
+                               }
+                               
+                               // Check for `markdown="1"` attribute and handle it.
+                               if ($md_attr && 
+                                       preg_match($markdown_attr_re, $tag, $attr_m) &&
+                                       preg_match('/^1|block|span$/', $attr_m[2] . $attr_m[3]))
+                               {
+                                       // Remove `markdown` attribute from opening tag.
+                                       $tag = preg_replace($markdown_attr_re, '', $tag);
+                                       
+                                       // Check if text inside this tag must be parsed in span mode.
+                                       $this->mode = $attr_m[2] . $attr_m[3];
+                                       $span_mode = $this->mode == 'span' || $this->mode != 'block' &&
+                                               preg_match('{^<(?:' . $this->contain_span_tags_re . ')\b}', $tag);
+                                       
+                                       // Calculate indent before tag.
+                                       if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) {
+                                               $strlen = $this->utf8_strlen;
+                                               $indent = $strlen($matches[1], 'UTF-8');
+                                       } else {
+                                               $indent = 0;
+                                       }
+                                       
+                                       // End preceding block with this tag.
+                                       $block_text .= $tag;
+                                       $parsed .= $this->$hash_method($block_text);
+                                       
+                                       // Get enclosing tag name for the ParseMarkdown function.
+                                       // (This pattern makes $tag_name_re safe without quoting.)
+                                       preg_match('/^<([\w:$]*)\b/', $tag, $matches);
+                                       $tag_name_re = $matches[1];
+                                       
+                                       // Parse the content using the HTML-in-Markdown parser.
+                                       list ($block_text, $text)
+                                               = $this->_hashHTMLBlocks_inMarkdown($text, $indent, 
+                                                       $tag_name_re, $span_mode);
+                                       
+                                       // Outdent markdown text.
+                                       if ($indent > 0) {
+                                               $block_text = preg_replace("/^[ ]{1,$indent}/m", "", 
+                                                                                                       $block_text);
+                                       }
+                                       
+                                       // Append tag content to parsed text.
+                                       if (!$span_mode)        $parsed .= "\n\n$block_text\n\n";
+                                       else                            $parsed .= "$block_text";
+                                       
+                                       // Start over with a new block.
+                                       $block_text = "";
+                               }
+                               else $block_text .= $tag;
+                       }
+                       
+               } while ($depth > 0);
+               
+               // Hash last block text that wasn't processed inside the loop.
+               $parsed .= $this->$hash_method($block_text);
+               
+               return array($parsed, $text);
+       }
+
+       /**
+        * Called whenever a tag must be hashed when a function inserts a "clean" tag
+        * in $text, it passes through this function and is automaticaly escaped, 
+        * blocking invalid nested overlap.
+        * @param  string $text
+        * @return string
+        */
+       protected function hashClean($text) {
+               return $this->hashPart($text, 'C');
+       }
+
+       /**
+        * Turn Markdown link shortcuts into XHTML <a> tags.
+        * @param  string $text
+        * @return string
+        */
+       protected function doAnchors($text) {
+               if ($this->in_anchor) {
+                       return $text;
+               }
+               $this->in_anchor = true;
+
+               // First, handle reference-style links: [link text] [id]
+               $text = preg_replace_callback('{
+                       (                                       # wrap whole match in $1
+                         \[
+                               (' . $this->nested_brackets_re . ')     # link text = $2
+                         \]
+
+                         [ ]?                          # one optional space
+                         (?:\n[ ]*)?           # one optional newline followed by spaces
+
+                         \[
+                               (.*?)           # id = $3
+                         \]
+                       )
+                       }xs',
+                       array($this, '_doAnchors_reference_callback'), $text);
+
+               // Next, inline-style links: [link text](url "optional title")
+               $text = preg_replace_callback('{
+                       (                               # wrap whole match in $1
+                         \[
+                               (' . $this->nested_brackets_re . ')     # link text = $2
+                         \]
+                         \(                    # literal paren
+                               [ \n]*
+                               (?:
+                                       <(.+?)> # href = $3
+                               |
+                                       (' . $this->nested_url_parenthesis_re . ')      # href = $4
+                               )
+                               [ \n]*
+                               (                       # $5
+                                 ([\'"])       # quote char = $6
+                                 (.*?)         # Title = $7
+                                 \6            # matching quote
+                                 [ \n]*        # ignore any spaces/tabs between closing quote and )
+                               )?                      # title is optional
+                         \)
+                         (?:[ ]? ' . $this->id_class_attr_catch_re . ' )?       # $8 = id/class attributes
+                       )
+                       }xs',
+                       array($this, '_doAnchors_inline_callback'), $text);
+
+               // Last, handle reference-style shortcuts: [link text]
+               // These must come last in case you've also got [link text][1]
+               // or [link text](/foo)
+               $text = preg_replace_callback('{
+                       (                                       # wrap whole match in $1
+                         \[
+                               ([^\[\]]+)              # link text = $2; can\'t contain [ or ]
+                         \]
+                       )
+                       }xs',
+                       array($this, '_doAnchors_reference_callback'), $text);
+
+               $this->in_anchor = false;
+               return $text;
+       }
+
+       /**
+        * Callback for reference anchors
+        * @param  array $matches
+        * @return string
+        */
+       protected function _doAnchors_reference_callback($matches) {
+               $whole_match =  $matches[1];
+               $link_text   =  $matches[2];
+               $link_id     =& $matches[3];
+
+               if ($link_id == "") {
+                       // for shortcut links like [this][] or [this].
+                       $link_id = $link_text;
+               }
+               
+               // lower-case and turn embedded newlines into spaces
+               $link_id = strtolower($link_id);
+               $link_id = preg_replace('{[ ]?\n}', ' ', $link_id);
+
+               if (isset($this->urls[$link_id])) {
+                       $url = $this->urls[$link_id];
+                       $url = $this->encodeURLAttribute($url);
+                       
+                       $result = "<a href=\"$url\"";
+                       if ( isset( $this->titles[$link_id] ) ) {
+                               $title = $this->titles[$link_id];
+                               $title = $this->encodeAttribute($title);
+                               $result .=  " title=\"$title\"";
+                       }
+                       if (isset($this->ref_attr[$link_id]))
+                               $result .= $this->ref_attr[$link_id];
+               
+                       $link_text = $this->runSpanGamut($link_text);
+                       $result .= ">$link_text</a>";
+                       $result = $this->hashPart($result);
+               }
+               else {
+                       $result = $whole_match;
+               }
+               return $result;
+       }
+
+       /**
+        * Callback for inline anchors
+        * @param  array $matches
+        * @return string
+        */
+       protected function _doAnchors_inline_callback($matches) {
+               $whole_match    =  $matches[1];
+               $link_text              =  $this->runSpanGamut($matches[2]);
+               $url                    =  $matches[3] == '' ? $matches[4] : $matches[3];
+               $title                  =& $matches[7];
+               $attr  = $this->doExtraAttributes("a", $dummy =& $matches[8]);
+
+               // if the URL was of the form <s p a c e s> it got caught by the HTML
+               // tag parser and hashed. Need to reverse the process before using the URL.
+               $unhashed = $this->unhash($url);
+               if ($unhashed != $url)
+                       $url = preg_replace('/^<(.*)>$/', '\1', $unhashed);
+
+               $url = $this->encodeURLAttribute($url);
+
+               $result = "<a href=\"$url\"";
+               if (isset($title)) {
+                       $title = $this->encodeAttribute($title);
+                       $result .=  " title=\"$title\"";
+               }
+               $result .= $attr;
+               
+               $link_text = $this->runSpanGamut($link_text);
+               $result .= ">$link_text</a>";
+
+               return $this->hashPart($result);
+       }
+
+       /**
+        * Turn Markdown image shortcuts into <img> tags.
+        * @param  string $text
+        * @return string
+        */
+       protected function doImages($text) {
+               // First, handle reference-style labeled images: ![alt text][id]
+               $text = preg_replace_callback('{
+                       (                               # wrap whole match in $1
+                         !\[
+                               (' . $this->nested_brackets_re . ')             # alt text = $2
+                         \]
+
+                         [ ]?                          # one optional space
+                         (?:\n[ ]*)?           # one optional newline followed by spaces
+
+                         \[
+                               (.*?)           # id = $3
+                         \]
+
+                       )
+                       }xs', 
+                       array($this, '_doImages_reference_callback'), $text);
+
+               // Next, handle inline images:  ![alt text](url "optional title")
+               // Don't forget: encode * and _
+               $text = preg_replace_callback('{
+                       (                               # wrap whole match in $1
+                         !\[
+                               (' . $this->nested_brackets_re . ')             # alt text = $2
+                         \]
+                         \s?                   # One optional whitespace character
+                         \(                    # literal paren
+                               [ \n]*
+                               (?:
+                                       <(\S*)> # src url = $3
+                               |
+                                       (' . $this->nested_url_parenthesis_re . ')      # src url = $4
+                               )
+                               [ \n]*
+                               (                       # $5
+                                 ([\'"])       # quote char = $6
+                                 (.*?)         # title = $7
+                                 \6            # matching quote
+                                 [ \n]*
+                               )?                      # title is optional
+                         \)
+                         (?:[ ]? ' . $this->id_class_attr_catch_re . ' )?       # $8 = id/class attributes
+                       )
+                       }xs',
+                       array($this, '_doImages_inline_callback'), $text);
+
+               return $text;
+       }
+
+       /**
+        * Callback for referenced images
+        * @param  array $matches
+        * @return string
+        */
+       protected function _doImages_reference_callback($matches) {
+               $whole_match = $matches[1];
+               $alt_text    = $matches[2];
+               $link_id     = strtolower($matches[3]);
+
+               if ($link_id == "") {
+                       $link_id = strtolower($alt_text); // for shortcut links like ![this][].
+               }
+
+               $alt_text = $this->encodeAttribute($alt_text);
+               if (isset($this->urls[$link_id])) {
+                       $url = $this->encodeURLAttribute($this->urls[$link_id]);
+                       $result = "<img src=\"$url\" alt=\"$alt_text\"";
+                       if (isset($this->titles[$link_id])) {
+                               $title = $this->titles[$link_id];
+                               $title = $this->encodeAttribute($title);
+                               $result .=  " title=\"$title\"";
+                       }
+                       if (isset($this->ref_attr[$link_id]))
+                               $result .= $this->ref_attr[$link_id];
+                       $result .= $this->empty_element_suffix;
+                       $result = $this->hashPart($result);
+               }
+               else {
+                       // If there's no such link ID, leave intact:
+                       $result = $whole_match;
+               }
+
+               return $result;
+       }
+
+       /**
+        * Callback for inline images
+        * @param  array $matches
+        * @return string
+        */
+       protected function _doImages_inline_callback($matches) {
+               $whole_match    = $matches[1];
+               $alt_text               = $matches[2];
+               $url                    = $matches[3] == '' ? $matches[4] : $matches[3];
+               $title                  =& $matches[7];
+               $attr  = $this->doExtraAttributes("img", $dummy =& $matches[8]);
+
+               $alt_text = $this->encodeAttribute($alt_text);
+               $url = $this->encodeURLAttribute($url);
+               $result = "<img src=\"$url\" alt=\"$alt_text\"";
+               if (isset($title)) {
+                       $title = $this->encodeAttribute($title);
+                       $result .=  " title=\"$title\""; // $title already quoted
+               }
+               $result .= $attr;
+               $result .= $this->empty_element_suffix;
+
+               return $this->hashPart($result);
+       }
+
+       /**
+        * Process markdown headers. Redefined to add ID and class attribute support.
+        * @param  string $text
+        * @return string
+        */
+       protected function doHeaders($text) {
+               // Setext-style headers:
+               //  Header 1  {#header1}
+               //        ========
+               //  
+               //        Header 2  {#header2 .class1 .class2}
+               //        --------
+               //
+               $text = preg_replace_callback(
+                       '{
+                               (^.+?)                                                          # $1: Header text
+                               (?:[ ]+ ' . $this->id_class_attr_catch_re . ' )?         # $3 = id/class attributes
+                               [ ]*\n(=+|-+)[ ]*\n+                            # $3: Header footer
+                       }mx',
+                       array($this, '_doHeaders_callback_setext'), $text);
 
+               // atx-style headers:
+               //      # Header 1        {#header1}
+               //      ## Header 2       {#header2}
+               //      ## Header 2 with closing hashes ##  {#header3.class1.class2}
+               //      ...
+               //      ###### Header 6   {.class2}
+               //
+               $text = preg_replace_callback('{
+                               ^(\#{1,6})      # $1 = string of #\'s
+                               [ ]*
+                               (.+?)           # $2 = Header text
+                               [ ]*
+                               \#*                     # optional closing #\'s (not counted)
+                               (?:[ ]+ ' . $this->id_class_attr_catch_re . ' )?         # $3 = id/class attributes
+                               [ ]*
+                               \n+
+                       }xm',
+                       array($this, '_doHeaders_callback_atx'), $text);
+
+               return $text;
+       }
+
+       /**
+        * Callback for setext headers
+        * @param  array $matches
+        * @return string
+        */
+       protected function _doHeaders_callback_setext($matches) {
+               if ($matches[3] == '-' && preg_match('{^- }', $matches[1])) {
+                       return $matches[0];
+               }
+
+               $level = $matches[3]{0} == '=' ? 1 : 2;
+
+               $defaultId = is_callable($this->header_id_func) ? call_user_func($this->header_id_func, $matches[1]) : null;
+
+               $attr  = $this->doExtraAttributes("h$level", $dummy =& $matches[2], $defaultId);
+               $block = "<h$level$attr>" . $this->runSpanGamut($matches[1]) . "</h$level>";
+               return "\n" . $this->hashBlock($block) . "\n\n";
+       }
+
+       /**
+        * Callback for atx headers
+        * @param  array $matches
+        * @return string
+        */
+       protected function _doHeaders_callback_atx($matches) {
+               $level = strlen($matches[1]);
+
+               $defaultId = is_callable($this->header_id_func) ? call_user_func($this->header_id_func, $matches[2]) : null;
+               $attr  = $this->doExtraAttributes("h$level", $dummy =& $matches[3], $defaultId);
+               $block = "<h$level$attr>" . $this->runSpanGamut($matches[2]) . "</h$level>";
+               return "\n" . $this->hashBlock($block) . "\n\n";
+       }
+
+       /**
+        * Form HTML tables.
+        * @param  string $text
+        * @return string
+        */
+       protected function doTables($text) {
+               $less_than_tab = $this->tab_width - 1;
+               // Find tables with leading pipe.
+               //
+               //      | Header 1 | Header 2
+               //      | -------- | --------
+               //      | Cell 1   | Cell 2
+               //      | Cell 3   | Cell 4
+               $text = preg_replace_callback('
+                       {
+                               ^                                                       # Start of a line
+                               [ ]{0,' . $less_than_tab . '}   # Allowed whitespace.
+                               [|]                                                     # Optional leading pipe (present)
+                               (.+) \n                                         # $1: Header row (at least one pipe)
+                               
+                               [ ]{0,' . $less_than_tab . '}   # Allowed whitespace.
+                               [|] ([ ]*[-:]+[-| :]*) \n       # $2: Header underline
+                               
+                               (                                                       # $3: Cells
+                                       (?>
+                                               [ ]*                            # Allowed whitespace.
+                                               [|] .* \n                       # Row content.
+                                       )*
+                               )
+                               (?=\n|\Z)                                       # Stop at final double newline.
+                       }xm',
+                       array($this, '_doTable_leadingPipe_callback'), $text);
+
+               // Find tables without leading pipe.
+               //
+               //      Header 1 | Header 2
+               //      -------- | --------
+               //      Cell 1   | Cell 2
+               //      Cell 3   | Cell 4
+               $text = preg_replace_callback('
+                       {
+                               ^                                                       # Start of a line
+                               [ ]{0,' . $less_than_tab . '}   # Allowed whitespace.
+                               (\S.*[|].*) \n                          # $1: Header row (at least one pipe)
+                               
+                               [ ]{0,' . $less_than_tab . '}   # Allowed whitespace.
+                               ([-:]+[ ]*[|][-| :]*) \n        # $2: Header underline
+                               
+                               (                                                       # $3: Cells
+                                       (?>
+                                               .* [|] .* \n            # Row content
+                                       )*
+                               )
+                               (?=\n|\Z)                                       # Stop at final double newline.
+                       }xm',
+                       array($this, '_DoTable_callback'), $text);
+
+               return $text;
+       }
+
+       /**
+        * Callback for removing the leading pipe for each row
+        * @param  array $matches
+        * @return string
+        */
+       protected function _doTable_leadingPipe_callback($matches) {
+               $head           = $matches[1];
+               $underline      = $matches[2];
+               $content        = $matches[3];
+
+               $content        = preg_replace('/^ *[|]/m', '', $content);
+               
+               return $this->_doTable_callback(array($matches[0], $head, $underline, $content));
+       }
+
+       /**
+        * Make the align attribute in a table
+        * @param  string $alignname
+        * @return string
+        */
+       protected function _doTable_makeAlignAttr($alignname)
+       {
+               if (empty($this->table_align_class_tmpl)) {
+                       return " align=\"$alignname\"";
+               }
+
+               $classname = str_replace('%%', $alignname, $this->table_align_class_tmpl);
+               return " class=\"$classname\"";
+       }
+
+       /**
+        * Calback for processing tables
+        * @param  array $matches
+        * @return string
+        */
+       protected function _doTable_callback($matches) {
+               $head           = $matches[1];
+               $underline      = $matches[2];
+               $content        = $matches[3];
+
+               // Remove any tailing pipes for each line.
+               $head           = preg_replace('/[|] *$/m', '', $head);
+               $underline      = preg_replace('/[|] *$/m', '', $underline);
+               $content        = preg_replace('/[|] *$/m', '', $content);
+               
+               // Reading alignement from header underline.
+               $separators     = preg_split('/ *[|] */', $underline);
+               foreach ($separators as $n => $s) {
+                       if (preg_match('/^ *-+: *$/', $s))
+                               $attr[$n] = $this->_doTable_makeAlignAttr('right');
+                       else if (preg_match('/^ *:-+: *$/', $s))
+                               $attr[$n] = $this->_doTable_makeAlignAttr('center');
+                       else if (preg_match('/^ *:-+ *$/', $s))
+                               $attr[$n] = $this->_doTable_makeAlignAttr('left');
+                       else
+                               $attr[$n] = '';
+               }
+               
+               // Parsing span elements, including code spans, character escapes, 
+               // and inline HTML tags, so that pipes inside those gets ignored.
+               $head           = $this->parseSpan($head);
+               $headers        = preg_split('/ *[|] */', $head);
+               $col_count      = count($headers);
+               $attr       = array_pad($attr, $col_count, '');
+               
+               // Write column headers.
+               $text = "<table>\n";
+               $text .= "<thead>\n";
+               $text .= "<tr>\n";
+               foreach ($headers as $n => $header)
+                       $text .= "  <th$attr[$n]>" . $this->runSpanGamut(trim($header)) . "</th>\n";
+               $text .= "</tr>\n";
+               $text .= "</thead>\n";
+               
+               // Split content by row.
+               $rows = explode("\n", trim($content, "\n"));
+               
+               $text .= "<tbody>\n";
+               foreach ($rows as $row) {
+                       // Parsing span elements, including code spans, character escapes, 
+                       // and inline HTML tags, so that pipes inside those gets ignored.
+                       $row = $this->parseSpan($row);
+                       
+                       // Split row by cell.
+                       $row_cells = preg_split('/ *[|] */', $row, $col_count);
+                       $row_cells = array_pad($row_cells, $col_count, '');
+                       
+                       $text .= "<tr>\n";
+                       foreach ($row_cells as $n => $cell)
+                               $text .= "  <td$attr[$n]>" . $this->runSpanGamut(trim($cell)) . "</td>\n";
+                       $text .= "</tr>\n";
+               }
+               $text .= "</tbody>\n";
+               $text .= "</table>";
+               
+               return $this->hashBlock($text) . "\n";
+       }
+
+       /**
+        * Form HTML definition lists.
+        * @param  string $text
+        * @return string
+        */
+       protected function doDefLists($text) {
+               $less_than_tab = $this->tab_width - 1;
+
+               // Re-usable pattern to match any entire dl list:
+               $whole_list_re = '(?>
+                       (                                                               # $1 = whole list
+                         (                                                             # $2
+                               [ ]{0,' . $less_than_tab . '}
+                               ((?>.*\S.*\n)+)                         # $3 = defined term
+                               \n?
+                               [ ]{0,' . $less_than_tab . '}:[ ]+ # colon starting definition
+                         )
+                         (?s:.+?)
+                         (                                                             # $4
+                                 \z
+                               |
+                                 \n{2,}
+                                 (?=\S)
+                                 (?!                                           # Negative lookahead for another term
+                                       [ ]{0,' . $less_than_tab . '}
+                                       (?: \S.*\n )+?                  # defined term
+                                       \n?
+                                       [ ]{0,' . $less_than_tab . '}:[ ]+ # colon starting definition
+                                 )
+                                 (?!                                           # Negative lookahead for another definition
+                                       [ ]{0,' . $less_than_tab . '}:[ ]+ # colon starting definition
+                                 )
+                         )
+                       )
+               )'; // mx
+
+               $text = preg_replace_callback('{
+                               (?>\A\n?|(?<=\n\n))
+                               ' . $whole_list_re . '
+                       }mx',
+                       array($this, '_doDefLists_callback'), $text);
+
+               return $text;
+       }
+
+       /**
+        * Callback for processing definition lists
+        * @param  array $matches
+        * @return string
+        */
+       protected function _doDefLists_callback($matches) {
+               // Re-usable patterns to match list item bullets and number markers:
+               $list = $matches[1];
+               
+               // Turn double returns into triple returns, so that we can make a
+               // paragraph for the last item in a list, if necessary:
+               $result = trim($this->processDefListItems($list));
+               $result = "<dl>\n" . $result . "\n</dl>";
+               return $this->hashBlock($result) . "\n\n";
+       }
+
+       /**
+        * Process the contents of a single definition list, splitting it
+        * into individual term and definition list items.
+        * @param  string $list_str
+        * @return string
+        */
+       protected function processDefListItems($list_str) {
+       
+               $less_than_tab = $this->tab_width - 1;
+               
+               // Trim trailing blank lines:
+               $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
+
+               // Process definition terms.
+               $list_str = preg_replace_callback('{
+                       (?>\A\n?|\n\n+)                                         # leading line
+                       (                                                                       # definition terms = $1
+                               [ ]{0,' . $less_than_tab . '}   # leading whitespace
+                               (?!\:[ ]|[ ])                                   # negative lookahead for a definition
+                                                                                               #   mark (colon) or more whitespace.
+                               (?> \S.* \n)+?                                  # actual term (not whitespace). 
+                       )                       
+                       (?=\n?[ ]{0,3}:[ ])                                     # lookahead for following line feed 
+                                                                                               #   with a definition mark.
+                       }xm',
+                       array($this, '_processDefListItems_callback_dt'), $list_str);
+
+               // Process actual definitions.
+               $list_str = preg_replace_callback('{
+                       \n(\n+)?                                                        # leading line = $1
+                       (                                                                       # marker space = $2
+                               [ ]{0,' . $less_than_tab . '}   # whitespace before colon
+                               \:[ ]+                                                  # definition mark (colon)
+                       )
+                       ((?s:.+?))                                                      # definition text = $3
+                       (?= \n+                                                         # stop at next definition mark,
+                               (?:                                                             # next term or end of text
+                                       [ ]{0,' . $less_than_tab . '} \:[ ]     |
+                                       <dt> | \z
+                               )                                               
+                       )                                       
+                       }xm',
+                       array($this, '_processDefListItems_callback_dd'), $list_str);
+
+               return $list_str;
+       }
+
+       /**
+        * Callback for <dt> elements in definition lists
+        * @param  array $matches
+        * @return string
+        */
+       protected function _processDefListItems_callback_dt($matches) {
+               $terms = explode("\n", trim($matches[1]));
+               $text = '';
+               foreach ($terms as $term) {
+                       $term = $this->runSpanGamut(trim($term));
+                       $text .= "\n<dt>" . $term . "</dt>";
+               }
+               return $text . "\n";
+       }
+
+       /**
+        * Callback for <dd> elements in definition lists
+        * @param  array $matches
+        * @return string
+        */
+       protected function _processDefListItems_callback_dd($matches) {
+               $leading_line   = $matches[1];
+               $marker_space   = $matches[2];
+               $def                    = $matches[3];
+
+               if ($leading_line || preg_match('/\n{2,}/', $def)) {
+                       // Replace marker with the appropriate whitespace indentation
+                       $def = str_repeat(' ', strlen($marker_space)) . $def;
+                       $def = $this->runBlockGamut($this->outdent($def . "\n\n"));
+                       $def = "\n". $def ."\n";
+               }
+               else {
+                       $def = rtrim($def);
+                       $def = $this->runSpanGamut($this->outdent($def));
+               }
+
+               return "\n<dd>" . $def . "</dd>\n";
+       }
+
+       /**
+        * Adding the fenced code block syntax to regular Markdown:
+        *
+        * ~~~
+        * Code block
+        * ~~~
+        * 
+        * @param  string $text
+        * @return string
+        */
+       protected function doFencedCodeBlocks($text) {
+       
+               $less_than_tab = $this->tab_width;
+               
+               $text = preg_replace_callback('{
+                               (?:\n|\A)
+                               # 1: Opening marker
+                               (
+                                       (?:~{3,}|`{3,}) # 3 or more tildes/backticks.
+                               )
+                               [ ]*
+                               (?:
+                                       \.?([-_:a-zA-Z0-9]+) # 2: standalone class name
+                               )?
+                               [ ]*
+                               (?:
+                                       ' . $this->id_class_attr_catch_re . ' # 3: Extra attributes
+                               )?
+                               [ ]* \n # Whitespace and newline following marker.
+                               
+                               # 4: Content
+                               (
+                                       (?>
+                                               (?!\1 [ ]* \n)  # Not a closing marker.
+                                               .*\n+
+                                       )+
+                               )
+                               
+                               # Closing marker.
+                               \1 [ ]* (?= \n )
+                       }xm',
+                       array($this, '_doFencedCodeBlocks_callback'), $text);
+
+               return $text;
+       }
+
+       /**
+        * Callback to process fenced code blocks
+        * @param  array $matches
+        * @return string
+        */
+       protected function _doFencedCodeBlocks_callback($matches) {
+               $classname =& $matches[2];
+               $attrs     =& $matches[3];
+               $codeblock = $matches[4];
+
+               if ($this->code_block_content_func) {
+                       $codeblock = call_user_func($this->code_block_content_func, $codeblock, $classname);
+               } else {
+                       $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
+               }
+
+               $codeblock = preg_replace_callback('/^\n+/',
+                       array($this, '_doFencedCodeBlocks_newlines'), $codeblock);
+
+               $classes = array();
+               if ($classname != "") {
+                       if ($classname{0} == '.')
+                               $classname = substr($classname, 1);
+                       $classes[] = $this->code_class_prefix . $classname;
+               }
+               $attr_str = $this->doExtraAttributes($this->code_attr_on_pre ? "pre" : "code", $attrs, null, $classes);
+               $pre_attr_str  = $this->code_attr_on_pre ? $attr_str : '';
+               $code_attr_str = $this->code_attr_on_pre ? '' : $attr_str;
+               $codeblock  = "<pre$pre_attr_str><code$code_attr_str>$codeblock</code></pre>";
+               
+               return "\n\n".$this->hashBlock($codeblock)."\n\n";
+       }
+
+       /**
+        * Replace new lines in fenced code blocks
+        * @param  array $matches
+        * @return string
+        */
+       protected function _doFencedCodeBlocks_newlines($matches) {
+               return str_repeat("<br$this->empty_element_suffix", 
+                       strlen($matches[0]));
+       }
+
+       /**
+        * Redefining emphasis markers so that emphasis by underscore does not
+        * work in the middle of a word.
+        * @var array
+        */
+       protected $em_relist = array(
+               ''  => '(?:(?<!\*)\*(?!\*)|(?<![a-zA-Z0-9_])_(?!_))(?![\.,:;]?\s)',
+               '*' => '(?<![\s*])\*(?!\*)',
+               '_' => '(?<![\s_])_(?![a-zA-Z0-9_])',
+       );
+       protected $strong_relist = array(
+               ''   => '(?:(?<!\*)\*\*(?!\*)|(?<![a-zA-Z0-9_])__(?!_))(?![\.,:;]?\s)',
+               '**' => '(?<![\s*])\*\*(?!\*)',
+               '__' => '(?<![\s_])__(?![a-zA-Z0-9_])',
+       );
+       protected $em_strong_relist = array(
+               ''    => '(?:(?<!\*)\*\*\*(?!\*)|(?<![a-zA-Z0-9_])___(?!_))(?![\.,:;]?\s)',
+               '***' => '(?<![\s*])\*\*\*(?!\*)',
+               '___' => '(?<![\s_])___(?![a-zA-Z0-9_])',
+       );
+
+       /**
+        * Parse text into paragraphs
+        * @param  string $text String to process in paragraphs
+        * @param  boolean $wrap_in_p Whether paragraphs should be wrapped in <p> tags
+        * @return string       HTML output
+        */
+       protected function formParagraphs($text, $wrap_in_p = true) {
+               // Strip leading and trailing lines:
+               $text = preg_replace('/\A\n+|\n+\z/', '', $text);
+
+               $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
+
+               // Wrap <p> tags and unhashify HTML blocks
+               foreach ($grafs as $key => $value) {
+                       $value = trim($this->runSpanGamut($value));
+                       
+                       // Check if this should be enclosed in a paragraph.
+                       // Clean tag hashes & block tag hashes are left alone.
+                       $is_p = $wrap_in_p && !preg_match('/^B\x1A[0-9]+B|^C\x1A[0-9]+C$/', $value);
+                       
+                       if ($is_p) {
+                               $value = "<p>$value</p>";
+                       }
+                       $grafs[$key] = $value;
+               }
+               
+               // Join grafs in one text, then unhash HTML tags. 
+               $text = implode("\n\n", $grafs);
+               
+               // Finish by removing any tag hashes still present in $text.
+               $text = $this->unhash($text);
+               
+               return $text;
+       }
+       
+       
+       /**
+        * Footnotes - Strips link definitions from text, stores the URLs and
+        * titles in hash references.
+        * @param  string $text
+        * @return string
+        */
+       protected function stripFootnotes($text) {
+               $less_than_tab = $this->tab_width - 1;
+
+               // Link defs are in the form: [^id]: url "optional title"
+               $text = preg_replace_callback('{
+                       ^[ ]{0,' . $less_than_tab . '}\[\^(.+?)\][ ]?:  # note_id = $1
+                         [ ]*
+                         \n?                                   # maybe *one* newline
+                       (                                               # text = $2 (no blank lines allowed)
+                               (?:                                     
+                                       .+                              # actual text
+                               |
+                                       \n                              # newlines but 
+                                       (?!\[.+?\][ ]?:\s)# negative lookahead for footnote or link definition marker.
+                                       (?!\n+[ ]{0,3}\S)# ensure line is not blank and followed 
+                                                                       # by non-indented content
+                               )*
+                       )               
+                       }xm',
+                       array($this, '_stripFootnotes_callback'),
+                       $text);
+               return $text;
+       }
+
+       /**
+        * Callback for stripping footnotes
+        * @param  array $matches
+        * @return string
+        */
+       protected function _stripFootnotes_callback($matches) {
+               $note_id = $this->fn_id_prefix . $matches[1];
+               $this->footnotes[$note_id] = $this->outdent($matches[2]);
+               return ''; // String that will replace the block
+       }
+
+       /**
+        * Replace footnote references in $text [^id] with a special text-token 
+        * which will be replaced by the actual footnote marker in appendFootnotes.
+        * @param  string $text
+        * @return string
+        */
+       protected function doFootnotes($text) {
+               if (!$this->in_anchor) {
+                       $text = preg_replace('{\[\^(.+?)\]}', "F\x1Afn:\\1\x1A:", $text);
+               }
+               return $text;
+       }
+
+       /**
+        * Append footnote list to text
+        * @param  string $text
+        * @return string
+        */
+       protected function appendFootnotes($text) {
+               $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', 
+                       array($this, '_appendFootnotes_callback'), $text);
+       
+               if (!empty($this->footnotes_ordered)) {
+                       $text .= "\n\n";
+                       $text .= "<div class=\"footnotes\">\n";
+                       $text .= "<hr" . $this->empty_element_suffix . "\n";
+                       $text .= "<ol>\n\n";
+
+                       $attr = "";
+                       if ($this->fn_backlink_class != "") {
+                               $class = $this->fn_backlink_class;
+                               $class = $this->encodeAttribute($class);
+                               $attr .= " class=\"$class\"";
+                       }
+                       if ($this->fn_backlink_title != "") {
+                               $title = $this->fn_backlink_title;
+                               $title = $this->encodeAttribute($title);
+                               $attr .= " title=\"$title\"";
+                       }
+                       $backlink_text = $this->fn_backlink_html;
+                       $num = 0;
+                       
+                       while (!empty($this->footnotes_ordered)) {
+                               $footnote = reset($this->footnotes_ordered);
+                               $note_id = key($this->footnotes_ordered);
+                               unset($this->footnotes_ordered[$note_id]);
+                               $ref_count = $this->footnotes_ref_count[$note_id];
+                               unset($this->footnotes_ref_count[$note_id]);
+                               unset($this->footnotes[$note_id]);
+                               
+                               $footnote .= "\n"; // Need to append newline before parsing.
+                               $footnote = $this->runBlockGamut("$footnote\n");                                
+                               $footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', 
+                                       array($this, '_appendFootnotes_callback'), $footnote);
+                               
+                               $attr = str_replace("%%", ++$num, $attr);
+                               $note_id = $this->encodeAttribute($note_id);
+
+                               // Prepare backlink, multiple backlinks if multiple references
+                               $backlink = "<a href=\"#fnref:$note_id\"$attr>$backlink_text</a>";
+                               for ($ref_num = 2; $ref_num <= $ref_count; ++$ref_num) {
+                                       $backlink .= " <a href=\"#fnref$ref_num:$note_id\"$attr>$backlink_text</a>";
+                               }
+                               // Add backlink to last paragraph; create new paragraph if needed.
+                               if (preg_match('{</p>$}', $footnote)) {
+                                       $footnote = substr($footnote, 0, -4) . "&#160;$backlink</p>";
+                               } else {
+                                       $footnote .= "\n\n<p>$backlink</p>";
+                               }
+                               
+                               $text .= "<li id=\"fn:$note_id\">\n";
+                               $text .= $footnote . "\n";
+                               $text .= "</li>\n\n";
+                       }
+                       
+                       $text .= "</ol>\n";
+                       $text .= "</div>";
+               }
+               return $text;
+       }
+
+       /**
+        * Callback for appending footnotes
+        * @param  array $matches
+        * @return string
+        */
+       protected function _appendFootnotes_callback($matches) {
+               $node_id = $this->fn_id_prefix . $matches[1];
+               
+               // Create footnote marker only if it has a corresponding footnote *and*
+               // the footnote hasn't been used by another marker.
+               if (isset($this->footnotes[$node_id])) {
+                       $num =& $this->footnotes_numbers[$node_id];
+                       if (!isset($num)) {
+                               // Transfer footnote content to the ordered list and give it its
+                               // number
+                               $this->footnotes_ordered[$node_id] = $this->footnotes[$node_id];
+                               $this->footnotes_ref_count[$node_id] = 1;
+                               $num = $this->footnote_counter++;
+                               $ref_count_mark = '';
+                       } else {
+                               $ref_count_mark = $this->footnotes_ref_count[$node_id] += 1;
+                       }
+
+                       $attr = "";
+                       if ($this->fn_link_class != "") {
+                               $class = $this->fn_link_class;
+                               $class = $this->encodeAttribute($class);
+                               $attr .= " class=\"$class\"";
+                       }
+                       if ($this->fn_link_title != "") {
+                               $title = $this->fn_link_title;
+                               $title = $this->encodeAttribute($title);
+                               $attr .= " title=\"$title\"";
+                       }
+                       
+                       $attr = str_replace("%%", $num, $attr);
+                       $node_id = $this->encodeAttribute($node_id);
+                       
+                       return
+                               "<sup id=\"fnref$ref_count_mark:$node_id\">".
+                               "<a href=\"#fn:$node_id\"$attr>$num</a>".
+                               "</sup>";
+               }
+               
+               return "[^" . $matches[1] . "]";
+       }
+               
+       
+       /**
+        * Abbreviations - strips abbreviations from text, stores titles in hash
+        * references.
+        * @param  string $text
+        * @return string
+        */
+       protected function stripAbbreviations($text) {
+               $less_than_tab = $this->tab_width - 1;
+
+               // Link defs are in the form: [id]*: url "optional title"
+               $text = preg_replace_callback('{
+                       ^[ ]{0,' . $less_than_tab . '}\*\[(.+?)\][ ]?:  # abbr_id = $1
+                       (.*)                                    # text = $2 (no blank lines allowed)    
+                       }xm',
+                       array($this, '_stripAbbreviations_callback'),
+                       $text);
+               return $text;
+       }
+
+       /**
+        * Callback for stripping abbreviations
+        * @param  array $matches
+        * @return string
+        */
+       protected function _stripAbbreviations_callback($matches) {
+               $abbr_word = $matches[1];
+               $abbr_desc = $matches[2];
+               if ($this->abbr_word_re) {
+                       $this->abbr_word_re .= '|';
+               }
+               $this->abbr_word_re .= preg_quote($abbr_word);
+               $this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
+               return ''; // String that will replace the block
+       }
+
+       /**
+        * Find defined abbreviations in text and wrap them in <abbr> elements.
+        * @param  string $text
+        * @return string
+        */
+       protected function doAbbreviations($text) {
+               if ($this->abbr_word_re) {
+                       // cannot use the /x modifier because abbr_word_re may 
+                       // contain significant spaces:
+                       $text = preg_replace_callback('{' .
+                               '(?<![\w\x1A])' .
+                               '(?:' . $this->abbr_word_re . ')' .
+                               '(?![\w\x1A])' .
+                               '}',
+                               array($this, '_doAbbreviations_callback'), $text);
+               }
+               return $text;
+       }
+
+       /**
+        * Callback for processing abbreviations
+        * @param  array $matches
+        * @return string
+        */
+       protected function _doAbbreviations_callback($matches) {
+               $abbr = $matches[0];
+               if (isset($this->abbr_desciptions[$abbr])) {
+                       $desc = $this->abbr_desciptions[$abbr];
+                       if (empty($desc)) {
+                               return $this->hashPart("<abbr>$abbr</abbr>");
+                       } else {
+                               $desc = $this->encodeAttribute($desc);
+                               return $this->hashPart("<abbr title=\"$desc\">$abbr</abbr>");
+                       }
+               } else {
+                       return $matches[0];
+               }
+       }
+}
index a023ed4e3ae3346b55920c10ffe0d75dea8ad7b4..c4e9ac7f64ca17deaef0c6bc3f682bbae7bc3843 100644 (file)
@@ -1,9 +1,9 @@
 <?php
 
-# Use this file if you cannot use class autoloading. It will include all the
-# files needed for the MarkdownInterface interface.
-#
-# Take a look at the PSR-0-compatible class autoloading implementation
-# in the Readme.php file if you want a simple autoloader setup.
+// Use this file if you cannot use class autoloading. It will include all the
+// files needed for the MarkdownInterface interface.
+//
+// Take a look at the PSR-0-compatible class autoloading implementation
+// in the Readme.php file if you want a simple autoloader setup.
 
 require_once dirname(__FILE__) . '/MarkdownInterface.php';
index e4c2931f32b01a626e7e51275a66a8ee041b0bb1..8512e3753e99768049b1b0cfecb644ab717bbf0b 100644 (file)
@@ -1,34 +1,38 @@
 <?php
-#
-# Markdown  -  A text-to-HTML conversion tool for web writers
-#
-# PHP Markdown
-# Copyright (c) 2004-2014 Michel Fortin
-# <http://michelf.com/projects/php-markdown/>
-#
-# Original Markdown
-# Copyright (c) 2004-2006 John Gruber
-# <http://daringfireball.net/projects/markdown/>
-#
-namespace Michelf;
-
+/**
+ * Markdown  -  A text-to-HTML conversion tool for web writers
+ *
+ * @package   php-markdown
+ * @author    Michel Fortin <michel.fortin@michelf.com>
+ * @copyright 2004-2016 Michel Fortin <https://michelf.com/projects/php-markdown/>
+ * @copyright (Original Markdown) 2004-2006 John Gruber <https://daringfireball.net/projects/markdown/>
+ */
 
-#
-# Markdown Parser Interface
-#
+namespace Michelf;
 
+/**
+ * Markdown Parser Interface 
+ */
 interface MarkdownInterface {
+       /**
+        * Initialize the parser and return the result of its transform method.
+        * This will work fine for derived classes too.
+        *
+        * @api
+        *
+        * @param  string $text
+        * @return string
+        */
+       public static function defaultTransform($text);
 
-  #
-  # Initialize the parser and return the result of its transform method.
-  # This will work fine for derived classes too.
-  #
-  public static function defaultTransform($text);
-
-  #
-  # Main function. Performs some preprocessing on the input text
-  # and pass it through the document gamut.
-  #
-  public function transform($text);
-
+       /**
+        * Main function. Performs some preprocessing on the input text
+        * and pass it through the document gamut.
+        *
+        * @api
+        *
+        * @param  string $text
+        * @return string
+        */
+       public function transform($text);
 }
index 80504c27c2aaa87fac0304de7bbd14504aa5ff14..63e8c1eceb871d34b7ab1d975988369ab21f5634 100644 (file)
@@ -1,13 +1,13 @@
 PHP Markdown
 ============
 
-PHP Markdown Lib 1.4.1 - 4 May 2013
+PHP Markdown Lib 1.7.0 - 29 Oct 2016
 
 by Michel Fortin  
-<http://michelf.ca/>
+<https://michelf.ca/>
 
 based on Markdown by John Gruber  
-<http://daringfireball.net/>
+<https://daringfireball.net/>
 
 
 Introduction
@@ -25,10 +25,10 @@ software tool, originally written in Perl, that converts the plain text
 markup to HTML. PHP Markdown is a port to PHP of the original Markdown 
 program by John Gruber.
 
-*      [Full documentation of the Markdown syntax](<http://daringfireball.net/projects/markdown/>)
-       - Daring Fireball (John Gruber)
-*      [Markdown Extra syntax additions](<http://michelf.ca/projects/php-markdown/extra/>)
-       - Michel Fortin
+*      [Full documentation of the Markdown syntax](<https://daringfireball.net/projects/markdown/>)  
+        Daring Fireball (John Gruber)
+*      [Markdown Extra syntax additions](<https://michelf.ca/projects/php-markdown/extra/>)  
+        Michel Fortin
 
 
 Requirement
@@ -83,7 +83,7 @@ configuration variables:
 
 To learn more, see the full list of [configuration variables].
 
- [configuration variables]: http://michelf.ca/projects/php-markdown/configuration/
+ [configuration variables]: https://michelf.ca/projects/php-markdown/configuration/
 
 
 ### Usage without an autoloader
@@ -149,7 +149,7 @@ Development and Testing
 -----------------------
 
 Pull requests for fixing bugs are welcome. Proposed new features are
-going meticulously reviewed -- taking into account backward compatibility, 
+going to be meticulously reviewed -- taking into account backward compatibility, 
 potential side effects, and future extensibility -- before deciding on
 acceptance or rejection.
 
@@ -174,11 +174,80 @@ PHP Markdown, please visit [michelf.ca/donate] or send Bitcoin to
 Version History
 ---------------
 
-Unreleased
+PHP Markdown Lib 1.7.0 (29 Oct 2016)
 
-*      Added the ability to insert custom HTML attributes everywhere an extra
-       attribute block is allowed (links, images, headers). Credits to
-       Peter Droogmans for providing the implementation.
+*      Added a `hard_wrap` configuration variable to make all newline characters 
+       in the text become `<br>` tags in the HTML output. By default, according 
+       to the standard Markdown syntax these newlines are ignored unless they a 
+       preceded by two spaces. Thanks to Jonathan Cohlmeyer for the implementation.
+
+*      Improved the parsing of list items to fix problematic cases that came to 
+       light with the addition of `hard_wrap`. This should have no effect on the 
+       output except span-level list items that ended with two spaces (and thus 
+       ended with a line break).
+
+*      Added a `code_span_content_func` configuration variable which takes a 
+       function that will convert the content of the code span to HTML. This can
+       be useful to implement syntax highlighting. Although contrary to its 
+       code block equivalent, there is no syntax for specifying a language. 
+       Credits to styxit for the implementation.
+
+*      Fixed a Markdown Extra issue where two-space-at-end-of-line hard breaks 
+       wouldn't work inside of HTML block elements such as `<p markdown="1">` 
+       where the element expects only span-level content.
+
+*      In the parser code, switched to PHPDoc comment format. Thanks to 
+       Robbie Averill for the help.
+
+
+PHP Markdown Lib 1.6.0 (23 Dec 2015)  
+
+Note: this version was incorrectly released as 1.5.1 on Dec 22, a number 
+that contradicted the versioning policy.
+
+*      For fenced code blocks in Markdown Extra, can now set a class name for the 
+       code block's language before the special attribute block. Previously, this 
+       class name was only allowed in the absence of the special attribute block.
+
+*      Added a `code_block_content_func` configuration variable which takes a 
+       function that will convert the content of the code block to HTML. This is 
+       most useful for syntax highlighting. For fenced code blocks in Markdown 
+       Extra, the function has access to the language class name (the one outside 
+       of the special attribute block). Credits to Mario Konrad for providing the 
+       implementation.
+
+*      The curled arrow character for the backlink in footnotes is now followed
+       by a Unicode variant selector to prevent it from being displayed in emoji
+       form on iOS.
+
+       Note that in older browsers the variant selector is often interpreted as a 
+       separate character, making it visible after the arrow. So there is now a 
+       also a `fn_backlink_html` configuration variable that can be used to set 
+       the link text to something else. Credits to Dana for providing the 
+       implementation.
+
+*      Fixed an issue in MarkdownExtra where long header lines followed by a
+       special attribute block would hit the backtrack limit an cause an empty
+       string to be returned.
+
+
+PHP Markdown Lib 1.5.0 (1 Mar 2015)
+
+*      Added the ability start ordered lists with a number different from 1 and
+       and have that reflected in the HTML output. This can be enabled with
+       the `enhanced_ordered_lists` configuration variable for the Markdown 
+       parser; it is enabled by default for Markdown Extra.
+       Credits to Matt Gorle for providing the implementation.
+
+*      Added the ability to insert custom HTML attributes with simple values 
+       everywhere an extra attribute block is allowed (links, images, headers).
+       The value must be unquoted, cannot contains spaces and is limited to 
+       alphanumeric ASCII characters.
+       Credits to Peter Droogmans for providing the implementation.
+
+*      Added a `header_id_func` configuration variable which takes a function
+       that can generate an `id` attribute value from the header text.
+       Credits to Evert Pot for providing the implementation.
 
 *      Added a `url_filter_func` configuration variable which takes a function
        that can rewrite any link or image URL to something different.
@@ -239,7 +308,7 @@ PHP Markdown Extra 1.2.6:
 
 *      Plugin interface for WordPress and other systems is no longer present in
        the Lib package. The classic package is still available if you need it:
-       <http://michelf.ca/projects/php-markdown/classic/>
+       <https://michelf.ca/projects/php-markdown/classic/>
 
 *      Added `public` and `protected` protection attributes, plus a section about
        what is "public API" and what isn't in the Readme file.
@@ -277,13 +346,13 @@ Copyright and License
 ---------------------
 
 PHP Markdown Lib
-Copyright (c) 2004-2014 Michel Fortin
-<http://michelf.ca/>  
+Copyright (c) 2004-2016 Michel Fortin
+<https://michelf.ca/>  
 All rights reserved.
 
 Based on Markdown  
 Copyright (c) 2003-2005 John Gruber   
-<http://daringfireball.net/>   
+<https://daringfireball.net/>   
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
index d007b119f212686ae7f44f21381a0ea87555e845..89449dea4dc1743a0ca0914aa7959120dfbcd3ef 100644 (file)
@@ -1,18 +1,18 @@
 <?php
 
-# This file passes the content of the Readme.md file in the same directory
-# through the Markdown filter. You can adapt this sample code in any way
-# you like.
+// This file passes the content of the Readme.md file in the same directory
+// through the Markdown filter. You can adapt this sample code in any way
+// you like.
 
-# Install PSR-0-compatible class autoloader
+// Install PSR-0-compatible class autoloader
 spl_autoload_register(function($class){
        require preg_replace('{\\\\|_(?!.*\\\\)}', DIRECTORY_SEPARATOR, ltrim($class, '\\')).'.php';
 });
 
-# Get Markdown class
+// Get Markdown class
 use \Michelf\Markdown;
 
-# Read file and pass content through the Markdown parser
+// Read file and pass content through the Markdown parser
 $text = file_get_contents('Readme.md');
 $html = Markdown::defaultTransform($text);
 
@@ -24,7 +24,7 @@ $html = Markdown::defaultTransform($text);
     </head>
     <body>
                <?php
-                       # Put HTML content in the document
+                       // Put HTML content in the document
                        echo $html;
                ?>
     </body>
index 45abc67744cf9167d1a17a51f8bf1376339ed640..c219e543c28450d96f2a8779ff3283b29af67eec 100644 (file)
@@ -2,19 +2,19 @@
        "name": "michelf/php-markdown",
        "type": "library",
        "description": "PHP Markdown",
-       "homepage": "http://michelf.ca/projects/php-markdown/",
+       "homepage": "https://michelf.ca/projects/php-markdown/",
        "keywords": ["markdown"],
        "license": "BSD-3-Clause",
        "authors": [
                {
                        "name": "Michel Fortin",
                        "email": "michel.fortin@michelf.ca",
-                       "homepage": "http://michelf.ca/",
+                       "homepage": "https://michelf.ca/",
                        "role": "Developer"
                },
                {
                        "name": "John Gruber",
-                       "homepage": "http://daringfireball.net/"
+                       "homepage": "https://daringfireball.net/"
                }
        ],
        "require": {
        },
        "autoload": {
                "psr-0": { "Michelf": "" }
-       },
-       "extra": {
-               "branch-alias": {
-                       "dev-lib": "1.4.x-dev"
-               }
        }
 }
diff --git a/library/phpsec/Crypt/AES.php b/library/phpsec/Crypt/AES.php
deleted file mode 100644 (file)
index 681800a..0000000
+++ /dev/null
@@ -1,479 +0,0 @@
-<?php\r
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */\r
-\r
-/**\r
- * Pure-PHP implementation of AES.\r
- *\r
- * Uses mcrypt, if available, and an internal implementation, otherwise.\r
- *\r
- * PHP versions 4 and 5\r
- *\r
- * If {@link Crypt_AES::setKeyLength() setKeyLength()} isn't called, it'll be calculated from\r
- * {@link Crypt_AES::setKey() setKey()}.  ie. if the key is 128-bits, the key length will be 128-bits.  If it's 136-bits\r
- * it'll be null-padded to 160-bits and 160 bits will be the key length until {@link Crypt_Rijndael::setKey() setKey()}\r
- * is called, again, at which point, it'll be recalculated.\r
- *\r
- * Since Crypt_AES extends Crypt_Rijndael, some functions are available to be called that, in the context of AES, don't\r
- * make a whole lot of sense.  {@link Crypt_AES::setBlockLength() setBlockLength()}, for instance.  Calling that function,\r
- * however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).\r
- *\r
- * Here's a short example of how to use this library:\r
- * <code>\r
- * <?php\r
- *    include('Crypt/AES.php');\r
- *\r
- *    $aes = new Crypt_AES();\r
- *\r
- *    $aes->setKey('abcdefghijklmnop');\r
- *\r
- *    $size = 10 * 1024;\r
- *    $plaintext = '';\r
- *    for ($i = 0; $i < $size; $i++) {\r
- *        $plaintext.= 'a';\r
- *    }\r
- *\r
- *    echo $aes->decrypt($aes->encrypt($plaintext));\r
- * ?>\r
- * </code>\r
- *\r
- * LICENSE: This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,\r
- * MA  02111-1307  USA\r
- *\r
- * @category   Crypt\r
- * @package    Crypt_AES\r
- * @author     Jim Wigginton <terrafrost@php.net>\r
- * @copyright  MMVIII Jim Wigginton\r
- * @license    http://www.gnu.org/licenses/lgpl.txt\r
- * @version    $Id: AES.php,v 1.7 2010/02/09 06:10:25 terrafrost Exp $\r
- * @link       http://phpseclib.sourceforge.net\r
- */\r
-\r
-/**\r
- * Include Crypt_Rijndael\r
- */\r
-require_once 'Rijndael.php';\r
-\r
-/**#@+\r
- * @access public\r
- * @see Crypt_AES::encrypt()\r
- * @see Crypt_AES::decrypt()\r
- */\r
-/**\r
- * Encrypt / decrypt using the Counter mode.\r
- *\r
- * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.\r
- *\r
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29\r
- */\r
-define('CRYPT_AES_MODE_CTR', -1);\r
-/**\r
- * Encrypt / decrypt using the Electronic Code Book mode.\r
- *\r
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29\r
- */\r
-define('CRYPT_AES_MODE_ECB', 1);\r
-/**\r
- * Encrypt / decrypt using the Code Book Chaining mode.\r
- *\r
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29\r
- */\r
-define('CRYPT_AES_MODE_CBC', 2);\r
-/**#@-*/\r
-\r
-/**#@+\r
- * @access private\r
- * @see Crypt_AES::Crypt_AES()\r
- */\r
-/**\r
- * Toggles the internal implementation\r
- */\r
-define('CRYPT_AES_MODE_INTERNAL', 1);\r
-/**\r
- * Toggles the mcrypt implementation\r
- */\r
-define('CRYPT_AES_MODE_MCRYPT', 2);\r
-/**#@-*/\r
-\r
-/**\r
- * Pure-PHP implementation of AES.\r
- *\r
- * @author  Jim Wigginton <terrafrost@php.net>\r
- * @version 0.1.0\r
- * @access  public\r
- * @package Crypt_AES\r
- */\r
-class Crypt_AES extends Crypt_Rijndael {\r
-    /**\r
-     * mcrypt resource for encryption\r
-     *\r
-     * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.\r
-     * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.\r
-     *\r
-     * @see Crypt_AES::encrypt()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $enmcrypt;\r
-\r
-    /**\r
-     * mcrypt resource for decryption\r
-     *\r
-     * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.\r
-     * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.\r
-     *\r
-     * @see Crypt_AES::decrypt()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $demcrypt;\r
-\r
-    /**\r
-     * Default Constructor.\r
-     *\r
-     * Determines whether or not the mcrypt extension should be used.  $mode should only, at present, be\r
-     * CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC.  If not explictly set, CRYPT_AES_MODE_CBC will be used.\r
-     *\r
-     * @param optional Integer $mode\r
-     * @return Crypt_AES\r
-     * @access public\r
-     */\r
-    function Crypt_AES($mode = CRYPT_AES_MODE_CBC)\r
-    {\r
-        if ( !defined('CRYPT_AES_MODE') ) {\r
-            switch (true) {\r
-                case extension_loaded('mcrypt'):\r
-                    // i'd check to see if aes was supported, by doing in_array('des', mcrypt_list_algorithms('')),\r
-                    // but since that can be changed after the object has been created, there doesn't seem to be\r
-                    // a lot of point...\r
-                    define('CRYPT_AES_MODE', CRYPT_AES_MODE_MCRYPT);\r
-                    break;\r
-                default:\r
-                    define('CRYPT_AES_MODE', CRYPT_AES_MODE_INTERNAL);\r
-            }\r
-        }\r
-\r
-        switch ( CRYPT_AES_MODE ) {\r
-            case CRYPT_AES_MODE_MCRYPT:\r
-                switch ($mode) {\r
-                    case CRYPT_AES_MODE_ECB:\r
-                        $this->mode = MCRYPT_MODE_ECB;\r
-                        break;\r
-                    case CRYPT_AES_MODE_CTR:\r
-                        // ctr doesn't have a constant associated with it even though it appears to be fairly widely\r
-                        // supported.  in lieu of knowing just how widely supported it is, i've, for now, opted not to\r
-                        // include a compatibility layer.  the layer has been implemented but, for now, is commented out.\r
-                        $this->mode = 'ctr';\r
-                        //$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_AES_MODE_CTR;\r
-                        break;\r
-                    case CRYPT_AES_MODE_CBC:\r
-                    default:\r
-                        $this->mode = MCRYPT_MODE_CBC;\r
-                }\r
-\r
-                break;\r
-            default:\r
-                switch ($mode) {\r
-                    case CRYPT_AES_MODE_ECB:\r
-                        $this->mode = CRYPT_RIJNDAEL_MODE_ECB;\r
-                        break;\r
-                    case CRYPT_AES_MODE_CTR:\r
-                        $this->mode = CRYPT_RIJNDAEL_MODE_CTR;\r
-                        break;\r
-                    case CRYPT_AES_MODE_CBC:\r
-                    default:\r
-                        $this->mode = CRYPT_RIJNDAEL_MODE_CBC;\r
-                }\r
-        }\r
-\r
-        if (CRYPT_AES_MODE == CRYPT_AES_MODE_INTERNAL) {\r
-            parent::Crypt_Rijndael($this->mode);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Dummy function\r
-     *\r
-     * Since Crypt_AES extends Crypt_Rijndael, this function is, technically, available, but it doesn't do anything.\r
-     *\r
-     * @access public\r
-     * @param Integer $length\r
-     */\r
-    function setBlockLength($length)\r
-    {\r
-        return;\r
-    }\r
-\r
-    /**\r
-     * Encrypts a message.\r
-     *\r
-     * $plaintext will be padded with up to 16 additional bytes.  Other AES implementations may or may not pad in the\r
-     * same manner.  Other common approaches to padding and the reasons why it's necessary are discussed in the following\r
-     * URL:\r
-     *\r
-     * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}\r
-     *\r
-     * An alternative to padding is to, separately, send the length of the file.  This is what SSH, in fact, does.\r
-     * strlen($plaintext) will still need to be a multiple of 16, however, arbitrary values can be added to make it that\r
-     * length.\r
-     *\r
-     * @see Crypt_AES::decrypt()\r
-     * @access public\r
-     * @param String $plaintext\r
-     */\r
-    function encrypt($plaintext)\r
-    {\r
-        if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {\r
-            $this->_mcryptSetup();\r
-            /*\r
-            if ($this->mode == CRYPT_AES_MODE_CTR) {\r
-                $iv = $this->encryptIV;\r
-                $xor = mcrypt_generic($this->enmcrypt, $this->_generate_xor(strlen($plaintext), $iv));\r
-                $ciphertext = $plaintext ^ $xor;\r
-                if ($this->continuousBuffer) {\r
-                    $this->encryptIV = $iv;\r
-                }\r
-                return $ciphertext;\r
-            }\r
-            */\r
-\r
-            if ($this->mode != 'ctr') {\r
-                $plaintext = $this->_pad($plaintext);\r
-            }\r
-\r
-            $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);\r
-\r
-            if (!$this->continuousBuffer) {\r
-                mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);\r
-            }\r
-\r
-            return $ciphertext;\r
-        }\r
-\r
-        return parent::encrypt($plaintext);\r
-    }\r
-\r
-    /**\r
-     * Decrypts a message.\r
-     *\r
-     * If strlen($ciphertext) is not a multiple of 16, null bytes will be added to the end of the string until it is.\r
-     *\r
-     * @see Crypt_AES::encrypt()\r
-     * @access public\r
-     * @param String $ciphertext\r
-     */\r
-    function decrypt($ciphertext)\r
-    {\r
-        if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {\r
-            $this->_mcryptSetup();\r
-            /*\r
-            if ($this->mode == CRYPT_AES_MODE_CTR) {\r
-                $iv = $this->decryptIV;\r
-                $xor = mcrypt_generic($this->enmcrypt, $this->_generate_xor(strlen($ciphertext), $iv));\r
-                $plaintext = $ciphertext ^ $xor;\r
-                if ($this->continuousBuffer) {\r
-                    $this->decryptIV = $iv;\r
-                }\r
-                return $plaintext;\r
-            }\r
-            */\r
-\r
-            if ($this->mode != 'ctr') {\r
-                // we pad with chr(0) since that's what mcrypt_generic does.  to quote from http://php.net/function.mcrypt-generic :\r
-                // "The data is padded with "\0" to make sure the length of the data is n * blocksize."\r
-                $ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 15) & 0xFFFFFFF0, chr(0));\r
-            }\r
-\r
-            $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);\r
-\r
-            if (!$this->continuousBuffer) {\r
-                mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);\r
-            }\r
-\r
-            return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext;\r
-        }\r
-\r
-        return parent::decrypt($ciphertext);\r
-    }\r
-\r
-    /**\r
-     * Setup mcrypt\r
-     *\r
-     * Validates all the variables.\r
-     *\r
-     * @access private\r
-     */\r
-    function _mcryptSetup()\r
-    {\r
-        if (!$this->changed) {\r
-            return;\r
-        }\r
-\r
-        if (!$this->explicit_key_length) {\r
-            // this just copied from Crypt_Rijndael::_setup()\r
-            $length = strlen($this->key) >> 2;\r
-            if ($length > 8) {\r
-                $length = 8;\r
-            } else if ($length < 4) {\r
-                $length = 4;\r
-            }\r
-            $this->Nk = $length;\r
-            $this->key_size = $length << 2;\r
-        }\r
-\r
-        switch ($this->Nk) {\r
-            case 4: // 128\r
-                $this->key_size = 16;\r
-                break;\r
-            case 5: // 160\r
-            case 6: // 192\r
-                $this->key_size = 24;\r
-                break;\r
-            case 7: // 224\r
-            case 8: // 256\r
-                $this->key_size = 32;\r
-        }\r
-\r
-        $this->key = substr($this->key, 0, $this->key_size);\r
-        $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($this->iv, 0, 16), 16, chr(0));\r
-\r
-        if (!isset($this->enmcrypt)) {\r
-            $mode = $this->mode;\r
-            //$mode = $this->mode == CRYPT_AES_MODE_CTR ? MCRYPT_MODE_ECB : $this->mode;\r
-\r
-            $this->demcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');\r
-            $this->enmcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');\r
-        } // else should mcrypt_generic_deinit be called?\r
-\r
-        mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);\r
-        mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);\r
-\r
-        $this->changed = false;\r
-    }\r
-\r
-    /**\r
-     * Encrypts a block\r
-     *\r
-     * Optimized over Crypt_Rijndael's implementation by means of loop unrolling.\r
-     *\r
-     * @see Crypt_Rijndael::_encryptBlock()\r
-     * @access private\r
-     * @param String $in\r
-     * @return String\r
-     */\r
-    function _encryptBlock($in)\r
-    {\r
-        $state = unpack('N*word', $in);\r
-\r
-        $Nr = $this->Nr;\r
-        $w = $this->w;\r
-        $t0 = $this->t0;\r
-        $t1 = $this->t1;\r
-        $t2 = $this->t2;\r
-        $t3 = $this->t3;\r
-\r
-        // addRoundKey and reindex $state\r
-        $state = array(\r
-            $state['word1'] ^ $w[0][0],\r
-            $state['word2'] ^ $w[0][1],\r
-            $state['word3'] ^ $w[0][2],\r
-            $state['word4'] ^ $w[0][3]\r
-        );\r
-\r
-        // shiftRows + subWord + mixColumns + addRoundKey\r
-        // we could loop unroll this and use if statements to do more rounds as necessary, but, in my tests, that yields\r
-        // only a marginal improvement.  since that also, imho, hinders the readability of the code, i've opted not to do it.\r
-        for ($round = 1; $round < $this->Nr; $round++) {\r
-            $state = array(\r
-                $t0[$state[0] & 0xFF000000] ^ $t1[$state[1] & 0x00FF0000] ^ $t2[$state[2] & 0x0000FF00] ^ $t3[$state[3] & 0x000000FF] ^ $w[$round][0],\r
-                $t0[$state[1] & 0xFF000000] ^ $t1[$state[2] & 0x00FF0000] ^ $t2[$state[3] & 0x0000FF00] ^ $t3[$state[0] & 0x000000FF] ^ $w[$round][1],\r
-                $t0[$state[2] & 0xFF000000] ^ $t1[$state[3] & 0x00FF0000] ^ $t2[$state[0] & 0x0000FF00] ^ $t3[$state[1] & 0x000000FF] ^ $w[$round][2],\r
-                $t0[$state[3] & 0xFF000000] ^ $t1[$state[0] & 0x00FF0000] ^ $t2[$state[1] & 0x0000FF00] ^ $t3[$state[2] & 0x000000FF] ^ $w[$round][3]\r
-            );\r
-\r
-        }\r
-\r
-        // subWord\r
-        $state = array(\r
-            $this->_subWord($state[0]),\r
-            $this->_subWord($state[1]),\r
-            $this->_subWord($state[2]),\r
-            $this->_subWord($state[3])\r
-        );\r
-\r
-        // shiftRows + addRoundKey\r
-        $state = array(\r
-            ($state[0] & 0xFF000000) ^ ($state[1] & 0x00FF0000) ^ ($state[2] & 0x0000FF00) ^ ($state[3] & 0x000000FF) ^ $this->w[$this->Nr][0],\r
-            ($state[1] & 0xFF000000) ^ ($state[2] & 0x00FF0000) ^ ($state[3] & 0x0000FF00) ^ ($state[0] & 0x000000FF) ^ $this->w[$this->Nr][1],\r
-            ($state[2] & 0xFF000000) ^ ($state[3] & 0x00FF0000) ^ ($state[0] & 0x0000FF00) ^ ($state[1] & 0x000000FF) ^ $this->w[$this->Nr][2],\r
-            ($state[3] & 0xFF000000) ^ ($state[0] & 0x00FF0000) ^ ($state[1] & 0x0000FF00) ^ ($state[2] & 0x000000FF) ^ $this->w[$this->Nr][3]\r
-        );\r
-\r
-        return pack('N*', $state[0], $state[1], $state[2], $state[3]);\r
-    }\r
-\r
-    /**\r
-     * Decrypts a block\r
-     *\r
-     * Optimized over Crypt_Rijndael's implementation by means of loop unrolling.\r
-     *\r
-     * @see Crypt_Rijndael::_decryptBlock()\r
-     * @access private\r
-     * @param String $in\r
-     * @return String\r
-     */\r
-    function _decryptBlock($in)\r
-    {\r
-        $state = unpack('N*word', $in);\r
-\r
-        $Nr = $this->Nr;\r
-        $dw = $this->dw;\r
-        $dt0 = $this->dt0;\r
-        $dt1 = $this->dt1;\r
-        $dt2 = $this->dt2;\r
-        $dt3 = $this->dt3;\r
-\r
-        // addRoundKey and reindex $state\r
-        $state = array(\r
-            $state['word1'] ^ $dw[$this->Nr][0],\r
-            $state['word2'] ^ $dw[$this->Nr][1],\r
-            $state['word3'] ^ $dw[$this->Nr][2],\r
-            $state['word4'] ^ $dw[$this->Nr][3]\r
-        );\r
-\r
-\r
-        // invShiftRows + invSubBytes + invMixColumns + addRoundKey\r
-        for ($round = $this->Nr - 1; $round > 0; $round--) {\r
-            $state = array(\r
-                $dt0[$state[0] & 0xFF000000] ^ $dt1[$state[3] & 0x00FF0000] ^ $dt2[$state[2] & 0x0000FF00] ^ $dt3[$state[1] & 0x000000FF] ^ $dw[$round][0],\r
-                $dt0[$state[1] & 0xFF000000] ^ $dt1[$state[0] & 0x00FF0000] ^ $dt2[$state[3] & 0x0000FF00] ^ $dt3[$state[2] & 0x000000FF] ^ $dw[$round][1],\r
-                $dt0[$state[2] & 0xFF000000] ^ $dt1[$state[1] & 0x00FF0000] ^ $dt2[$state[0] & 0x0000FF00] ^ $dt3[$state[3] & 0x000000FF] ^ $dw[$round][2],\r
-                $dt0[$state[3] & 0xFF000000] ^ $dt1[$state[2] & 0x00FF0000] ^ $dt2[$state[1] & 0x0000FF00] ^ $dt3[$state[0] & 0x000000FF] ^ $dw[$round][3]\r
-            );\r
-        }\r
-\r
-        // invShiftRows + invSubWord + addRoundKey\r
-        $state = array(\r
-            $this->_invSubWord(($state[0] & 0xFF000000) ^ ($state[3] & 0x00FF0000) ^ ($state[2] & 0x0000FF00) ^ ($state[1] & 0x000000FF)) ^ $dw[0][0],\r
-            $this->_invSubWord(($state[1] & 0xFF000000) ^ ($state[0] & 0x00FF0000) ^ ($state[3] & 0x0000FF00) ^ ($state[2] & 0x000000FF)) ^ $dw[0][1],\r
-            $this->_invSubWord(($state[2] & 0xFF000000) ^ ($state[1] & 0x00FF0000) ^ ($state[0] & 0x0000FF00) ^ ($state[3] & 0x000000FF)) ^ $dw[0][2],\r
-            $this->_invSubWord(($state[3] & 0xFF000000) ^ ($state[2] & 0x00FF0000) ^ ($state[1] & 0x0000FF00) ^ ($state[0] & 0x000000FF)) ^ $dw[0][3]\r
-        );\r
-\r
-        return pack('N*', $state[0], $state[1], $state[2], $state[3]);\r
-    }\r
-}\r
-\r
-// vim: ts=4:sw=4:et:\r
-// vim6: fdl=1:
\ No newline at end of file
diff --git a/library/phpsec/Crypt/DES.php b/library/phpsec/Crypt/DES.php
deleted file mode 100644 (file)
index 431ad53..0000000
+++ /dev/null
@@ -1,945 +0,0 @@
-<?php\r
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */\r
-\r
-/**\r
- * Pure-PHP implementation of DES.\r
- *\r
- * Uses mcrypt, if available, and an internal implementation, otherwise.\r
- *\r
- * PHP versions 4 and 5\r
- *\r
- * Useful resources are as follows:\r
- *\r
- *  - {@link http://en.wikipedia.org/wiki/DES_supplementary_material Wikipedia: DES supplementary material}\r
- *  - {@link http://www.itl.nist.gov/fipspubs/fip46-2.htm FIPS 46-2 - (DES), Data Encryption Standard}\r
- *  - {@link http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-DES.html JavaScript DES Example}\r
- *\r
- * Here's a short example of how to use this library:\r
- * <code>\r
- * <?php\r
- *    include('Crypt/DES.php');\r
- *\r
- *    $des = new Crypt_DES();\r
- *\r
- *    $des->setKey('abcdefgh');\r
- *\r
- *    $size = 10 * 1024;\r
- *    $plaintext = '';\r
- *    for ($i = 0; $i < $size; $i++) {\r
- *        $plaintext.= 'a';\r
- *    }\r
- *\r
- *    echo $des->decrypt($des->encrypt($plaintext));\r
- * ?>\r
- * </code>\r
- *\r
- * LICENSE: This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,\r
- * MA  02111-1307  USA\r
- *\r
- * @category   Crypt\r
- * @package    Crypt_DES\r
- * @author     Jim Wigginton <terrafrost@php.net>\r
- * @copyright  MMVII Jim Wigginton\r
- * @license    http://www.gnu.org/licenses/lgpl.txt\r
- * @version    $Id: DES.php,v 1.12 2010/02/09 06:10:26 terrafrost Exp $\r
- * @link       http://phpseclib.sourceforge.net\r
- */\r
-\r
-/**#@+\r
- * @access private\r
- * @see Crypt_DES::_prepareKey()\r
- * @see Crypt_DES::_processBlock()\r
- */\r
-/**\r
- * Contains array_reverse($keys[CRYPT_DES_DECRYPT])\r
- */\r
-define('CRYPT_DES_ENCRYPT', 0);\r
-/**\r
- * Contains array_reverse($keys[CRYPT_DES_ENCRYPT])\r
- */\r
-define('CRYPT_DES_DECRYPT', 1);\r
-/**#@-*/\r
-\r
-/**#@+\r
- * @access public\r
- * @see Crypt_DES::encrypt()\r
- * @see Crypt_DES::decrypt()\r
- */\r
-/**\r
- * Encrypt / decrypt using the Counter mode.\r
- *\r
- * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.\r
- *\r
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29\r
- */\r
-define('CRYPT_DES_MODE_CTR', -1);\r
-/**\r
- * Encrypt / decrypt using the Electronic Code Book mode.\r
- *\r
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29\r
- */\r
-define('CRYPT_DES_MODE_ECB', 1);\r
-/**\r
- * Encrypt / decrypt using the Code Book Chaining mode.\r
- *\r
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29\r
- */\r
-define('CRYPT_DES_MODE_CBC', 2);\r
-/**#@-*/\r
-\r
-/**#@+\r
- * @access private\r
- * @see Crypt_DES::Crypt_DES()\r
- */\r
-/**\r
- * Toggles the internal implementation\r
- */\r
-define('CRYPT_DES_MODE_INTERNAL', 1);\r
-/**\r
- * Toggles the mcrypt implementation\r
- */\r
-define('CRYPT_DES_MODE_MCRYPT', 2);\r
-/**#@-*/\r
-\r
-/**\r
- * Pure-PHP implementation of DES.\r
- *\r
- * @author  Jim Wigginton <terrafrost@php.net>\r
- * @version 0.1.0\r
- * @access  public\r
- * @package Crypt_DES\r
- */\r
-class Crypt_DES {\r
-    /**\r
-     * The Key Schedule\r
-     *\r
-     * @see Crypt_DES::setKey()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $keys = "\0\0\0\0\0\0\0\0";\r
-\r
-    /**\r
-     * The Encryption Mode\r
-     *\r
-     * @see Crypt_DES::Crypt_DES()\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $mode;\r
-\r
-    /**\r
-     * Continuous Buffer status\r
-     *\r
-     * @see Crypt_DES::enableContinuousBuffer()\r
-     * @var Boolean\r
-     * @access private\r
-     */\r
-    var $continuousBuffer = false;\r
-\r
-    /**\r
-     * Padding status\r
-     *\r
-     * @see Crypt_DES::enablePadding()\r
-     * @var Boolean\r
-     * @access private\r
-     */\r
-    var $padding = true;\r
-\r
-    /**\r
-     * The Initialization Vector\r
-     *\r
-     * @see Crypt_DES::setIV()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $iv = "\0\0\0\0\0\0\0\0";\r
-\r
-    /**\r
-     * A "sliding" Initialization Vector\r
-     *\r
-     * @see Crypt_DES::enableContinuousBuffer()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $encryptIV = "\0\0\0\0\0\0\0\0";\r
-\r
-    /**\r
-     * A "sliding" Initialization Vector\r
-     *\r
-     * @see Crypt_DES::enableContinuousBuffer()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $decryptIV = "\0\0\0\0\0\0\0\0";\r
-\r
-    /**\r
-     * mcrypt resource for encryption\r
-     *\r
-     * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.\r
-     * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.\r
-     *\r
-     * @see Crypt_AES::encrypt()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $enmcrypt;\r
-\r
-    /**\r
-     * mcrypt resource for decryption\r
-     *\r
-     * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.\r
-     * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.\r
-     *\r
-     * @see Crypt_AES::decrypt()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $demcrypt;\r
-\r
-    /**\r
-     * Does the (en|de)mcrypt resource need to be (re)initialized?\r
-     *\r
-     * @see setKey()\r
-     * @see setIV()\r
-     * @var Boolean\r
-     * @access private\r
-     */\r
-    var $changed = true;\r
-\r
-    /**\r
-     * Default Constructor.\r
-     *\r
-     * Determines whether or not the mcrypt extension should be used.  $mode should only, at present, be\r
-     * CRYPT_DES_MODE_ECB or CRYPT_DES_MODE_CBC.  If not explictly set, CRYPT_DES_MODE_CBC will be used.\r
-     *\r
-     * @param optional Integer $mode\r
-     * @return Crypt_DES\r
-     * @access public\r
-     */\r
-    function Crypt_DES($mode = CRYPT_MODE_DES_CBC)\r
-    {\r
-        if ( !defined('CRYPT_DES_MODE') ) {\r
-            switch (true) {\r
-                case extension_loaded('mcrypt'):\r
-                    // i'd check to see if des was supported, by doing in_array('des', mcrypt_list_algorithms('')),\r
-                    // but since that can be changed after the object has been created, there doesn't seem to be\r
-                    // a lot of point...\r
-                    define('CRYPT_DES_MODE', CRYPT_DES_MODE_MCRYPT);\r
-                    break;\r
-                default:\r
-                    define('CRYPT_DES_MODE', CRYPT_DES_MODE_INTERNAL);\r
-            }\r
-        }\r
-\r
-        switch ( CRYPT_DES_MODE ) {\r
-            case CRYPT_DES_MODE_MCRYPT:\r
-                switch ($mode) {\r
-                    case CRYPT_DES_MODE_ECB:\r
-                        $this->mode = MCRYPT_MODE_ECB;\r
-                        break;\r
-                    case CRYPT_DES_MODE_CTR:\r
-                        $this->mode = 'ctr';\r
-                        //$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_DES_MODE_CTR;\r
-                        break;\r
-                    case CRYPT_DES_MODE_CBC:\r
-                    default:\r
-                        $this->mode = MCRYPT_MODE_CBC;\r
-                }\r
-\r
-                break;\r
-            default:\r
-                switch ($mode) {\r
-                    case CRYPT_DES_MODE_ECB:\r
-                    case CRYPT_DES_MODE_CTR:\r
-                    case CRYPT_DES_MODE_CBC:\r
-                        $this->mode = $mode;\r
-                        break;\r
-                    default:\r
-                        $this->mode = CRYPT_DES_MODE_CBC;\r
-                }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Sets the key.\r
-     *\r
-     * Keys can be of any length.  DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we\r
-     * only use the first eight, if $key has more then eight characters in it, and pad $key with the\r
-     * null byte if it is less then eight characters long.\r
-     *\r
-     * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.\r
-     *\r
-     * If the key is not explicitly set, it'll be assumed to be all zero's.\r
-     *\r
-     * @access public\r
-     * @param String $key\r
-     */\r
-    function setKey($key)\r
-    {\r
-        $this->keys = ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) ? substr($key, 0, 8) : $this->_prepareKey($key);\r
-        $this->changed = true;\r
-    }\r
-\r
-    /**\r
-     * Sets the initialization vector. (optional)\r
-     *\r
-     * SetIV is not required when CRYPT_DES_MODE_ECB is being used.  If not explictly set, it'll be assumed\r
-     * to be all zero's.\r
-     *\r
-     * @access public\r
-     * @param String $iv\r
-     */\r
-    function setIV($iv)\r
-    {\r
-        $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, 8), 8, chr(0));\r
-        $this->changed = true;\r
-    }\r
-\r
-    /**\r
-     * Generate CTR XOR encryption key\r
-     *\r
-     * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the\r
-     * plaintext / ciphertext in CTR mode.\r
-     *\r
-     * @see Crypt_DES::decrypt()\r
-     * @see Crypt_DES::encrypt()\r
-     * @access public\r
-     * @param Integer $length\r
-     * @param String $iv\r
-     */\r
-    function _generate_xor($length, &$iv)\r
-    {\r
-        $xor = '';\r
-        $num_blocks = ($length + 7) >> 3;\r
-        for ($i = 0; $i < $num_blocks; $i++) {\r
-            $xor.= $iv;\r
-            for ($j = 4; $j <= 8; $j+=4) {\r
-                $temp = substr($iv, -$j, 4);\r
-                switch ($temp) {\r
-                    case "\xFF\xFF\xFF\xFF":\r
-                        $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);\r
-                        break;\r
-                    case "\x7F\xFF\xFF\xFF":\r
-                        $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);\r
-                        break 2;\r
-                    default:\r
-                        extract(unpack('Ncount', $temp));\r
-                        $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);\r
-                        break 2;\r
-                }\r
-            }\r
-        }\r
-\r
-        return $xor;\r
-    }\r
-\r
-    /**\r
-     * Encrypts a message.\r
-     *\r
-     * $plaintext will be padded with up to 8 additional bytes.  Other DES implementations may or may not pad in the\r
-     * same manner.  Other common approaches to padding and the reasons why it's necessary are discussed in the following\r
-     * URL:\r
-     *\r
-     * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}\r
-     *\r
-     * An alternative to padding is to, separately, send the length of the file.  This is what SSH, in fact, does.\r
-     * strlen($plaintext) will still need to be a multiple of 8, however, arbitrary values can be added to make it that\r
-     * length.\r
-     *\r
-     * @see Crypt_DES::decrypt()\r
-     * @access public\r
-     * @param String $plaintext\r
-     */\r
-    function encrypt($plaintext)\r
-    {\r
-        if ($this->mode != CRYPT_DES_MODE_CTR && $this->mode != 'ctr') {\r
-            $plaintext = $this->_pad($plaintext);\r
-        }\r
-\r
-        if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {\r
-            if ($this->changed) {\r
-                if (!isset($this->enmcrypt)) {\r
-                    $this->enmcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');\r
-                }\r
-                mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);\r
-                $this->changed = false;\r
-            }\r
-\r
-            $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);\r
-\r
-            if (!$this->continuousBuffer) {\r
-                mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);\r
-            }\r
-\r
-            return $ciphertext;\r
-        }\r
-\r
-        if (!is_array($this->keys)) {\r
-            $this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");\r
-        }\r
-\r
-        $ciphertext = '';\r
-        switch ($this->mode) {\r
-            case CRYPT_DES_MODE_ECB:\r
-                for ($i = 0; $i < strlen($plaintext); $i+=8) {\r
-                    $ciphertext.= $this->_processBlock(substr($plaintext, $i, 8), CRYPT_DES_ENCRYPT);\r
-                }\r
-                break;\r
-            case CRYPT_DES_MODE_CBC:\r
-                $xor = $this->encryptIV;\r
-                for ($i = 0; $i < strlen($plaintext); $i+=8) {\r
-                    $block = substr($plaintext, $i, 8);\r
-                    $block = $this->_processBlock($block ^ $xor, CRYPT_DES_ENCRYPT);\r
-                    $xor = $block;\r
-                    $ciphertext.= $block;\r
-                }\r
-                if ($this->continuousBuffer) {\r
-                    $this->encryptIV = $xor;\r
-                }\r
-                break;\r
-            case CRYPT_DES_MODE_CTR:\r
-                $xor = $this->encryptIV;\r
-                for ($i = 0; $i < strlen($plaintext); $i+=8) {\r
-                    $block = substr($plaintext, $i, 8);\r
-                    $key = $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);\r
-                    $ciphertext.= $block ^ $key;\r
-                }\r
-                if ($this->continuousBuffer) {\r
-                    $this->encryptIV = $xor;\r
-                }\r
-        }\r
-\r
-        return $ciphertext;\r
-    }\r
-\r
-    /**\r
-     * Decrypts a message.\r
-     *\r
-     * If strlen($ciphertext) is not a multiple of 8, null bytes will be added to the end of the string until it is.\r
-     *\r
-     * @see Crypt_DES::encrypt()\r
-     * @access public\r
-     * @param String $ciphertext\r
-     */\r
-    function decrypt($ciphertext)\r
-    {\r
-        if ($this->mode != CRYPT_DES_MODE_CTR && $this->mode != 'ctr') {\r
-            // we pad with chr(0) since that's what mcrypt_generic does.  to quote from http://php.net/function.mcrypt-generic :\r
-            // "The data is padded with "\0" to make sure the length of the data is n * blocksize."\r
-            $ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, chr(0));\r
-        }\r
-\r
-        if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {\r
-            if ($this->changed) {\r
-                if (!isset($this->demcrypt)) {\r
-                    $this->demcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');\r
-                }\r
-                mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);\r
-                $this->changed = false;\r
-            }\r
-\r
-            $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);\r
-\r
-            if (!$this->continuousBuffer) {\r
-                mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);\r
-            }\r
-\r
-            return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext;\r
-        }\r
-\r
-        if (!is_array($this->keys)) {\r
-            $this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");\r
-        }\r
-\r
-        $plaintext = '';\r
-        switch ($this->mode) {\r
-            case CRYPT_DES_MODE_ECB:\r
-                for ($i = 0; $i < strlen($ciphertext); $i+=8) {\r
-                    $plaintext.= $this->_processBlock(substr($ciphertext, $i, 8), CRYPT_DES_DECRYPT);\r
-                }\r
-                break;\r
-            case CRYPT_DES_MODE_CBC:\r
-                $xor = $this->decryptIV;\r
-                for ($i = 0; $i < strlen($ciphertext); $i+=8) {\r
-                    $block = substr($ciphertext, $i, 8);\r
-                    $plaintext.= $this->_processBlock($block, CRYPT_DES_DECRYPT) ^ $xor;\r
-                    $xor = $block;\r
-                }\r
-                if ($this->continuousBuffer) {\r
-                    $this->decryptIV = $xor;\r
-                }\r
-                break;\r
-            case CRYPT_DES_MODE_CTR:\r
-                $xor = $this->decryptIV;\r
-                for ($i = 0; $i < strlen($ciphertext); $i+=8) {\r
-                    $block = substr($ciphertext, $i, 8);\r
-                    $key = $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);\r
-                    $plaintext.= $block ^ $key;\r
-                }\r
-                if ($this->continuousBuffer) {\r
-                    $this->decryptIV = $xor;\r
-                }\r
-        }\r
-\r
-        return $this->mode != CRYPT_DES_MODE_CTR ? $this->_unpad($plaintext) : $plaintext;\r
-    }\r
-\r
-    /**\r
-     * Treat consecutive "packets" as if they are a continuous buffer.\r
-     *\r
-     * Say you have a 16-byte plaintext $plaintext.  Using the default behavior, the two following code snippets\r
-     * will yield different outputs:\r
-     *\r
-     * <code>\r
-     *    echo $des->encrypt(substr($plaintext, 0, 8));\r
-     *    echo $des->encrypt(substr($plaintext, 8, 8));\r
-     * </code>\r
-     * <code>\r
-     *    echo $des->encrypt($plaintext);\r
-     * </code>\r
-     *\r
-     * The solution is to enable the continuous buffer.  Although this will resolve the above discrepancy, it creates\r
-     * another, as demonstrated with the following:\r
-     *\r
-     * <code>\r
-     *    $des->encrypt(substr($plaintext, 0, 8));\r
-     *    echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));\r
-     * </code>\r
-     * <code>\r
-     *    echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));\r
-     * </code>\r
-     *\r
-     * With the continuous buffer disabled, these would yield the same output.  With it enabled, they yield different\r
-     * outputs.  The reason is due to the fact that the initialization vector's change after every encryption /\r
-     * decryption round when the continuous buffer is enabled.  When it's disabled, they remain constant.\r
-     *\r
-     * Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each\r
-     * encryption / decryption round, whereas otherwise, it'd remain constant.  For this reason, it's recommended that\r
-     * continuous buffers not be used.  They do offer better security and are, in fact, sometimes required (SSH uses them),\r
-     * however, they are also less intuitive and more likely to cause you problems.\r
-     *\r
-     * @see Crypt_DES::disableContinuousBuffer()\r
-     * @access public\r
-     */\r
-    function enableContinuousBuffer()\r
-    {\r
-        $this->continuousBuffer = true;\r
-    }\r
-\r
-    /**\r
-     * Treat consecutive packets as if they are a discontinuous buffer.\r
-     *\r
-     * The default behavior.\r
-     *\r
-     * @see Crypt_DES::enableContinuousBuffer()\r
-     * @access public\r
-     */\r
-    function disableContinuousBuffer()\r
-    {\r
-        $this->continuousBuffer = false;\r
-        $this->encryptIV = $this->iv;\r
-        $this->decryptIV = $this->iv;\r
-    }\r
-\r
-    /**\r
-     * Pad "packets".\r
-     *\r
-     * DES works by encrypting eight bytes at a time.  If you ever need to encrypt or decrypt something that's not\r
-     * a multiple of eight, it becomes necessary to pad the input so that it's length is a multiple of eight.\r
-     *\r
-     * Padding is enabled by default.  Sometimes, however, it is undesirable to pad strings.  Such is the case in SSH1,\r
-     * where "packets" are padded with random bytes before being encrypted.  Unpad these packets and you risk stripping\r
-     * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is\r
-     * transmitted separately)\r
-     *\r
-     * @see Crypt_DES::disablePadding()\r
-     * @access public\r
-     */\r
-    function enablePadding()\r
-    {\r
-        $this->padding = true;\r
-    }\r
-\r
-    /**\r
-     * Do not pad packets.\r
-     *\r
-     * @see Crypt_DES::enablePadding()\r
-     * @access public\r
-     */\r
-    function disablePadding()\r
-    {\r
-        $this->padding = false;\r
-    }\r
-\r
-    /**\r
-     * Pads a string\r
-     *\r
-     * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize (8).\r
-     * 8 - (strlen($text) & 7) bytes are added, each of which is equal to chr(8 - (strlen($text) & 7)\r
-     *\r
-     * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless\r
-     * and padding will, hence forth, be enabled.\r
-     *\r
-     * @see Crypt_DES::_unpad()\r
-     * @access private\r
-     */\r
-    function _pad($text)\r
-    {\r
-        $length = strlen($text);\r
-\r
-        if (!$this->padding) {\r
-            if (($length & 7) == 0) {\r
-                return $text;\r
-            } else {\r
-                user_error("The plaintext's length ($length) is not a multiple of the block size (8)", E_USER_NOTICE);\r
-                $this->padding = true;\r
-            }\r
-        }\r
-\r
-        $pad = 8 - ($length & 7);\r
-        return str_pad($text, $length + $pad, chr($pad));\r
-    }\r
-\r
-    /**\r
-     * Unpads a string\r
-     *\r
-     * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong\r
-     * and false will be returned.\r
-     *\r
-     * @see Crypt_DES::_pad()\r
-     * @access private\r
-     */\r
-    function _unpad($text)\r
-    {\r
-        if (!$this->padding) {\r
-            return $text;\r
-        }\r
-\r
-        $length = ord($text[strlen($text) - 1]);\r
-\r
-        if (!$length || $length > 8) {\r
-            return false;\r
-        }\r
-\r
-        return substr($text, 0, -$length);\r
-    }\r
-\r
-    /**\r
-     * Encrypts or decrypts a 64-bit block\r
-     *\r
-     * $mode should be either CRYPT_DES_ENCRYPT or CRYPT_DES_DECRYPT.  See\r
-     * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general\r
-     * idea of what this function does.\r
-     *\r
-     * @access private\r
-     * @param String $block\r
-     * @param Integer $mode\r
-     * @return String\r
-     */\r
-    function _processBlock($block, $mode)\r
-    {\r
-        // s-boxes.  in the official DES docs, they're described as being matrices that\r
-        // one accesses by using the first and last bits to determine the row and the\r
-        // middle four bits to determine the column.  in this implementation, they've\r
-        // been converted to vectors\r
-        static $sbox = array(\r
-            array(\r
-                14,  0,  4, 15, 13,  7,  1,  4,  2, 14, 15,  2, 11, 13,  8,  1,\r
-                 3, 10 ,10,  6,  6, 12, 12, 11,  5,  9,  9,  5,  0,  3,  7,  8,\r
-                 4, 15,  1, 12, 14,  8,  8,  2, 13,  4,  6,  9,  2,  1, 11,  7,\r
-                15,  5, 12, 11,  9,  3,  7, 14,  3, 10, 10,  0,  5,  6,  0, 13\r
-            ),\r
-            array(\r
-                15,  3,  1, 13,  8,  4, 14,  7,  6, 15, 11,  2,  3,  8,  4, 14,\r
-                 9, 12,  7,  0,  2,  1, 13, 10, 12,  6,  0,  9,  5, 11, 10,  5,\r
-                 0, 13, 14,  8,  7, 10, 11,  1, 10,  3,  4, 15, 13,  4,  1,  2,\r
-                 5, 11,  8,  6, 12,  7,  6, 12,  9,  0,  3,  5,  2, 14, 15,  9\r
-            ),\r
-            array(\r
-                10, 13,  0,  7,  9,  0, 14,  9,  6,  3,  3,  4, 15,  6,  5, 10,\r
-                 1,  2, 13,  8, 12,  5,  7, 14, 11, 12,  4, 11,  2, 15,  8,  1,\r
-                13,  1,  6, 10,  4, 13,  9,  0,  8,  6, 15,  9,  3,  8,  0,  7,\r
-                11,  4,  1, 15,  2, 14, 12,  3,  5, 11, 10,  5, 14,  2,  7, 12\r
-            ),\r
-            array(\r
-                 7, 13, 13,  8, 14, 11,  3,  5,  0,  6,  6, 15,  9,  0, 10,  3,\r
-                 1,  4,  2,  7,  8,  2,  5, 12, 11,  1, 12, 10,  4, 14, 15,  9,\r
-                10,  3,  6, 15,  9,  0,  0,  6, 12, 10, 11,  1,  7, 13, 13,  8,\r
-                15,  9,  1,  4,  3,  5, 14, 11,  5, 12,  2,  7,  8,  2,  4, 14\r
-            ),\r
-            array(\r
-                 2, 14, 12, 11,  4,  2,  1, 12,  7,  4, 10,  7, 11, 13,  6,  1,\r
-                 8,  5,  5,  0,  3, 15, 15, 10, 13,  3,  0,  9, 14,  8,  9,  6,\r
-                 4, 11,  2,  8,  1, 12, 11,  7, 10,  1, 13, 14,  7,  2,  8, 13,\r
-                15,  6,  9, 15, 12,  0,  5,  9,  6, 10,  3,  4,  0,  5, 14,  3\r
-            ),\r
-            array(\r
-                12, 10,  1, 15, 10,  4, 15,  2,  9,  7,  2, 12,  6,  9,  8,  5,\r
-                 0,  6, 13,  1,  3, 13,  4, 14, 14,  0,  7, 11,  5,  3, 11,  8,\r
-                 9,  4, 14,  3, 15,  2,  5, 12,  2,  9,  8,  5, 12, 15,  3, 10,\r
-                 7, 11,  0, 14,  4,  1, 10,  7,  1,  6, 13,  0, 11,  8,  6, 13\r
-            ),\r
-            array(\r
-                 4, 13, 11,  0,  2, 11, 14,  7, 15,  4,  0,  9,  8,  1, 13, 10,\r
-                 3, 14, 12,  3,  9,  5,  7, 12,  5,  2, 10, 15,  6,  8,  1,  6,\r
-                 1,  6,  4, 11, 11, 13, 13,  8, 12,  1,  3,  4,  7, 10, 14,  7,\r
-                10,  9, 15,  5,  6,  0,  8, 15,  0, 14,  5,  2,  9,  3,  2, 12\r
-            ),\r
-            array(\r
-                13,  1,  2, 15,  8, 13,  4,  8,  6, 10, 15,  3, 11,  7,  1,  4,\r
-                10, 12,  9,  5,  3,  6, 14, 11,  5,  0,  0, 14, 12,  9,  7,  2,\r
-                 7,  2, 11,  1,  4, 14,  1,  7,  9,  4, 12, 10, 14,  8,  2, 13,\r
-                 0, 15,  6, 12, 10,  9, 13,  0, 15,  3,  3,  5,  5,  6,  8, 11\r
-            )\r
-        );\r
-\r
-        $keys = $this->keys;\r
-\r
-        $temp = unpack('Na/Nb', $block);\r
-        $block = array($temp['a'], $temp['b']);\r
-\r
-        // because php does arithmetic right shifts, if the most significant bits are set, right\r
-        // shifting those into the correct position will add 1's - not 0's.  this will intefere\r
-        // with the | operation unless a second & is done.  so we isolate these bits and left shift\r
-        // them into place.  we then & each block with 0x7FFFFFFF to prevennt 1's from being added\r
-        // for any other shifts.\r
-        $msb = array(\r
-            ($block[0] >> 31) & 1,\r
-            ($block[1] >> 31) & 1\r
-        );\r
-        $block[0] &= 0x7FFFFFFF;\r
-        $block[1] &= 0x7FFFFFFF;\r
-\r
-        // we isolate the appropriate bit in the appropriate integer and shift as appropriate.  in\r
-        // some cases, there are going to be multiple bits in the same integer that need to be shifted\r
-        // in the same way.  we combine those into one shift operation.\r
-        $block = array(\r
-            (($block[1] & 0x00000040) << 25) | (($block[1] & 0x00004000) << 16) |\r
-            (($block[1] & 0x00400001) <<  7) | (($block[1] & 0x40000100) >>  2) |\r
-            (($block[0] & 0x00000040) << 21) | (($block[0] & 0x00004000) << 12) |\r
-            (($block[0] & 0x00400001) <<  3) | (($block[0] & 0x40000100) >>  6) |\r
-            (($block[1] & 0x00000010) << 19) | (($block[1] & 0x00001000) << 10) |\r
-            (($block[1] & 0x00100000) <<  1) | (($block[1] & 0x10000000) >>  8) |\r
-            (($block[0] & 0x00000010) << 15) | (($block[0] & 0x00001000) <<  6) |\r
-            (($block[0] & 0x00100000) >>  3) | (($block[0] & 0x10000000) >> 12) |\r
-            (($block[1] & 0x00000004) << 13) | (($block[1] & 0x00000400) <<  4) |\r
-            (($block[1] & 0x00040000) >>  5) | (($block[1] & 0x04000000) >> 14) |\r
-            (($block[0] & 0x00000004) <<  9) | ( $block[0] & 0x00000400       ) |\r
-            (($block[0] & 0x00040000) >>  9) | (($block[0] & 0x04000000) >> 18) |\r
-            (($block[1] & 0x00010000) >> 11) | (($block[1] & 0x01000000) >> 20) |\r
-            (($block[0] & 0x00010000) >> 15) | (($block[0] & 0x01000000) >> 24)\r
-        ,\r
-            (($block[1] & 0x00000080) << 24) | (($block[1] & 0x00008000) << 15) |\r
-            (($block[1] & 0x00800002) <<  6) | (($block[0] & 0x00000080) << 20) |\r
-            (($block[0] & 0x00008000) << 11) | (($block[0] & 0x00800002) <<  2) |\r
-            (($block[1] & 0x00000020) << 18) | (($block[1] & 0x00002000) <<  9) |\r
-            ( $block[1] & 0x00200000       ) | (($block[1] & 0x20000000) >>  9) |\r
-            (($block[0] & 0x00000020) << 14) | (($block[0] & 0x00002000) <<  5) |\r
-            (($block[0] & 0x00200000) >>  4) | (($block[0] & 0x20000000) >> 13) |\r
-            (($block[1] & 0x00000008) << 12) | (($block[1] & 0x00000800) <<  3) |\r
-            (($block[1] & 0x00080000) >>  6) | (($block[1] & 0x08000000) >> 15) |\r
-            (($block[0] & 0x00000008) <<  8) | (($block[0] & 0x00000800) >>  1) |\r
-            (($block[0] & 0x00080000) >> 10) | (($block[0] & 0x08000000) >> 19) |\r
-            (($block[1] & 0x00000200) >>  3) | (($block[0] & 0x00000200) >>  7) |\r
-            (($block[1] & 0x00020000) >> 12) | (($block[1] & 0x02000000) >> 21) |\r
-            (($block[0] & 0x00020000) >> 16) | (($block[0] & 0x02000000) >> 25) |\r
-            ($msb[1] << 28) | ($msb[0] << 24)\r
-        );\r
-\r
-        for ($i = 0; $i < 16; $i++) {\r
-            // start of "the Feistel (F) function" - see the following URL:\r
-            // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png\r
-            $temp = (($sbox[0][((($block[1] >> 27) & 0x1F) | (($block[1] & 1) << 5)) ^ $keys[$mode][$i][0]]) << 28)\r
-                  | (($sbox[1][(($block[1] & 0x1F800000) >> 23) ^ $keys[$mode][$i][1]]) << 24)\r
-                  | (($sbox[2][(($block[1] & 0x01F80000) >> 19) ^ $keys[$mode][$i][2]]) << 20)\r
-                  | (($sbox[3][(($block[1] & 0x001F8000) >> 15) ^ $keys[$mode][$i][3]]) << 16)\r
-                  | (($sbox[4][(($block[1] & 0x0001F800) >> 11) ^ $keys[$mode][$i][4]]) << 12)\r
-                  | (($sbox[5][(($block[1] & 0x00001F80) >>  7) ^ $keys[$mode][$i][5]]) <<  8)\r
-                  | (($sbox[6][(($block[1] & 0x000001F8) >>  3) ^ $keys[$mode][$i][6]]) <<  4)\r
-                  | ( $sbox[7][((($block[1] & 0x1F) << 1) | (($block[1] >> 31) & 1)) ^ $keys[$mode][$i][7]]);\r
-\r
-            $msb = ($temp >> 31) & 1;\r
-            $temp &= 0x7FFFFFFF;\r
-            $newBlock = (($temp & 0x00010000) << 15) | (($temp & 0x02020120) <<  5)\r
-                      | (($temp & 0x00001800) << 17) | (($temp & 0x01000000) >> 10)\r
-                      | (($temp & 0x00000008) << 24) | (($temp & 0x00100000) <<  6)\r
-                      | (($temp & 0x00000010) << 21) | (($temp & 0x00008000) <<  9)\r
-                      | (($temp & 0x00000200) << 12) | (($temp & 0x10000000) >> 27)\r
-                      | (($temp & 0x00000040) << 14) | (($temp & 0x08000000) >>  8)\r
-                      | (($temp & 0x00004000) <<  4) | (($temp & 0x00000002) << 16)\r
-                      | (($temp & 0x00442000) >>  6) | (($temp & 0x40800000) >> 15)\r
-                      | (($temp & 0x00000001) << 11) | (($temp & 0x20000000) >> 20)\r
-                      | (($temp & 0x00080000) >> 13) | (($temp & 0x00000004) <<  3)\r
-                      | (($temp & 0x04000000) >> 22) | (($temp & 0x00000480) >>  7)\r
-                      | (($temp & 0x00200000) >> 19) | ($msb << 23);\r
-            // end of "the Feistel (F) function" - $newBlock is F's output\r
-\r
-            $temp = $block[1];\r
-            $block[1] = $block[0] ^ $newBlock;\r
-            $block[0] = $temp;\r
-        }\r
-\r
-        $msb = array(\r
-            ($block[0] >> 31) & 1,\r
-            ($block[1] >> 31) & 1\r
-        );\r
-        $block[0] &= 0x7FFFFFFF;\r
-        $block[1] &= 0x7FFFFFFF;\r
-\r
-        $block = array(\r
-            (($block[0] & 0x01000004) <<  7) | (($block[1] & 0x01000004) <<  6) |\r
-            (($block[0] & 0x00010000) << 13) | (($block[1] & 0x00010000) << 12) |\r
-            (($block[0] & 0x00000100) << 19) | (($block[1] & 0x00000100) << 18) |\r
-            (($block[0] & 0x00000001) << 25) | (($block[1] & 0x00000001) << 24) |\r
-            (($block[0] & 0x02000008) >>  2) | (($block[1] & 0x02000008) >>  3) |\r
-            (($block[0] & 0x00020000) <<  4) | (($block[1] & 0x00020000) <<  3) |\r
-            (($block[0] & 0x00000200) << 10) | (($block[1] & 0x00000200) <<  9) |\r
-            (($block[0] & 0x00000002) << 16) | (($block[1] & 0x00000002) << 15) |\r
-            (($block[0] & 0x04000000) >> 11) | (($block[1] & 0x04000000) >> 12) |\r
-            (($block[0] & 0x00040000) >>  5) | (($block[1] & 0x00040000) >>  6) |\r
-            (($block[0] & 0x00000400) <<  1) | ( $block[1] & 0x00000400       ) |\r
-            (($block[0] & 0x08000000) >> 20) | (($block[1] & 0x08000000) >> 21) |\r
-            (($block[0] & 0x00080000) >> 14) | (($block[1] & 0x00080000) >> 15) |\r
-            (($block[0] & 0x00000800) >>  8) | (($block[1] & 0x00000800) >>  9)\r
-        ,\r
-            (($block[0] & 0x10000040) <<  3) | (($block[1] & 0x10000040) <<  2) |\r
-            (($block[0] & 0x00100000) <<  9) | (($block[1] & 0x00100000) <<  8) |\r
-            (($block[0] & 0x00001000) << 15) | (($block[1] & 0x00001000) << 14) |\r
-            (($block[0] & 0x00000010) << 21) | (($block[1] & 0x00000010) << 20) |\r
-            (($block[0] & 0x20000080) >>  6) | (($block[1] & 0x20000080) >>  7) |\r
-            ( $block[0] & 0x00200000       ) | (($block[1] & 0x00200000) >>  1) |\r
-            (($block[0] & 0x00002000) <<  6) | (($block[1] & 0x00002000) <<  5) |\r
-            (($block[0] & 0x00000020) << 12) | (($block[1] & 0x00000020) << 11) |\r
-            (($block[0] & 0x40000000) >> 15) | (($block[1] & 0x40000000) >> 16) |\r
-            (($block[0] & 0x00400000) >>  9) | (($block[1] & 0x00400000) >> 10) |\r
-            (($block[0] & 0x00004000) >>  3) | (($block[1] & 0x00004000) >>  4) |\r
-            (($block[0] & 0x00800000) >> 18) | (($block[1] & 0x00800000) >> 19) |\r
-            (($block[0] & 0x00008000) >> 12) | (($block[1] & 0x00008000) >> 13) |\r
-            ($msb[0] <<  7) | ($msb[1] <<  6)\r
-        );\r
-\r
-        return pack('NN', $block[0], $block[1]);\r
-    }\r
-\r
-    /**\r
-     * Creates the key schedule.\r
-     *\r
-     * @access private\r
-     * @param String $key\r
-     * @return Array\r
-     */\r
-    function _prepareKey($key)\r
-    {\r
-        static $shifts = array( // number of key bits shifted per round\r
-            1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1\r
-        );\r
-\r
-        // pad the key and remove extra characters as appropriate.\r
-        $key = str_pad(substr($key, 0, 8), 8, chr(0));\r
-\r
-        $temp = unpack('Na/Nb', $key);\r
-        $key = array($temp['a'], $temp['b']);\r
-        $msb = array(\r
-            ($key[0] >> 31) & 1,\r
-            ($key[1] >> 31) & 1\r
-        );\r
-        $key[0] &= 0x7FFFFFFF;\r
-        $key[1] &= 0x7FFFFFFF;\r
-\r
-        $key = array(\r
-            (($key[1] & 0x00000002) << 26) | (($key[1] & 0x00000204) << 17) |\r
-            (($key[1] & 0x00020408) <<  8) | (($key[1] & 0x02040800) >>  1) |\r
-            (($key[0] & 0x00000002) << 22) | (($key[0] & 0x00000204) << 13) |\r
-            (($key[0] & 0x00020408) <<  4) | (($key[0] & 0x02040800) >>  5) |\r
-            (($key[1] & 0x04080000) >> 10) | (($key[0] & 0x04080000) >> 14) |\r
-            (($key[1] & 0x08000000) >> 19) | (($key[0] & 0x08000000) >> 23) |\r
-            (($key[0] & 0x00000010) >>  1) | (($key[0] & 0x00001000) >> 10) |\r
-            (($key[0] & 0x00100000) >> 19) | (($key[0] & 0x10000000) >> 28)\r
-        ,\r
-            (($key[1] & 0x00000080) << 20) | (($key[1] & 0x00008000) << 11) |\r
-            (($key[1] & 0x00800000) <<  2) | (($key[0] & 0x00000080) << 16) |\r
-            (($key[0] & 0x00008000) <<  7) | (($key[0] & 0x00800000) >>  2) |\r
-            (($key[1] & 0x00000040) << 13) | (($key[1] & 0x00004000) <<  4) |\r
-            (($key[1] & 0x00400000) >>  5) | (($key[1] & 0x40000000) >> 14) |\r
-            (($key[0] & 0x00000040) <<  9) | ( $key[0] & 0x00004000       ) |\r
-            (($key[0] & 0x00400000) >>  9) | (($key[0] & 0x40000000) >> 18) |\r
-            (($key[1] & 0x00000020) <<  6) | (($key[1] & 0x00002000) >>  3) |\r
-            (($key[1] & 0x00200000) >> 12) | (($key[1] & 0x20000000) >> 21) |\r
-            (($key[0] & 0x00000020) <<  2) | (($key[0] & 0x00002000) >>  7) |\r
-            (($key[0] & 0x00200000) >> 16) | (($key[0] & 0x20000000) >> 25) |\r
-            (($key[1] & 0x00000010) >>  1) | (($key[1] & 0x00001000) >> 10) |\r
-            (($key[1] & 0x00100000) >> 19) | (($key[1] & 0x10000000) >> 28) |\r
-            ($msb[1] << 24) | ($msb[0] << 20)\r
-        ); \r
-\r
-        $keys = array();\r
-        for ($i = 0; $i < 16; $i++) {\r
-            $key[0] <<= $shifts[$i];\r
-            $temp = ($key[0] & 0xF0000000) >> 28;\r
-            $key[0] = ($key[0] | $temp) & 0x0FFFFFFF;\r
-\r
-            $key[1] <<= $shifts[$i];\r
-            $temp = ($key[1] & 0xF0000000) >> 28;\r
-            $key[1] = ($key[1] | $temp) & 0x0FFFFFFF;\r
-\r
-            $temp = array(\r
-                (($key[1] & 0x00004000) >>  9) | (($key[1] & 0x00000800) >>  7) |\r
-                (($key[1] & 0x00020000) >> 14) | (($key[1] & 0x00000010) >>  2) |\r
-                (($key[1] & 0x08000000) >> 26) | (($key[1] & 0x00800000) >> 23)\r
-            ,\r
-                (($key[1] & 0x02400000) >> 20) | (($key[1] & 0x00000001) <<  4) |\r
-                (($key[1] & 0x00002000) >> 10) | (($key[1] & 0x00040000) >> 18) |\r
-                (($key[1] & 0x00000080) >>  6)\r
-            ,\r
-                ( $key[1] & 0x00000020       ) | (($key[1] & 0x00000200) >>  5) |\r
-                (($key[1] & 0x00010000) >> 13) | (($key[1] & 0x01000000) >> 22) |\r
-                (($key[1] & 0x00000004) >>  1) | (($key[1] & 0x00100000) >> 20)\r
-            ,\r
-                (($key[1] & 0x00001000) >>  7) | (($key[1] & 0x00200000) >> 17) |\r
-                (($key[1] & 0x00000002) <<  2) | (($key[1] & 0x00000100) >>  6) |\r
-                (($key[1] & 0x00008000) >> 14) | (($key[1] & 0x04000000) >> 26)\r
-            ,\r
-                (($key[0] & 0x00008000) >> 10) | ( $key[0] & 0x00000010       ) |\r
-                (($key[0] & 0x02000000) >> 22) | (($key[0] & 0x00080000) >> 17) |\r
-                (($key[0] & 0x00000200) >>  8) | (($key[0] & 0x00000002) >>  1)\r
-            ,\r
-                (($key[0] & 0x04000000) >> 21) | (($key[0] & 0x00010000) >> 12) |\r
-                (($key[0] & 0x00000020) >>  2) | (($key[0] & 0x00000800) >>  9) |\r
-                (($key[0] & 0x00800000) >> 22) | (($key[0] & 0x00000100) >>  8)\r
-            ,\r
-                (($key[0] & 0x00001000) >>  7) | (($key[0] & 0x00000088) >>  3) |\r
-                (($key[0] & 0x00020000) >> 14) | (($key[0] & 0x00000001) <<  2) |\r
-                (($key[0] & 0x00400000) >> 21)\r
-            ,\r
-                (($key[0] & 0x00000400) >>  5) | (($key[0] & 0x00004000) >> 10) |\r
-                (($key[0] & 0x00000040) >>  3) | (($key[0] & 0x00100000) >> 18) |\r
-                (($key[0] & 0x08000000) >> 26) | (($key[0] & 0x01000000) >> 24)\r
-            );\r
-\r
-            $keys[] = $temp;\r
-        }\r
-\r
-        $temp = array(\r
-            CRYPT_DES_ENCRYPT => $keys,\r
-            CRYPT_DES_DECRYPT => array_reverse($keys)\r
-        );\r
-\r
-        return $temp;\r
-    }\r
-}\r
-\r
-// vim: ts=4:sw=4:et:\r
-// vim6: fdl=1:
\ No newline at end of file
diff --git a/library/phpsec/Crypt/Hash.php b/library/phpsec/Crypt/Hash.php
deleted file mode 100644 (file)
index ef3a858..0000000
+++ /dev/null
@@ -1,816 +0,0 @@
-<?php\r
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */\r
-\r
-/**\r
- * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.\r
- *\r
- * Uses hash() or mhash() if available and an internal implementation, otherwise.  Currently supports the following:\r
- *\r
- * md2, md5, md5-96, sha1, sha1-96, sha256, sha384, and sha512\r
- *\r
- * If {@link Crypt_Hash::setKey() setKey()} is called, {@link Crypt_Hash::hash() hash()} will return the HMAC as opposed to\r
- * the hash.  If no valid algorithm is provided, sha1 will be used.\r
- *\r
- * PHP versions 4 and 5\r
- *\r
- * {@internal The variable names are the same as those in \r
- * {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}\r
- *\r
- * Here's a short example of how to use this library:\r
- * <code>\r
- * <?php\r
- *    include('Crypt/Hash.php');\r
- *\r
- *    $hash = new Crypt_Hash('sha1');\r
- *\r
- *    $hash->setKey('abcdefg');\r
- *\r
- *    echo base64_encode($hash->hash('abcdefg'));\r
- * ?>\r
- * </code>\r
- *\r
- * LICENSE: This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,\r
- * MA  02111-1307  USA\r
- *\r
- * @category   Crypt\r
- * @package    Crypt_Hash\r
- * @author     Jim Wigginton <terrafrost@php.net>\r
- * @copyright  MMVII Jim Wigginton\r
- * @license    http://www.gnu.org/licenses/lgpl.txt\r
- * @version    $Id: Hash.php,v 1.6 2009/11/23 23:37:07 terrafrost Exp $\r
- * @link       http://phpseclib.sourceforge.net\r
- */\r
-\r
-/**#@+\r
- * @access private\r
- * @see Crypt_Hash::Crypt_Hash()\r
- */\r
-/**\r
- * Toggles the internal implementation\r
- */\r
-define('CRYPT_HASH_MODE_INTERNAL', 1);\r
-/**\r
- * Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.\r
- */\r
-define('CRYPT_HASH_MODE_MHASH',    2);\r
-/**\r
- * Toggles the hash() implementation, which works on PHP 5.1.2+.\r
- */\r
-define('CRYPT_HASH_MODE_HASH',     3);\r
-/**#@-*/\r
-\r
-/**\r
- * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.\r
- *\r
- * @author  Jim Wigginton <terrafrost@php.net>\r
- * @version 0.1.0\r
- * @access  public\r
- * @package Crypt_Hash\r
- */\r
-class Crypt_Hash {\r
-    /**\r
-     * Byte-length of compression blocks / key (Internal HMAC)\r
-     *\r
-     * @see Crypt_Hash::setAlgorithm()\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $b;\r
-\r
-    /**\r
-     * Byte-length of hash output (Internal HMAC)\r
-     *\r
-     * @see Crypt_Hash::setHash()\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $l = false;\r
-\r
-    /**\r
-     * Hash Algorithm\r
-     *\r
-     * @see Crypt_Hash::setHash()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $hash;\r
-\r
-    /**\r
-     * Key\r
-     *\r
-     * @see Crypt_Hash::setKey()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $key = '';\r
-\r
-    /**\r
-     * Outer XOR (Internal HMAC)\r
-     *\r
-     * @see Crypt_Hash::setKey()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $opad;\r
-\r
-    /**\r
-     * Inner XOR (Internal HMAC)\r
-     *\r
-     * @see Crypt_Hash::setKey()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $ipad;\r
-\r
-    /**\r
-     * Default Constructor.\r
-     *\r
-     * @param optional String $hash\r
-     * @return Crypt_Hash\r
-     * @access public\r
-     */\r
-    function Crypt_Hash($hash = 'sha1')\r
-    {\r
-        if ( !defined('CRYPT_HASH_MODE') ) {\r
-            switch (true) {\r
-                case extension_loaded('hash'):\r
-                    define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_HASH);\r
-                    break;\r
-                case extension_loaded('mhash'):\r
-                    define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_MHASH);\r
-                    break;\r
-                default:\r
-                    define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_INTERNAL);\r
-            }\r
-        }\r
-\r
-        $this->setHash($hash);\r
-    }\r
-\r
-    /**\r
-     * Sets the key for HMACs\r
-     *\r
-     * Keys can be of any length.\r
-     *\r
-     * @access public\r
-     * @param String $key\r
-     */\r
-    function setKey($key)\r
-    {\r
-        $this->key = $key;\r
-    }\r
-\r
-    /**\r
-     * Sets the hash function.\r
-     *\r
-     * @access public\r
-     * @param String $hash\r
-     */\r
-    function setHash($hash)\r
-    {\r
-        switch ($hash) {\r
-            case 'md5-96':\r
-            case 'sha1-96':\r
-                $this->l = 12; // 96 / 8 = 12\r
-                break;\r
-            case 'md2':\r
-            case 'md5':\r
-                $this->l = 16;\r
-                break;\r
-            case 'sha1':\r
-                $this->l = 20;\r
-                break;\r
-            case 'sha256':\r
-                $this->l = 32;\r
-                break;\r
-            case 'sha384':\r
-                $this->l = 48;\r
-                break;\r
-            case 'sha512':\r
-                $this->l = 64;\r
-        }\r
-\r
-        switch ($hash) {\r
-            case 'md2':\r
-                $mode = CRYPT_HASH_MODE_INTERNAL;\r
-                break;\r
-            case 'sha384':\r
-            case 'sha512':\r
-                $mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_MHASH ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;\r
-                break;\r
-            default:\r
-                $mode = CRYPT_HASH_MODE;\r
-        }\r
-\r
-        switch ( $mode ) {\r
-            case CRYPT_HASH_MODE_MHASH:\r
-                switch ($hash) {\r
-                    case 'md5':\r
-                    case 'md5-96':\r
-                        $this->hash = MHASH_MD5;\r
-                        break;\r
-                    case 'sha256':\r
-                        $this->hash = MHASH_SHA256;\r
-                        break;\r
-                    case 'sha1':\r
-                    case 'sha1-96':\r
-                    default:\r
-                        $this->hash = MHASH_SHA1;\r
-                }\r
-                return;\r
-            case CRYPT_HASH_MODE_HASH:\r
-                switch ($hash) {\r
-                    case 'md5':\r
-                    case 'md5-96':\r
-                        $this->hash = 'md5';\r
-                        return;\r
-                    case 'sha256':\r
-                    case 'sha384':\r
-                    case 'sha512':\r
-                        $this->hash = $hash;\r
-                        return;\r
-                    case 'sha1':\r
-                    case 'sha1-96':\r
-                    default:\r
-                        $this->hash = 'sha1';\r
-                }\r
-                return;\r
-        }\r
-\r
-        switch ($hash) {\r
-            case 'md2':\r
-                 $this->b = 16;\r
-                 $this->hash = array($this, '_md2');\r
-                 break;\r
-            case 'md5':\r
-            case 'md5-96':\r
-                 $this->b = 64;\r
-                 $this->hash = array($this, '_md5');\r
-                 break;\r
-            case 'sha256':\r
-                 $this->b = 64;\r
-                 $this->hash = array($this, '_sha256');\r
-                 break;\r
-            case 'sha384':\r
-            case 'sha512':\r
-                 $this->b = 128;\r
-                 $this->hash = array($this, '_sha512');\r
-                 break;\r
-            case 'sha1':\r
-            case 'sha1-96':\r
-            default:\r
-                 $this->b = 64;\r
-                 $this->hash = array($this, '_sha1');\r
-        }\r
-\r
-        $this->ipad = str_repeat(chr(0x36), $this->b);\r
-        $this->opad = str_repeat(chr(0x5C), $this->b);\r
-    }\r
-\r
-    /**\r
-     * Compute the HMAC.\r
-     *\r
-     * @access public\r
-     * @param String $text\r
-     * @return String\r
-     */\r
-    function hash($text)\r
-    {\r
-        $mode = is_array($this->hash) ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;\r
-\r
-        if (!empty($this->key)) {\r
-            switch ( $mode ) {\r
-                case CRYPT_HASH_MODE_MHASH:\r
-                    $output = mhash($this->hash, $text, $this->key);\r
-                    break;\r
-                case CRYPT_HASH_MODE_HASH:\r
-                    $output = hash_hmac($this->hash, $text, $this->key, true);\r
-                    break;\r
-                case CRYPT_HASH_MODE_INTERNAL:\r
-                    /* "Applications that use keys longer than B bytes will first hash the key using H and then use the\r
-                        resultant L byte string as the actual key to HMAC."\r
-\r
-                        -- http://tools.ietf.org/html/rfc2104#section-2 */\r
-                    $key = strlen($this->key) > $this->b ? call_user_func($this->$hash, $this->key) : $this->key;\r
-\r
-                    $key    = str_pad($key, $this->b, chr(0));      // step 1\r
-                    $temp   = $this->ipad ^ $key;                   // step 2\r
-                    $temp  .= $text;                                // step 3\r
-                    $temp   = call_user_func($this->hash, $temp);   // step 4\r
-                    $output = $this->opad ^ $key;                   // step 5\r
-                    $output.= $temp;                                // step 6\r
-                    $output = call_user_func($this->hash, $output); // step 7\r
-            }\r
-        } else {\r
-            switch ( $mode ) {\r
-                case CRYPT_HASH_MODE_MHASH:\r
-                    $output = mhash($this->hash, $text);\r
-                    break;\r
-                case CRYPT_HASH_MODE_HASH:\r
-                    $output = hash($this->hash, $text, true);\r
-                    break;\r
-                case CRYPT_HASH_MODE_INTERNAL:\r
-                    $output = call_user_func($this->hash, $text);\r
-            }\r
-        }\r
-\r
-        return substr($output, 0, $this->l);\r
-    }\r
-\r
-    /**\r
-     * Returns the hash length (in bytes)\r
-     *\r
-     * @access private\r
-     * @return Integer\r
-     */\r
-    function getLength()\r
-    {\r
-        return $this->l;\r
-    }\r
-\r
-    /**\r
-     * Wrapper for MD5\r
-     *\r
-     * @access private\r
-     * @param String $text\r
-     */\r
-    function _md5($m)\r
-    {\r
-        return pack('H*', md5($m));\r
-    }\r
-\r
-    /**\r
-     * Wrapper for SHA1\r
-     *\r
-     * @access private\r
-     * @param String $text\r
-     */\r
-    function _sha1($m)\r
-    {\r
-        return pack('H*', sha1($m));\r
-    }\r
-\r
-    /**\r
-     * Pure-PHP implementation of MD2\r
-     *\r
-     * See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.\r
-     *\r
-     * @access private\r
-     * @param String $text\r
-     */\r
-    function _md2($m)\r
-    {\r
-        static $s = array(\r
-             41,  46,  67, 201, 162, 216, 124,   1,  61,  54,  84, 161, 236, 240, 6,\r
-             19,  98, 167,   5, 243, 192, 199, 115, 140, 152, 147,  43, 217, 188,\r
-             76, 130, 202,  30, 155,  87,  60, 253, 212, 224,  22, 103,  66, 111, 24,\r
-            138,  23, 229,  18, 190,  78, 196, 214, 218, 158, 222,  73, 160, 251,\r
-            245, 142, 187,  47, 238, 122, 169, 104, 121, 145,  21, 178,   7,  63,\r
-            148, 194,  16, 137,  11,  34,  95,  33, 128, 127,  93, 154,  90, 144, 50,\r
-             39,  53,  62, 204, 231, 191, 247, 151,   3, 255,  25,  48, 179,  72, 165,\r
-            181, 209, 215,  94, 146,  42, 172,  86, 170, 198,  79, 184,  56, 210,\r
-            150, 164, 125, 182, 118, 252, 107, 226, 156, 116,   4, 241,  69, 157,\r
-            112,  89, 100, 113, 135,  32, 134,  91, 207, 101, 230,  45, 168,   2, 27,\r
-             96,  37, 173, 174, 176, 185, 246,  28,  70,  97, 105,  52,  64, 126, 15,\r
-             85,  71, 163,  35, 221,  81, 175,  58, 195,  92, 249, 206, 186, 197,\r
-            234,  38,  44,  83,  13, 110, 133,  40, 132,   9, 211, 223, 205, 244, 65,\r
-            129,  77,  82, 106, 220,  55, 200, 108, 193, 171, 250,  36, 225, 123,\r
-              8,  12, 189, 177,  74, 120, 136, 149, 139, 227,  99, 232, 109, 233,\r
-            203, 213, 254,  59,   0,  29,  57, 242, 239, 183,  14, 102,  88, 208, 228,\r
-            166, 119, 114, 248, 235, 117,  75,  10,  49,  68,  80, 180, 143, 237,\r
-             31,  26, 219, 153, 141,  51, 159,  17, 131, 20\r
-        );\r
-\r
-        // Step 1. Append Padding Bytes\r
-        $pad = 16 - (strlen($m) & 0xF);\r
-        $m.= str_repeat(chr($pad), $pad);\r
-\r
-        $length = strlen($m);\r
-\r
-        // Step 2. Append Checksum\r
-        $c = str_repeat(chr(0), 16);\r
-        $l = chr(0);\r
-        for ($i = 0; $i < $length; $i+= 16) {\r
-            for ($j = 0; $j < 16; $j++) {\r
-                $c[$j] = chr($s[ord($m[$i + $j] ^ $l)]);\r
-                $l = $c[$j];\r
-            }\r
-        }\r
-        $m.= $c;\r
-\r
-        $length+= 16;\r
-\r
-        // Step 3. Initialize MD Buffer\r
-        $x = str_repeat(chr(0), 48);\r
-\r
-        // Step 4. Process Message in 16-Byte Blocks\r
-        for ($i = 0; $i < $length; $i+= 16) {\r
-            for ($j = 0; $j < 16; $j++) {\r
-                $x[$j + 16] = $m[$i + $j];\r
-                $x[$j + 32] = $x[$j + 16] ^ $x[$j];\r
-            }\r
-            $t = chr(0);\r
-            for ($j = 0; $j < 18; $j++) {\r
-                for ($k = 0; $k < 48; $k++) {\r
-                    $x[$k] = $t = $x[$k] ^ chr($s[ord($t)]);\r
-                    //$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]);\r
-                }\r
-                $t = chr(ord($t) + $j);\r
-            }\r
-        }\r
-\r
-        // Step 5. Output\r
-        return substr($x, 0, 16);\r
-    }\r
-\r
-    /**\r
-     * Pure-PHP implementation of SHA256\r
-     *\r
-     * See {@link http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode SHA-256 (a SHA-2 variant) pseudocode - Wikipedia}.\r
-     *\r
-     * @access private\r
-     * @param String $text\r
-     */\r
-    function _sha256($m)\r
-    {\r
-        if (extension_loaded('suhosin')) {\r
-            return pack('H*', sha256($m));\r
-        }\r
-\r
-        // Initialize variables\r
-        $hash = array(\r
-            0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19\r
-        );\r
-        // Initialize table of round constants\r
-        // (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)\r
-        static $k = array(\r
-            0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\r
-            0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\r
-            0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\r
-            0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\r
-            0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\r
-            0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\r
-            0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\r
-            0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\r
-        );\r
-\r
-        // Pre-processing\r
-        $length = strlen($m);\r
-        // to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64\r
-        $m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F));\r
-        $m[$length] = chr(0x80);\r
-        // we don't support hashing strings 512MB long\r
-        $m.= pack('N2', 0, $length << 3);\r
-\r
-        // Process the message in successive 512-bit chunks\r
-        $chunks = str_split($m, 64);\r
-        foreach ($chunks as $chunk) {\r
-            $w = array();\r
-            for ($i = 0; $i < 16; $i++) {\r
-                extract(unpack('Ntemp', $this->_string_shift($chunk, 4)));\r
-                $w[] = $temp;\r
-            }\r
-\r
-            // Extend the sixteen 32-bit words into sixty-four 32-bit words\r
-            for ($i = 16; $i < 64; $i++) {\r
-                $s0 = $this->_rightRotate($w[$i - 15],  7) ^\r
-                      $this->_rightRotate($w[$i - 15], 18) ^\r
-                      $this->_rightShift( $w[$i - 15],  3);\r
-                $s1 = $this->_rightRotate($w[$i - 2], 17) ^\r
-                      $this->_rightRotate($w[$i - 2], 19) ^\r
-                      $this->_rightShift( $w[$i - 2], 10);\r
-                $w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1);\r
-\r
-            }\r
-\r
-            // Initialize hash value for this chunk\r
-            list($a, $b, $c, $d, $e, $f, $g, $h) = $hash;\r
-\r
-            // Main loop\r
-            for ($i = 0; $i < 64; $i++) {\r
-                $s0 = $this->_rightRotate($a,  2) ^\r
-                      $this->_rightRotate($a, 13) ^\r
-                      $this->_rightRotate($a, 22);\r
-                $maj = ($a & $b) ^\r
-                       ($a & $c) ^\r
-                       ($b & $c);\r
-                $t2 = $this->_add($s0, $maj);\r
-\r
-                $s1 = $this->_rightRotate($e,  6) ^\r
-                      $this->_rightRotate($e, 11) ^\r
-                      $this->_rightRotate($e, 25);\r
-                $ch = ($e & $f) ^\r
-                      ($this->_not($e) & $g);\r
-                $t1 = $this->_add($h, $s1, $ch, $k[$i], $w[$i]);\r
-\r
-                $h = $g;\r
-                $g = $f;\r
-                $f = $e;\r
-                $e = $this->_add($d, $t1);\r
-                $d = $c;\r
-                $c = $b;\r
-                $b = $a;\r
-                $a = $this->_add($t1, $t2);\r
-            }\r
-\r
-            // Add this chunk's hash to result so far\r
-            $hash = array(\r
-                $this->_add($hash[0], $a),\r
-                $this->_add($hash[1], $b),\r
-                $this->_add($hash[2], $c),\r
-                $this->_add($hash[3], $d),\r
-                $this->_add($hash[4], $e),\r
-                $this->_add($hash[5], $f),\r
-                $this->_add($hash[6], $g),\r
-                $this->_add($hash[7], $h)\r
-            );\r
-        }\r
-\r
-        // Produce the final hash value (big-endian)\r
-        return pack('N8', $hash[0], $hash[1], $hash[2], $hash[3], $hash[4], $hash[5], $hash[6], $hash[7]);\r
-    }\r
-\r
-    /**\r
-     * Pure-PHP implementation of SHA384 and SHA512\r
-     *\r
-     * @access private\r
-     * @param String $text\r
-     */\r
-    function _sha512($m)\r
-    {\r
-        if (!class_exists('Math_BigInteger')) {\r
-            require_once('Math/BigInteger.php');\r
-        }\r
-\r
-        static $init384, $init512, $k;\r
-\r
-        if (!isset($k)) {\r
-            // Initialize variables\r
-            $init384 = array( // initial values for SHA384\r
-                'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939', \r
-                '67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4'\r
-            );\r
-            $init512 = array( // initial values for SHA512\r
-                '6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1', \r
-                '510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179'\r
-            );\r
-\r
-            for ($i = 0; $i < 8; $i++) {\r
-                $init384[$i] = new Math_BigInteger($init384[$i], 16);\r
-                $init384[$i]->setPrecision(64);\r
-                $init512[$i] = new Math_BigInteger($init512[$i], 16);\r
-                $init512[$i]->setPrecision(64);\r
-            }\r
-\r
-            // Initialize table of round constants\r
-            // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409)\r
-            $k = array(\r
-                '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc',\r
-                '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118',\r
-                'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2',\r
-                '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694',\r
-                'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65',\r
-                '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5',\r
-                '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4',\r
-                'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70',\r
-                '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df',\r
-                '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b',\r
-                'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30',\r
-                'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8',\r
-                '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8',\r
-                '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3',\r
-                '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec',\r
-                '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b',\r
-                'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178',\r
-                '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b',\r
-                '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c',\r
-                '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817'\r
-            );\r
-\r
-            for ($i = 0; $i < 80; $i++) {\r
-                $k[$i] = new Math_BigInteger($k[$i], 16);\r
-            }\r
-        }\r
-\r
-        $hash = $this->l == 48 ? $init384 : $init512;\r
-\r
-        // Pre-processing\r
-        $length = strlen($m);\r
-        // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128\r
-        $m.= str_repeat(chr(0), 128 - (($length + 16) & 0x7F));\r
-        $m[$length] = chr(0x80);\r
-        // we don't support hashing strings 512MB long\r
-        $m.= pack('N4', 0, 0, 0, $length << 3);\r
-\r
-        // Process the message in successive 1024-bit chunks\r
-        $chunks = str_split($m, 128);\r
-        foreach ($chunks as $chunk) {\r
-            $w = array();\r
-            for ($i = 0; $i < 16; $i++) {\r
-                $temp = new Math_BigInteger($this->_string_shift($chunk, 8), 256);\r
-                $temp->setPrecision(64);\r
-                $w[] = $temp;\r
-            }\r
-\r
-            // Extend the sixteen 32-bit words into eighty 32-bit words\r
-            for ($i = 16; $i < 80; $i++) {\r
-                $temp = array(\r
-                          $w[$i - 15]->bitwise_rightRotate(1),\r
-                          $w[$i - 15]->bitwise_rightRotate(8),\r
-                          $w[$i - 15]->bitwise_rightShift(7)\r
-                );\r
-                $s0 = $temp[0]->bitwise_xor($temp[1]);\r
-                $s0 = $s0->bitwise_xor($temp[2]);\r
-                $temp = array(\r
-                          $w[$i - 2]->bitwise_rightRotate(19),\r
-                          $w[$i - 2]->bitwise_rightRotate(61),\r
-                          $w[$i - 2]->bitwise_rightShift(6)\r
-                );\r
-                $s1 = $temp[0]->bitwise_xor($temp[1]);\r
-                $s1 = $s1->bitwise_xor($temp[2]);\r
-                $w[$i] = $w[$i - 16]->copy();\r
-                $w[$i] = $w[$i]->add($s0);\r
-                $w[$i] = $w[$i]->add($w[$i - 7]);\r
-                $w[$i] = $w[$i]->add($s1);\r
-            }\r
-\r
-            // Initialize hash value for this chunk\r
-            $a = $hash[0]->copy();\r
-            $b = $hash[1]->copy();\r
-            $c = $hash[2]->copy();\r
-            $d = $hash[3]->copy();\r
-            $e = $hash[4]->copy();\r
-            $f = $hash[5]->copy();\r
-            $g = $hash[6]->copy();\r
-            $h = $hash[7]->copy();\r
-\r
-            // Main loop\r
-            for ($i = 0; $i < 80; $i++) {\r
-                $temp = array(\r
-                    $a->bitwise_rightRotate(28),\r
-                    $a->bitwise_rightRotate(34),\r
-                    $a->bitwise_rightRotate(39)\r
-                );\r
-                $s0 = $temp[0]->bitwise_xor($temp[1]);\r
-                $s0 = $s0->bitwise_xor($temp[2]);\r
-                $temp = array(\r
-                    $a->bitwise_and($b),\r
-                    $a->bitwise_and($c),\r
-                    $b->bitwise_and($c)\r
-                );\r
-                $maj = $temp[0]->bitwise_xor($temp[1]);\r
-                $maj = $maj->bitwise_xor($temp[2]);\r
-                $t2 = $s0->add($maj);\r
-\r
-                $temp = array(\r
-                    $e->bitwise_rightRotate(14),\r
-                    $e->bitwise_rightRotate(18),\r
-                    $e->bitwise_rightRotate(41)\r
-                );\r
-                $s1 = $temp[0]->bitwise_xor($temp[1]);\r
-                $s1 = $s1->bitwise_xor($temp[2]);\r
-                $temp = array(\r
-                    $e->bitwise_and($f),\r
-                    $g->bitwise_and($e->bitwise_not())\r
-                );\r
-                $ch = $temp[0]->bitwise_xor($temp[1]);\r
-                $t1 = $h->add($s1);\r
-                $t1 = $t1->add($ch);\r
-                $t1 = $t1->add($k[$i]);\r
-                $t1 = $t1->add($w[$i]);\r
-\r
-                $h = $g->copy();\r
-                $g = $f->copy();\r
-                $f = $e->copy();\r
-                $e = $d->add($t1);\r
-                $d = $c->copy();\r
-                $c = $b->copy();\r
-                $b = $a->copy();\r
-                $a = $t1->add($t2);\r
-            }\r
-\r
-            // Add this chunk's hash to result so far\r
-            $hash = array(\r
-                $hash[0]->add($a),\r
-                $hash[1]->add($b),\r
-                $hash[2]->add($c),\r
-                $hash[3]->add($d),\r
-                $hash[4]->add($e),\r
-                $hash[5]->add($f),\r
-                $hash[6]->add($g),\r
-                $hash[7]->add($h)\r
-            );\r
-        }\r
-\r
-        // Produce the final hash value (big-endian)\r
-        // (Crypt_Hash::hash() trims the output for hashes but not for HMACs.  as such, we trim the output here)\r
-        $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .\r
-                $hash[4]->toBytes() . $hash[5]->toBytes();\r
-        if ($this->l != 48) {\r
-            $temp.= $hash[6]->toBytes() . $hash[7]->toBytes();\r
-        }\r
-\r
-        return $temp;\r
-    }\r
-\r
-    /**\r
-     * Right Rotate\r
-     *\r
-     * @access private\r
-     * @param Integer $int\r
-     * @param Integer $amt\r
-     * @see _sha256()\r
-     * @return Integer\r
-     */\r
-    function _rightRotate($int, $amt)\r
-    {\r
-        $invamt = 32 - $amt;\r
-        $mask = (1 << $invamt) - 1;\r
-        return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask);\r
-    }\r
-\r
-    /**\r
-     * Right Shift\r
-     *\r
-     * @access private\r
-     * @param Integer $int\r
-     * @param Integer $amt\r
-     * @see _sha256()\r
-     * @return Integer\r
-     */\r
-    function _rightShift($int, $amt)\r
-    {\r
-        $mask = (1 << (32 - $amt)) - 1;\r
-        return ($int >> $amt) & $mask;\r
-    }\r
-\r
-    /**\r
-     * Not\r
-     *\r
-     * @access private\r
-     * @param Integer $int\r
-     * @see _sha256()\r
-     * @return Integer\r
-     */\r
-    function _not($int)\r
-    {\r
-        return ~$int & 0xFFFFFFFF;\r
-    }\r
-\r
-    /**\r
-     * Add\r
-     *\r
-     * _sha256() adds multiple unsigned 32-bit integers.  Since PHP doesn't support unsigned integers and since the\r
-     * possibility of overflow exists, care has to be taken.  Math_BigInteger() could be used but this should be faster.\r
-     *\r
-     * @param String $string\r
-     * @param optional Integer $index\r
-     * @return String\r
-     * @see _sha256()\r
-     * @access private\r
-     */\r
-    function _add()\r
-    {\r
-        static $mod;\r
-        if (!isset($mod)) {\r
-            $mod = pow(2, 32);\r
-        }\r
-\r
-        $result = 0;\r
-        $arguments = func_get_args();\r
-        foreach ($arguments as $argument) {\r
-            $result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;\r
-        }\r
-\r
-        return fmod($result, $mod);\r
-    }\r
-\r
-    /**\r
-     * String Shift\r
-     *\r
-     * Inspired by array_shift\r
-     *\r
-     * @param String $string\r
-     * @param optional Integer $index\r
-     * @return String\r
-     * @access private\r
-     */\r
-    function _string_shift(&$string, $index = 1)\r
-    {\r
-        $substr = substr($string, 0, $index);\r
-        $string = substr($string, $index);\r
-        return $substr;\r
-    }\r
-}
\ No newline at end of file
diff --git a/library/phpsec/Crypt/RC4.php b/library/phpsec/Crypt/RC4.php
deleted file mode 100644 (file)
index 6f82b24..0000000
+++ /dev/null
@@ -1,493 +0,0 @@
-<?php\r
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */\r
-\r
-/**\r
- * Pure-PHP implementation of RC4.\r
- *\r
- * Uses mcrypt, if available, and an internal implementation, otherwise.\r
- *\r
- * PHP versions 4 and 5\r
- *\r
- * Useful resources are as follows:\r
- *\r
- *  - {@link http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt ARCFOUR Algorithm}\r
- *  - {@link http://en.wikipedia.org/wiki/RC4 - Wikipedia: RC4}\r
- *\r
- * RC4 is also known as ARCFOUR or ARC4.  The reason is elaborated upon at Wikipedia.  This class is named RC4 and not\r
- * ARCFOUR or ARC4 because RC4 is how it is refered to in the SSH1 specification.\r
- *\r
- * Here's a short example of how to use this library:\r
- * <code>\r
- * <?php\r
- *    include('Crypt/RC4.php');\r
- *\r
- *    $rc4 = new Crypt_RC4();\r
- *\r
- *    $rc4->setKey('abcdefgh');\r
- *\r
- *    $size = 10 * 1024;\r
- *    $plaintext = '';\r
- *    for ($i = 0; $i < $size; $i++) {\r
- *        $plaintext.= 'a';\r
- *    }\r
- *\r
- *    echo $rc4->decrypt($rc4->encrypt($plaintext));\r
- * ?>\r
- * </code>\r
- *\r
- * LICENSE: This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,\r
- * MA  02111-1307  USA\r
- *\r
- * @category   Crypt\r
- * @package    Crypt_RC4\r
- * @author     Jim Wigginton <terrafrost@php.net>\r
- * @copyright  MMVII Jim Wigginton\r
- * @license    http://www.gnu.org/licenses/lgpl.txt\r
- * @version    $Id: RC4.php,v 1.8 2009/06/09 04:00:38 terrafrost Exp $\r
- * @link       http://phpseclib.sourceforge.net\r
- */\r
-\r
-/**#@+\r
- * @access private\r
- * @see Crypt_RC4::Crypt_RC4()\r
- */\r
-/**\r
- * Toggles the internal implementation\r
- */\r
-define('CRYPT_RC4_MODE_INTERNAL', 1);\r
-/**\r
- * Toggles the mcrypt implementation\r
- */\r
-define('CRYPT_RC4_MODE_MCRYPT', 2);\r
-/**#@-*/\r
-\r
-/**#@+\r
- * @access private\r
- * @see Crypt_RC4::_crypt()\r
- */\r
-define('CRYPT_RC4_ENCRYPT', 0);\r
-define('CRYPT_RC4_DECRYPT', 1);\r
-/**#@-*/\r
-\r
-/**\r
- * Pure-PHP implementation of RC4.\r
- *\r
- * @author  Jim Wigginton <terrafrost@php.net>\r
- * @version 0.1.0\r
- * @access  public\r
- * @package Crypt_RC4\r
- */\r
-class Crypt_RC4 {\r
-    /**\r
-     * The Key\r
-     *\r
-     * @see Crypt_RC4::setKey()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $key = "\0";\r
-\r
-    /**\r
-     * The Key Stream for encryption\r
-     *\r
-     * If CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT, this will be equal to the mcrypt object\r
-     *\r
-     * @see Crypt_RC4::setKey()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $encryptStream = false;\r
-\r
-    /**\r
-     * The Key Stream for decryption\r
-     *\r
-     * If CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT, this will be equal to the mcrypt object\r
-     *\r
-     * @see Crypt_RC4::setKey()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $decryptStream = false;\r
-\r
-    /**\r
-     * The $i and $j indexes for encryption\r
-     *\r
-     * @see Crypt_RC4::_crypt()\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $encryptIndex = 0;\r
-\r
-    /**\r
-     * The $i and $j indexes for decryption\r
-     *\r
-     * @see Crypt_RC4::_crypt()\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $decryptIndex = 0;\r
-\r
-    /**\r
-     * MCrypt parameters\r
-     *\r
-     * @see Crypt_RC4::setMCrypt()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $mcrypt = array('', '');\r
-\r
-    /**\r
-     * The Encryption Algorithm\r
-     *\r
-     * Only used if CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT.  Only possible values are MCRYPT_RC4 or MCRYPT_ARCFOUR.\r
-     *\r
-     * @see Crypt_RC4::Crypt_RC4()\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $mode;\r
-\r
-    /**\r
-     * Default Constructor.\r
-     *\r
-     * Determines whether or not the mcrypt extension should be used.\r
-     *\r
-     * @param optional Integer $mode\r
-     * @return Crypt_RC4\r
-     * @access public\r
-     */\r
-    function Crypt_RC4()\r
-    {\r
-        if ( !defined('CRYPT_RC4_MODE') ) {\r
-            switch (true) {\r
-                case extension_loaded('mcrypt') && (defined('MCRYPT_ARCFOUR') || defined('MCRYPT_RC4')):\r
-                    // i'd check to see if rc4 was supported, by doing in_array('arcfour', mcrypt_list_algorithms('')),\r
-                    // but since that can be changed after the object has been created, there doesn't seem to be\r
-                    // a lot of point...\r
-                    define('CRYPT_RC4_MODE', CRYPT_RC4_MODE_MCRYPT);\r
-                    break;\r
-                default:\r
-                    define('CRYPT_RC4_MODE', CRYPT_RC4_MODE_INTERNAL);\r
-            }\r
-        }\r
-\r
-        switch ( CRYPT_RC4_MODE ) {\r
-            case CRYPT_RC4_MODE_MCRYPT:\r
-                switch (true) {\r
-                    case defined('MCRYPT_ARCFOUR'):\r
-                        $this->mode = MCRYPT_ARCFOUR;\r
-                        break;\r
-                    case defined('MCRYPT_RC4');\r
-                        $this->mode = MCRYPT_RC4;\r
-                }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Sets the key.\r
-     *\r
-     * Keys can be between 1 and 256 bytes long.  If they are longer then 256 bytes, the first 256 bytes will\r
-     * be used.  If no key is explicitly set, it'll be assumed to be a single null byte.\r
-     *\r
-     * @access public\r
-     * @param String $key\r
-     */\r
-    function setKey($key)\r
-    {\r
-        $this->key = $key;\r
-\r
-        if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {\r
-            return;\r
-        }\r
-\r
-        $keyLength = strlen($key);\r
-        $keyStream = array();\r
-        for ($i = 0; $i < 256; $i++) {\r
-            $keyStream[$i] = $i;\r
-        }\r
-        $j = 0;\r
-        for ($i = 0; $i < 256; $i++) {\r
-            $j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255;\r
-            $temp = $keyStream[$i];\r
-            $keyStream[$i] = $keyStream[$j];\r
-            $keyStream[$j] = $temp;\r
-        }\r
-\r
-        $this->encryptIndex = $this->decryptIndex = array(0, 0);\r
-        $this->encryptStream = $this->decryptStream = $keyStream;\r
-    }\r
-\r
-    /**\r
-     * Dummy function.\r
-     *\r
-     * Some protocols, such as WEP, prepend an "initialization vector" to the key, effectively creating a new key [1].\r
-     * If you need to use an initialization vector in this manner, feel free to prepend it to the key, yourself, before\r
-     * calling setKey().\r
-     *\r
-     * [1] WEP's initialization vectors (IV's) are used in a somewhat insecure way.  Since, in that protocol,\r
-     * the IV's are relatively easy to predict, an attack described by\r
-     * {@link http://www.drizzle.com/~aboba/IEEE/rc4_ksaproc.pdf Scott Fluhrer, Itsik Mantin, and Adi Shamir}\r
-     * can be used to quickly guess at the rest of the key.  The following links elaborate:\r
-     *\r
-     * {@link http://www.rsa.com/rsalabs/node.asp?id=2009 http://www.rsa.com/rsalabs/node.asp?id=2009}\r
-     * {@link http://en.wikipedia.org/wiki/Related_key_attack http://en.wikipedia.org/wiki/Related_key_attack}\r
-     *\r
-     * @param String $iv\r
-     * @see Crypt_RC4::setKey()\r
-     * @access public\r
-     */\r
-    function setIV($iv)\r
-    {\r
-    }\r
-\r
-    /**\r
-     * Sets MCrypt parameters. (optional)\r
-     *\r
-     * If MCrypt is being used, empty strings will be used, unless otherwise specified.\r
-     *\r
-     * @link http://php.net/function.mcrypt-module-open#function.mcrypt-module-open\r
-     * @access public\r
-     * @param optional Integer $algorithm_directory\r
-     * @param optional Integer $mode_directory\r
-     */\r
-    function setMCrypt($algorithm_directory = '', $mode_directory = '')\r
-    {\r
-        if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {\r
-            $this->mcrypt = array($algorithm_directory, $mode_directory);\r
-            $this->_closeMCrypt();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Encrypts a message.\r
-     *\r
-     * @see Crypt_RC4::_crypt()\r
-     * @access public\r
-     * @param String $plaintext\r
-     */\r
-    function encrypt($plaintext)\r
-    {\r
-        return $this->_crypt($plaintext, CRYPT_RC4_ENCRYPT);\r
-    }\r
-\r
-    /**\r
-     * Decrypts a message.\r
-     *\r
-     * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)).\r
-     * Atleast if the continuous buffer is disabled.\r
-     *\r
-     * @see Crypt_RC4::_crypt()\r
-     * @access public\r
-     * @param String $ciphertext\r
-     */\r
-    function decrypt($ciphertext)\r
-    {\r
-        return $this->_crypt($ciphertext, CRYPT_RC4_DECRYPT);\r
-    }\r
-\r
-    /**\r
-     * Encrypts or decrypts a message.\r
-     *\r
-     * @see Crypt_RC4::encrypt()\r
-     * @see Crypt_RC4::decrypt()\r
-     * @access private\r
-     * @param String $text\r
-     * @param Integer $mode\r
-     */\r
-    function _crypt($text, $mode)\r
-    {\r
-        if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {\r
-            $keyStream = $mode == CRYPT_RC4_ENCRYPT ? 'encryptStream' : 'decryptStream';\r
-\r
-            if ($this->$keyStream === false) {\r
-                $this->$keyStream = mcrypt_module_open($this->mode, $this->mcrypt[0], MCRYPT_MODE_STREAM, $this->mcrypt[1]);\r
-                mcrypt_generic_init($this->$keyStream, $this->key, '');\r
-            } else if (!$this->continuousBuffer) {\r
-                mcrypt_generic_init($this->$keyStream, $this->key, '');\r
-            }\r
-            $newText = mcrypt_generic($this->$keyStream, $text);\r
-            if (!$this->continuousBuffer) {\r
-                mcrypt_generic_deinit($this->$keyStream);\r
-            }\r
-\r
-            return $newText;\r
-        }\r
-\r
-        if ($this->encryptStream === false) {\r
-            $this->setKey($this->key);\r
-        }\r
-\r
-        switch ($mode) {\r
-            case CRYPT_RC4_ENCRYPT:\r
-                $keyStream = $this->encryptStream;\r
-                list($i, $j) = $this->encryptIndex;\r
-                break;\r
-            case CRYPT_RC4_DECRYPT:\r
-                $keyStream = $this->decryptStream;\r
-                list($i, $j) = $this->decryptIndex;\r
-        }\r
-\r
-        $newText = '';\r
-        for ($k = 0; $k < strlen($text); $k++) {\r
-            $i = ($i + 1) & 255;\r
-            $j = ($j + $keyStream[$i]) & 255;\r
-            $temp = $keyStream[$i];\r
-            $keyStream[$i] = $keyStream[$j];\r
-            $keyStream[$j] = $temp;\r
-            $temp = $keyStream[($keyStream[$i] + $keyStream[$j]) & 255];\r
-            $newText.= chr(ord($text[$k]) ^ $temp);\r
-        }\r
-\r
-        if ($this->continuousBuffer) {\r
-            switch ($mode) {\r
-                case CRYPT_RC4_ENCRYPT:\r
-                    $this->encryptStream = $keyStream;\r
-                    $this->encryptIndex = array($i, $j);\r
-                    break;\r
-                case CRYPT_RC4_DECRYPT:\r
-                    $this->decryptStream = $keyStream;\r
-                    $this->decryptIndex = array($i, $j);\r
-            }\r
-        }\r
-\r
-        return $newText;\r
-    }\r
-\r
-    /**\r
-     * Treat consecutive "packets" as if they are a continuous buffer.\r
-     *\r
-     * Say you have a 16-byte plaintext $plaintext.  Using the default behavior, the two following code snippets\r
-     * will yield different outputs:\r
-     *\r
-     * <code>\r
-     *    echo $rc4->encrypt(substr($plaintext, 0, 8));\r
-     *    echo $rc4->encrypt(substr($plaintext, 8, 8));\r
-     * </code>\r
-     * <code>\r
-     *    echo $rc4->encrypt($plaintext);\r
-     * </code>\r
-     *\r
-     * The solution is to enable the continuous buffer.  Although this will resolve the above discrepancy, it creates\r
-     * another, as demonstrated with the following:\r
-     *\r
-     * <code>\r
-     *    $rc4->encrypt(substr($plaintext, 0, 8));\r
-     *    echo $rc4->decrypt($des->encrypt(substr($plaintext, 8, 8)));\r
-     * </code>\r
-     * <code>\r
-     *    echo $rc4->decrypt($des->encrypt(substr($plaintext, 8, 8)));\r
-     * </code>\r
-     *\r
-     * With the continuous buffer disabled, these would yield the same output.  With it enabled, they yield different\r
-     * outputs.  The reason is due to the fact that the initialization vector's change after every encryption /\r
-     * decryption round when the continuous buffer is enabled.  When it's disabled, they remain constant.\r
-     *\r
-     * Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each\r
-     * encryption / decryption round, whereas otherwise, it'd remain constant.  For this reason, it's recommended that\r
-     * continuous buffers not be used.  They do offer better security and are, in fact, sometimes required (SSH uses them),\r
-     * however, they are also less intuitive and more likely to cause you problems.\r
-     *\r
-     * @see Crypt_RC4::disableContinuousBuffer()\r
-     * @access public\r
-     */\r
-    function enableContinuousBuffer()\r
-    {\r
-        $this->continuousBuffer = true;\r
-    }\r
-\r
-    /**\r
-     * Treat consecutive packets as if they are a discontinuous buffer.\r
-     *\r
-     * The default behavior.\r
-     *\r
-     * @see Crypt_RC4::enableContinuousBuffer()\r
-     * @access public\r
-     */\r
-    function disableContinuousBuffer()\r
-    {\r
-        if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_INTERNAL ) {\r
-            $this->encryptIndex = $this->decryptIndex = array(0, 0);\r
-            $this->setKey($this->key);\r
-        }\r
-\r
-        $this->continuousBuffer = false;\r
-    }\r
-\r
-    /**\r
-     * Dummy function.\r
-     *\r
-     * Since RC4 is a stream cipher and not a block cipher, no padding is necessary.  The only reason this function is\r
-     * included is so that you can switch between a block cipher and a stream cipher transparently.\r
-     *\r
-     * @see Crypt_RC4::disablePadding()\r
-     * @access public\r
-     */\r
-    function enablePadding()\r
-    {\r
-    }\r
-\r
-    /**\r
-     * Dummy function.\r
-     *\r
-     * @see Crypt_RC4::enablePadding()\r
-     * @access public\r
-     */\r
-    function disablePadding()\r
-    {\r
-    }\r
-\r
-    /**\r
-     * Class destructor.\r
-     *\r
-     * Will be called, automatically, if you're using PHP5.  If you're using PHP4, call it yourself.  Only really\r
-     * needs to be called if mcrypt is being used.\r
-     *\r
-     * @access public\r
-     */\r
-    function __destruct()\r
-    {\r
-        if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {\r
-            $this->_closeMCrypt();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Properly close the MCrypt objects.\r
-     *\r
-     * @access prviate\r
-     */\r
-    function _closeMCrypt()\r
-    {\r
-        if ( $this->encryptStream !== false ) {\r
-            if ( $this->continuousBuffer ) {\r
-                mcrypt_generic_deinit($this->encryptStream);\r
-            }\r
-\r
-            mcrypt_module_close($this->encryptStream);\r
-\r
-            $this->encryptStream = false;\r
-        }\r
-\r
-        if ( $this->decryptStream !== false ) {\r
-            if ( $this->continuousBuffer ) {\r
-                mcrypt_generic_deinit($this->decryptStream);\r
-            }\r
-\r
-            mcrypt_module_close($this->decryptStream);\r
-\r
-            $this->decryptStream = false;\r
-        }\r
-    }\r
-}
\ No newline at end of file
diff --git a/library/phpsec/Crypt/RSA.php b/library/phpsec/Crypt/RSA.php
deleted file mode 100644 (file)
index 1c56208..0000000
+++ /dev/null
@@ -1,2119 +0,0 @@
-<?php\r
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */\r
-\r
-/**\r
- * Pure-PHP PKCS#1 (v2.1) compliant implementation of RSA.\r
- *\r
- * PHP versions 4 and 5\r
- *\r
- * Here's an example of how to encrypt and decrypt text with this library:\r
- * <code>\r
- * <?php\r
- *    include('Crypt/RSA.php');\r
- *\r
- *    $rsa = new Crypt_RSA();\r
- *    extract($rsa->createKey());\r
- *\r
- *    $plaintext = 'terrafrost';\r
- *\r
- *    $rsa->loadKey($privatekey);\r
- *    $ciphertext = $rsa->encrypt($plaintext);\r
- *\r
- *    $rsa->loadKey($publickey);\r
- *    echo $rsa->decrypt($ciphertext);\r
- * ?>\r
- * </code>\r
- *\r
- * Here's an example of how to create signatures and verify signatures with this library:\r
- * <code>\r
- * <?php\r
- *    include('Crypt/RSA.php');\r
- *\r
- *    $rsa = new Crypt_RSA();\r
- *    extract($rsa->createKey());\r
- *\r
- *    $plaintext = 'terrafrost';\r
- *\r
- *    $rsa->loadKey($privatekey);\r
- *    $signature = $rsa->sign($plaintext);\r
- *\r
- *    $rsa->loadKey($publickey);\r
- *    echo $rsa->verify($plaintext, $signature) ? 'verified' : 'unverified';\r
- * ?>\r
- * </code>\r
- *\r
- * LICENSE: This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,\r
- * MA  02111-1307  USA\r
- *\r
- * @category   Crypt\r
- * @package    Crypt_RSA\r
- * @author     Jim Wigginton <terrafrost@php.net>\r
- * @copyright  MMIX Jim Wigginton\r
- * @license    http://www.gnu.org/licenses/lgpl.txt\r
- * @version    $Id: RSA.php,v 1.15 2010/04/10 15:57:02 terrafrost Exp $\r
- * @link       http://phpseclib.sourceforge.net\r
- */\r
-\r
-/**\r
- * Include Math_BigInteger\r
- */\r
-require_once('Math/BigInteger.php');\r
-\r
-/**\r
- * Include Crypt_Random\r
- */\r
-require_once('Crypt/Random.php');\r
-\r
-/**\r
- * Include Crypt_Hash\r
- */\r
-require_once('Crypt/Hash.php');\r
-\r
-/**#@+\r
- * @access public\r
- * @see Crypt_RSA::encrypt()\r
- * @see Crypt_RSA::decrypt()\r
- */\r
-/**\r
- * Use {@link http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding Optimal Asymmetric Encryption Padding}\r
- * (OAEP) for encryption / decryption.\r
- *\r
- * Uses sha1 by default.\r
- *\r
- * @see Crypt_RSA::setHash()\r
- * @see Crypt_RSA::setMGFHash()\r
- */\r
-define('CRYPT_RSA_ENCRYPTION_OAEP',  1);\r
-/**\r
- * Use PKCS#1 padding.\r
- *\r
- * Although CRYPT_RSA_ENCRYPTION_OAEP offers more security, including PKCS#1 padding is necessary for purposes of backwards\r
- * compatability with protocols (like SSH-1) written before OAEP's introduction.\r
- */\r
-define('CRYPT_RSA_ENCRYPTION_PKCS1', 2);\r
-/**#@-*/\r
-\r
-/**#@+\r
- * @access public\r
- * @see Crypt_RSA::sign()\r
- * @see Crypt_RSA::verify()\r
- * @see Crypt_RSA::setHash()\r
- */\r
-/**\r
- * Use the Probabilistic Signature Scheme for signing\r
- *\r
- * Uses sha1 by default.\r
- *\r
- * @see Crypt_RSA::setSaltLength()\r
- * @see Crypt_RSA::setMGFHash()\r
- */\r
-define('CRYPT_RSA_SIGNATURE_PSS',  1);\r
-/**\r
- * Use the PKCS#1 scheme by default.\r
- *\r
- * Although CRYPT_RSA_SIGNATURE_PSS offers more security, including PKCS#1 signing is necessary for purposes of backwards\r
- * compatability with protocols (like SSH-2) written before PSS's introduction.\r
- */\r
-define('CRYPT_RSA_SIGNATURE_PKCS1', 2);\r
-/**#@-*/\r
-\r
-/**#@+\r
- * @access private\r
- * @see Crypt_RSA::createKey()\r
- */\r
-/**\r
- * ASN1 Integer\r
- */\r
-define('CRYPT_RSA_ASN1_INTEGER',   2);\r
-/**\r
- * ASN1 Sequence (with the constucted bit set)\r
- */\r
-define('CRYPT_RSA_ASN1_SEQUENCE', 48);\r
-/**#@-*/\r
-\r
-/**#@+\r
- * @access private\r
- * @see Crypt_RSA::Crypt_RSA()\r
- */\r
-/**\r
- * To use the pure-PHP implementation\r
- */\r
-define('CRYPT_RSA_MODE_INTERNAL', 1);\r
-/**\r
- * To use the OpenSSL library\r
- *\r
- * (if enabled; otherwise, the internal implementation will be used)\r
- */\r
-define('CRYPT_RSA_MODE_OPENSSL', 2);\r
-/**#@-*/\r
-\r
-/**#@+\r
- * @access public\r
- * @see Crypt_RSA::createKey()\r
- * @see Crypt_RSA::setPrivateKeyFormat()\r
- */\r
-/**\r
- * PKCS#1 formatted private key\r
- *\r
- * Used by OpenSSH\r
- */\r
-define('CRYPT_RSA_PRIVATE_FORMAT_PKCS1', 0);\r
-/**#@-*/\r
-\r
-/**#@+\r
- * @access public\r
- * @see Crypt_RSA::createKey()\r
- * @see Crypt_RSA::setPublicKeyFormat()\r
- */\r
-/**\r
- * Raw public key\r
- *\r
- * An array containing two Math_BigInteger objects.\r
- *\r
- * The exponent can be indexed with any of the following:\r
- *\r
- * 0, e, exponent, publicExponent\r
- *\r
- * The modulus can be indexed with any of the following:\r
- *\r
- * 1, n, modulo, modulus\r
- */\r
-define('CRYPT_RSA_PUBLIC_FORMAT_RAW', 1);\r
-/**\r
- * PKCS#1 formatted public key\r
- */\r
-define('CRYPT_RSA_PUBLIC_FORMAT_PKCS1', 2);\r
-/**\r
- * OpenSSH formatted public key\r
- *\r
- * Place in $HOME/.ssh/authorized_keys\r
- */\r
-define('CRYPT_RSA_PUBLIC_FORMAT_OPENSSH', 3);\r
-/**#@-*/\r
-\r
-/**\r
- * Pure-PHP PKCS#1 compliant implementation of RSA.\r
- *\r
- * @author  Jim Wigginton <terrafrost@php.net>\r
- * @version 0.1.0\r
- * @access  public\r
- * @package Crypt_RSA\r
- */\r
-class Crypt_RSA {\r
-    /**\r
-     * Precomputed Zero\r
-     *\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $zero;\r
-\r
-    /**\r
-     * Precomputed One\r
-     *\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $one;\r
-\r
-    /**\r
-     * Private Key Format\r
-     *\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $privateKeyFormat = CRYPT_RSA_PRIVATE_FORMAT_PKCS1;\r
-\r
-    /**\r
-     * Public Key Format\r
-     *\r
-     * @var Integer\r
-     * @access public\r
-     */\r
-    var $publicKeyFormat = CRYPT_RSA_PUBLIC_FORMAT_PKCS1;\r
-\r
-    /**\r
-     * Modulus (ie. n)\r
-     *\r
-     * @var Math_BigInteger\r
-     * @access private\r
-     */\r
-    var $modulus;\r
-\r
-    /**\r
-     * Modulus length\r
-     *\r
-     * @var Math_BigInteger\r
-     * @access private\r
-     */\r
-    var $k;\r
-\r
-    /**\r
-     * Exponent (ie. e or d)\r
-     *\r
-     * @var Math_BigInteger\r
-     * @access private\r
-     */\r
-    var $exponent;\r
-\r
-    /**\r
-     * Primes for Chinese Remainder Theorem (ie. p and q)\r
-     *\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $primes;\r
-\r
-    /**\r
-     * Exponents for Chinese Remainder Theorem (ie. dP and dQ)\r
-     *\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $exponents;\r
-\r
-    /**\r
-     * Coefficients for Chinese Remainder Theorem (ie. qInv)\r
-     *\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $coefficients;\r
-\r
-    /**\r
-     * Hash name\r
-     *\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $hashName;\r
-\r
-    /**\r
-     * Hash function\r
-     *\r
-     * @var Crypt_Hash\r
-     * @access private\r
-     */\r
-    var $hash;\r
-\r
-    /**\r
-     * Length of hash function output\r
-     *\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $hLen;\r
-\r
-    /**\r
-     * Length of salt\r
-     *\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $sLen;\r
-\r
-    /**\r
-     * Hash function for the Mask Generation Function\r
-     *\r
-     * @var Crypt_Hash\r
-     * @access private\r
-     */\r
-    var $mgfHash;\r
-\r
-    /**\r
-     * Length of MGF hash function output\r
-     *\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $mgfHLen;\r
-\r
-    /**\r
-     * Encryption mode\r
-     *\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $encryptionMode = CRYPT_RSA_ENCRYPTION_OAEP;\r
-\r
-    /**\r
-     * Signature mode\r
-     *\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $signatureMode = CRYPT_RSA_SIGNATURE_PSS;\r
-\r
-    /**\r
-     * Public Exponent\r
-     *\r
-     * @var Mixed\r
-     * @access private\r
-     */\r
-    var $publicExponent = false;\r
-\r
-    /**\r
-     * Password\r
-     *\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $password = '';\r
-\r
-    /**\r
-     * The constructor\r
-     *\r
-     * If you want to make use of the openssl extension, you'll need to set the mode manually, yourself.  The reason\r
-     * Crypt_RSA doesn't do it is because OpenSSL doesn't fail gracefully.  openssl_pkey_new(), in particular, requires\r
-     * openssl.cnf be present somewhere and, unfortunately, the only real way to find out is too late.\r
-     *\r
-     * @return Crypt_RSA\r
-     * @access public\r
-     */\r
-    function Crypt_RSA()\r
-    {\r
-        if ( !defined('CRYPT_RSA_MODE') ) {\r
-            switch (true) {\r
-                //case extension_loaded('openssl') && version_compare(PHP_VERSION, '4.2.0', '>='):\r
-                //    define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_OPENSSL);\r
-                //    break;\r
-                default:\r
-                    define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);\r
-            }\r
-        }\r
-\r
-        $this->zero = new Math_BigInteger();\r
-        $this->one = new Math_BigInteger(1);\r
-\r
-        $this->hash = new Crypt_Hash('sha1');\r
-        $this->hLen = $this->hash->getLength();\r
-        $this->hashName = 'sha1';\r
-        $this->mgfHash = new Crypt_Hash('sha1');\r
-        $this->mgfHLen = $this->mgfHash->getLength();\r
-    }\r
-\r
-    /**\r
-     * Create public / private key pair\r
-     *\r
-     * Returns an array with the following three elements:\r
-     *  - 'privatekey': The private key.\r
-     *  - 'publickey':  The public key.\r
-     *  - 'partialkey': A partially computed key (if the execution time exceeded $timeout).\r
-     *                  Will need to be passed back to Crypt_RSA::createKey() as the third parameter for further processing.\r
-     *\r
-     * @access public\r
-     * @param optional Integer $bits\r
-     * @param optional Integer $timeout\r
-     * @param optional Math_BigInteger $p\r
-     */\r
-    function createKey($bits = 1024, $timeout = false, $partial = array())\r
-    {\r
-        if ( CRYPT_RSA_MODE == CRYPT_RSA_MODE_OPENSSL ) {\r
-            $rsa = openssl_pkey_new(array('private_key_bits' => $bits));\r
-            openssl_pkey_export($rsa, $privatekey);\r
-            $publickey = openssl_pkey_get_details($rsa);\r
-            $publickey = $publickey['key'];\r
-\r
-            if ($this->privateKeyFormat != CRYPT_RSA_PRIVATE_FORMAT_PKCS1) {\r
-                $privatekey = call_user_func_array(array($this, '_convertPrivateKey'), array_values($this->_parseKey($privatekey, CRYPT_RSA_PRIVATE_FORMAT_PKCS1)));\r
-                $publickey = call_user_func_array(array($this, '_convertPublicKey'), array_values($this->_parseKey($publickey, CRYPT_RSA_PUBLIC_FORMAT_PKCS1)));\r
-            }\r
-\r
-            return array(\r
-                'privatekey' => $privatekey,\r
-                'publickey' => $publickey,\r
-                'partialkey' => false\r
-            );\r
-        }\r
-\r
-        static $e;\r
-        if (!isset($e)) {\r
-            if (!defined('CRYPT_RSA_EXPONENT')) {\r
-                // http://en.wikipedia.org/wiki/65537_%28number%29\r
-                define('CRYPT_RSA_EXPONENT', '65537');\r
-            }\r
-            if (!defined('CRYPT_RSA_COMMENT')) {\r
-                define('CRYPT_RSA_COMMENT', 'phpseclib-generated-key');\r
-            }\r
-            // per <http://cseweb.ucsd.edu/~hovav/dist/survey.pdf#page=5>, this number ought not result in primes smaller\r
-            // than 256 bits.\r
-            if (!defined('CRYPT_RSA_SMALLEST_PRIME')) {\r
-                define('CRYPT_RSA_SMALLEST_PRIME', 4096);\r
-            }\r
-\r
-            $e = new Math_BigInteger(CRYPT_RSA_EXPONENT);\r
-        }\r
-\r
-        extract($this->_generateMinMax($bits));\r
-        $absoluteMin = $min;\r
-        $temp = $bits >> 1;\r
-        if ($temp > CRYPT_RSA_SMALLEST_PRIME) {\r
-            $num_primes = floor($bits / CRYPT_RSA_SMALLEST_PRIME);\r
-            $temp = CRYPT_RSA_SMALLEST_PRIME;\r
-        } else {\r
-            $num_primes = 2;\r
-        }\r
-        extract($this->_generateMinMax($temp + $bits % $temp));\r
-        $finalMax = $max;\r
-        extract($this->_generateMinMax($temp));\r
-\r
-        $generator = new Math_BigInteger();\r
-        $generator->setRandomGenerator('crypt_random');\r
-\r
-        $n = $this->one->copy();\r
-        if (!empty($partial)) {\r
-            extract(unserialize($partial));\r
-        } else {\r
-            $exponents = $coefficients = $primes = array();\r
-            $lcm = array(\r
-                'top' => $this->one->copy(),\r
-                'bottom' => false\r
-            );\r
-        }\r
-\r
-        $start = time();\r
-        $i0 = count($primes) + 1;\r
-\r
-        do {\r
-            for ($i = $i0; $i <= $num_primes; $i++) {\r
-                if ($timeout !== false) {\r
-                    $timeout-= time() - $start;\r
-                    $start = time();\r
-                    if ($timeout <= 0) {\r
-                        return serialize(array(\r
-                            'privatekey' => '',\r
-                            'publickey'  => '',\r
-                            'partialkey' => array(\r
-                                'primes' => $primes,\r
-                                'coefficients' => $coefficients,\r
-                                'lcm' => $lcm,\r
-                                'exponents' => $exponents\r
-                            )\r
-                        ));\r
-                    }\r
-                }\r
-\r
-                if ($i == $num_primes) {\r
-                    list($min, $temp) = $absoluteMin->divide($n);\r
-                    if (!$temp->equals($this->zero)) {\r
-                        $min = $min->add($this->one); // ie. ceil()\r
-                    }\r
-                    $primes[$i] = $generator->randomPrime($min, $finalMax, $timeout);\r
-                } else {\r
-                    $primes[$i] = $generator->randomPrime($min, $max, $timeout);\r
-                }\r
-\r
-                if ($primes[$i] === false) { // if we've reached the timeout\r
-                    return array(\r
-                        'privatekey' => '',\r
-                        'publickey'  => '',\r
-                        'partialkey' => empty($primes) ? '' : serialize(array(\r
-                            'primes' => array_slice($primes, 0, $i - 1),\r
-                            'coefficients' => $coefficients,\r
-                            'lcm' => $lcm,\r
-                            'exponents' => $exponents\r
-                        ))\r
-                    );\r
-                }\r
-\r
-                // the first coefficient is calculated differently from the rest\r
-                // ie. instead of being $primes[1]->modInverse($primes[2]), it's $primes[2]->modInverse($primes[1])\r
-                if ($i > 2) {\r
-                    $coefficients[$i] = $n->modInverse($primes[$i]);\r
-                }\r
-\r
-                $n = $n->multiply($primes[$i]);\r
-\r
-                $temp = $primes[$i]->subtract($this->one);\r
-\r
-                // textbook RSA implementations use Euler's totient function instead of the least common multiple.\r
-                // see http://en.wikipedia.org/wiki/Euler%27s_totient_function\r
-                $lcm['top'] = $lcm['top']->multiply($temp);\r
-                $lcm['bottom'] = $lcm['bottom'] === false ? $temp : $lcm['bottom']->gcd($temp);\r
-\r
-                $exponents[$i] = $e->modInverse($temp);\r
-            }\r
-\r
-            list($lcm) = $lcm['top']->divide($lcm['bottom']);\r
-            $gcd = $lcm->gcd($e);\r
-            $i0 = 1;\r
-        } while (!$gcd->equals($this->one));\r
-\r
-        $d = $e->modInverse($lcm);\r
-\r
-        $coefficients[2] = $primes[2]->modInverse($primes[1]);\r
-\r
-        // from <http://tools.ietf.org/html/rfc3447#appendix-A.1.2>:\r
-        // RSAPrivateKey ::= SEQUENCE {\r
-        //     version           Version,\r
-        //     modulus           INTEGER,  -- n\r
-        //     publicExponent    INTEGER,  -- e\r
-        //     privateExponent   INTEGER,  -- d\r
-        //     prime1            INTEGER,  -- p\r
-        //     prime2            INTEGER,  -- q\r
-        //     exponent1         INTEGER,  -- d mod (p-1)\r
-        //     exponent2         INTEGER,  -- d mod (q-1)\r
-        //     coefficient       INTEGER,  -- (inverse of q) mod p\r
-        //     otherPrimeInfos   OtherPrimeInfos OPTIONAL\r
-        // }\r
-\r
-        return array(\r
-            'privatekey' => $this->_convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients),\r
-            'publickey'  => $this->_convertPublicKey($n, $e),\r
-            'partialkey' => false\r
-        );\r
-    }\r
-\r
-    /**\r
-     * Convert a private key to the appropriate format.\r
-     *\r
-     * @access private\r
-     * @see setPrivateKeyFormat()\r
-     * @param String $RSAPrivateKey\r
-     * @return String\r
-     */\r
-    function _convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients)\r
-    {\r
-        $num_primes = count($primes);\r
-        $raw = array(\r
-            'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi\r
-            'modulus' => $n->toBytes(true),\r
-            'publicExponent' => $e->toBytes(true),\r
-            'privateExponent' => $d->toBytes(true),\r
-            'prime1' => $primes[1]->toBytes(true),\r
-            'prime2' => $primes[2]->toBytes(true),\r
-            'exponent1' => $exponents[1]->toBytes(true),\r
-            'exponent2' => $exponents[2]->toBytes(true),\r
-            'coefficient' => $coefficients[2]->toBytes(true)\r
-        );\r
-\r
-        // if the format in question does not support multi-prime rsa and multi-prime rsa was used,\r
-        // call _convertPublicKey() instead.\r
-        switch ($this->privateKeyFormat) {\r
-            default: // eg. CRYPT_RSA_PRIVATE_FORMAT_PKCS1\r
-                $components = array();\r
-                foreach ($raw as $name => $value) {\r
-                    $components[$name] = pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($value)), $value);\r
-                }\r
-\r
-                $RSAPrivateKey = implode('', $components);\r
-\r
-                if ($num_primes > 2) {\r
-                    $OtherPrimeInfos = '';\r
-                    for ($i = 3; $i <= $num_primes; $i++) {\r
-                        // OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo\r
-                        //\r
-                        // OtherPrimeInfo ::= SEQUENCE {\r
-                        //     prime             INTEGER,  -- ri\r
-                        //     exponent          INTEGER,  -- di\r
-                        //     coefficient       INTEGER   -- ti\r
-                        // }\r
-                        $OtherPrimeInfo = pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));\r
-                        $OtherPrimeInfo.= pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));\r
-                        $OtherPrimeInfo.= pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));\r
-                        $OtherPrimeInfos.= pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);\r
-                    }\r
-                    $RSAPrivateKey.= pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);\r
-                }\r
-\r
-                $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);\r
-\r
-                if (!empty($this->password)) {\r
-                    $iv = $this->_random(8);\r
-                    $symkey = pack('H*', md5($this->password . $iv)); // symkey is short for symmetric key\r
-                    $symkey.= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8);\r
-                    if (!class_exists('Crypt_TripleDES')) {\r
-                        require_once('Crypt/TripleDES.php');\r
-                    }\r
-                    $des = new Crypt_TripleDES();\r
-                    $des->setKey($symkey);\r
-                    $des->setIV($iv);\r
-                    $iv = strtoupper(bin2hex($iv));\r
-                    $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .\r
-                                     "Proc-Type: 4,ENCRYPTED\r\n" .\r
-                                     "DEK-Info: DES-EDE3-CBC,$iv\r\n" .\r
-                                     "\r\n" .\r
-                                     chunk_split(base64_encode($des->encrypt($RSAPrivateKey))) .\r
-                                     '-----END RSA PRIVATE KEY-----';\r
-                } else {\r
-                    $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .\r
-                                     chunk_split(base64_encode($RSAPrivateKey)) .\r
-                                     '-----END RSA PRIVATE KEY-----';\r
-                }\r
-\r
-                return $RSAPrivateKey;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Convert a public key to the appropriate format\r
-     *\r
-     * @access private\r
-     * @see setPublicKeyFormat()\r
-     * @param String $RSAPrivateKey\r
-     * @return String\r
-     */\r
-    function _convertPublicKey($n, $e)\r
-    {\r
-        $modulus = $n->toBytes(true);\r
-        $publicExponent = $e->toBytes(true);\r
-\r
-        switch ($this->publicKeyFormat) {\r
-            case CRYPT_RSA_PUBLIC_FORMAT_RAW:\r
-                return array('e' => $e->copy(), 'n' => $n->copy());\r
-            case CRYPT_RSA_PUBLIC_FORMAT_OPENSSH:\r
-                // from <http://tools.ietf.org/html/rfc4253#page-15>:\r
-                // string    "ssh-rsa"\r
-                // mpint     e\r
-                // mpint     n\r
-                $RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus);\r
-                $RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . CRYPT_RSA_COMMENT;\r
-\r
-                return $RSAPublicKey;\r
-            default: // eg. CRYPT_RSA_PUBLIC_FORMAT_PKCS1\r
-                // from <http://tools.ietf.org/html/rfc3447#appendix-A.1.1>:\r
-                // RSAPublicKey ::= SEQUENCE {\r
-                //     modulus           INTEGER,  -- n\r
-                //     publicExponent    INTEGER   -- e\r
-                // }\r
-                $components = array(\r
-                    'modulus' => pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($modulus)), $modulus),\r
-                    'publicExponent' => pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($publicExponent)), $publicExponent)\r
-                );\r
-\r
-                $RSAPublicKey = pack('Ca*a*a*',\r
-                    CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),\r
-                    $components['modulus'], $components['publicExponent']\r
-                );\r
-\r
-                $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .\r
-                                 chunk_split(base64_encode($RSAPublicKey)) .\r
-                                 '-----END PUBLIC KEY-----';\r
-\r
-                return $RSAPublicKey;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Break a public or private key down into its constituant components\r
-     *\r
-     * @access private\r
-     * @see _convertPublicKey()\r
-     * @see _convertPrivateKey()\r
-     * @param String $key\r
-     * @param Integer $type\r
-     * @return Array\r
-     */\r
-    function _parseKey($key, $type)\r
-    {\r
-        switch ($type) {\r
-            case CRYPT_RSA_PUBLIC_FORMAT_RAW:\r
-                if (!is_array($key)) {\r
-                    return false;\r
-                }\r
-                $components = array();\r
-                switch (true) {\r
-                    case isset($key['e']):\r
-                        $components['publicExponent'] = $key['e']->copy();\r
-                        break;\r
-                    case isset($key['exponent']):\r
-                        $components['publicExponent'] = $key['exponent']->copy();\r
-                        break;\r
-                    case isset($key['publicExponent']):\r
-                        $components['publicExponent'] = $key['publicExponent']->copy();\r
-                        break;\r
-                    case isset($key[0]):\r
-                        $components['publicExponent'] = $key[0]->copy();\r
-                }\r
-                switch (true) {\r
-                    case isset($key['n']):\r
-                        $components['modulus'] = $key['n']->copy();\r
-                        break;\r
-                    case isset($key['modulo']):\r
-                        $components['modulus'] = $key['modulo']->copy();\r
-                        break;\r
-                    case isset($key['modulus']):\r
-                        $components['modulus'] = $key['modulus']->copy();\r
-                        break;\r
-                    case isset($key[1]):\r
-                        $components['modulus'] = $key[1]->copy();\r
-                }\r
-                return $components;\r
-            case CRYPT_RSA_PRIVATE_FORMAT_PKCS1:\r
-            case CRYPT_RSA_PUBLIC_FORMAT_PKCS1:\r
-                /* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is\r
-                   "outside the scope" of PKCS#1.  PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to\r
-                   protect private keys, however, that's not what OpenSSL* does.  OpenSSL protects private keys by adding\r
-                   two new "fields" to the key - DEK-Info and Proc-Type.  These fields are discussed here:\r
-\r
-                   http://tools.ietf.org/html/rfc1421#section-4.6.1.1\r
-                   http://tools.ietf.org/html/rfc1421#section-4.6.1.3\r
-\r
-                   DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell.\r
-                   DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation\r
-                   function.  As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's\r
-                   own implementation.  ie. the implementation *is* the standard and any bugs that may exist in that \r
-                   implementation are part of the standard, as well.\r
-\r
-                   * OpenSSL is the de facto standard.  It's utilized by OpenSSH and other projects */\r
-                if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) {\r
-                    $iv = pack('H*', trim($matches[2]));\r
-                    $symkey = pack('H*', md5($this->password . $iv)); // symkey is short for symmetric key\r
-                    $symkey.= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8);\r
-                    $ciphertext = preg_replace('#.+(\r|\n|\r\n)\1|[\r\n]|-.+-#s', '', $key);\r
-                    $ciphertext = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $ciphertext) ? base64_decode($ciphertext) : false;\r
-                    if ($ciphertext === false) {\r
-                        $ciphertext = $key;\r
-                    }\r
-                    switch ($matches[1]) {\r
-                        case 'DES-EDE3-CBC':\r
-                            if (!class_exists('Crypt_TripleDES')) {\r
-                                require_once('Crypt/TripleDES.php');\r
-                            }\r
-                            $crypto = new Crypt_TripleDES();\r
-                            break;\r
-                        case 'DES-CBC':\r
-                            if (!class_exists('Crypt_DES')) {\r
-                                require_once('Crypt/DES.php');\r
-                            }\r
-                            $crypto = new Crypt_DES();\r
-                            break;\r
-                        default:\r
-                            return false;\r
-                    }\r
-                    $crypto->setKey($symkey);\r
-                    $crypto->setIV($iv);\r
-                    $decoded = $crypto->decrypt($ciphertext);\r
-                } else {\r
-                    $decoded = preg_replace('#-.+-|[\r\n]#', '', $key);\r
-                    $decoded = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $decoded) ? base64_decode($decoded) : false;\r
-                }\r
-\r
-                if ($decoded !== false) {\r
-                    $key = $decoded;\r
-                }\r
-\r
-                $components = array();\r
-\r
-                if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {\r
-                    return false;\r
-                }\r
-                if ($this->_decodeLength($key) != strlen($key)) {\r
-                    return false;\r
-                }\r
-\r
-                $tag = ord($this->_string_shift($key));\r
-                if ($tag == CRYPT_RSA_ASN1_SEQUENCE) {\r
-                    /* intended for keys for which OpenSSL's asn1parse returns the following:\r
-\r
-                        0:d=0  hl=4 l= 290 cons: SEQUENCE\r
-                        4:d=1  hl=2 l=  13 cons:  SEQUENCE\r
-                        6:d=2  hl=2 l=   9 prim:   OBJECT            :rsaEncryption\r
-                       17:d=2  hl=2 l=   0 prim:   NULL\r
-                       19:d=1  hl=4 l= 271 prim:  BIT STRING */\r
-                    $this->_string_shift($key, $this->_decodeLength($key));\r
-                    $this->_string_shift($key); // skip over the BIT STRING tag\r
-                    $this->_decodeLength($key); // skip over the BIT STRING length\r
-                    // "The initial octet shall encode, as an unsigned binary integer wtih bit 1 as the least significant bit, the number of\r
-                    //  unused bits in teh final subsequent octet. The number shall be in the range zero to seven."\r
-                    //  -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf (section 8.6.2.2)\r
-                    $this->_string_shift($key);\r
-                    if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {\r
-                        return false;\r
-                    }\r
-                    if ($this->_decodeLength($key) != strlen($key)) {\r
-                        return false;\r
-                    }\r
-                    $tag = ord($this->_string_shift($key));\r
-                }\r
-                if ($tag != CRYPT_RSA_ASN1_INTEGER) {\r
-                    return false;\r
-                }\r
-\r
-                $length = $this->_decodeLength($key);\r
-                $temp = $this->_string_shift($key, $length);\r
-                if (strlen($temp) != 1 || ord($temp) > 2) {\r
-                    $components['modulus'] = new Math_BigInteger($temp, -256);\r
-                    $this->_string_shift($key); // skip over CRYPT_RSA_ASN1_INTEGER\r
-                    $length = $this->_decodeLength($key);\r
-                    $components[$type == CRYPT_RSA_PUBLIC_FORMAT_PKCS1 ? 'publicExponent' : 'privateExponent'] = new Math_BigInteger($this->_string_shift($key, $length), -256);\r
-\r
-                    return $components;\r
-                }\r
-                if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_INTEGER) {\r
-                    return false;\r
-                }\r
-                $length = $this->_decodeLength($key);\r
-                $components['modulus'] = new Math_BigInteger($this->_string_shift($key, $length), -256);\r
-                $this->_string_shift($key);\r
-                $length = $this->_decodeLength($key);\r
-                $components['publicExponent'] = new Math_BigInteger($this->_string_shift($key, $length), -256);\r
-                $this->_string_shift($key);\r
-                $length = $this->_decodeLength($key);\r
-                $components['privateExponent'] = new Math_BigInteger($this->_string_shift($key, $length), -256);\r
-                $this->_string_shift($key);\r
-                $length = $this->_decodeLength($key);\r
-                $components['primes'] = array(1 => new Math_BigInteger($this->_string_shift($key, $length), -256));\r
-                $this->_string_shift($key);\r
-                $length = $this->_decodeLength($key);\r
-                $components['primes'][] = new Math_BigInteger($this->_string_shift($key, $length), -256);\r
-                $this->_string_shift($key);\r
-                $length = $this->_decodeLength($key);\r
-                $components['exponents'] = array(1 => new Math_BigInteger($this->_string_shift($key, $length), -256));\r
-                $this->_string_shift($key);\r
-                $length = $this->_decodeLength($key);\r
-                $components['exponents'][] = new Math_BigInteger($this->_string_shift($key, $length), -256);\r
-                $this->_string_shift($key);\r
-                $length = $this->_decodeLength($key);\r
-                $components['coefficients'] = array(2 => new Math_BigInteger($this->_string_shift($key, $length), -256));\r
-\r
-                if (!empty($key)) {\r
-                    if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {\r
-                        return false;\r
-                    }\r
-                    $this->_decodeLength($key);\r
-                    while (!empty($key)) {\r
-                        if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {\r
-                            return false;\r
-                        }\r
-                        $this->_decodeLength($key);\r
-                        $key = substr($key, 1);\r
-                        $length = $this->_decodeLength($key);\r
-                        $components['primes'][] = new Math_BigInteger($this->_string_shift($key, $length), -256);\r
-                        $this->_string_shift($key);\r
-                        $length = $this->_decodeLength($key);\r
-                        $components['exponents'][] = new Math_BigInteger($this->_string_shift($key, $length), -256);\r
-                        $this->_string_shift($key);\r
-                        $length = $this->_decodeLength($key);\r
-                        $components['coefficients'][] = new Math_BigInteger($this->_string_shift($key, $length), -256);\r
-                    }\r
-                }\r
-\r
-                return $components;\r
-            case CRYPT_RSA_PUBLIC_FORMAT_OPENSSH:\r
-                $key = base64_decode(preg_replace('#^ssh-rsa | .+$#', '', $key));\r
-                if ($key === false) {\r
-                    return false;\r
-                }\r
-\r
-                $cleanup = substr($key, 0, 11) == "\0\0\0\7ssh-rsa";\r
-\r
-                extract(unpack('Nlength', $this->_string_shift($key, 4)));\r
-                $publicExponent = new Math_BigInteger($this->_string_shift($key, $length), -256);\r
-                extract(unpack('Nlength', $this->_string_shift($key, 4)));\r
-                $modulus = new Math_BigInteger($this->_string_shift($key, $length), -256);\r
-\r
-                if ($cleanup && strlen($key)) {\r
-                    extract(unpack('Nlength', $this->_string_shift($key, 4)));\r
-                    return array(\r
-                        'modulus' => new Math_BigInteger($this->_string_shift($key, $length), -256),\r
-                        'publicExponent' => $modulus\r
-                    );\r
-                } else {\r
-                    return array(\r
-                        'modulus' => $modulus,\r
-                        'publicExponent' => $publicExponent\r
-                    );\r
-                }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Loads a public or private key\r
-     *\r
-     * Returns true on success and false on failure (ie. an incorrect password was provided or the key was malformed)\r
-     *\r
-     * @access public\r
-     * @param String $key\r
-     * @param Integer $type optional\r
-     */\r
-    function loadKey($key, $type = CRYPT_RSA_PRIVATE_FORMAT_PKCS1)\r
-    {\r
-        $components = $this->_parseKey($key, $type);\r
-        if ($components === false) {\r
-            return false;\r
-        }\r
-\r
-        $this->modulus = $components['modulus'];\r
-        $this->k = strlen($this->modulus->toBytes());\r
-        $this->exponent = isset($components['privateExponent']) ? $components['privateExponent'] : $components['publicExponent'];\r
-        if (isset($components['primes'])) {\r
-            $this->primes = $components['primes'];\r
-            $this->exponents = $components['exponents'];\r
-            $this->coefficients = $components['coefficients'];\r
-            $this->publicExponent = $components['publicExponent'];\r
-        } else {\r
-            $this->primes = array();\r
-            $this->exponents = array();\r
-            $this->coefficients = array();\r
-            $this->publicExponent = false;\r
-        }\r
-\r
-        return true;\r
-    }\r
-\r
-    /**\r
-     * Sets the password\r
-     *\r
-     * Private keys can be encrypted with a password.  To unset the password, pass in the empty string or false.\r
-     * Or rather, pass in $password such that empty($password) is true.\r
-     *\r
-     * @see createKey()\r
-     * @see loadKey()\r
-     * @access public\r
-     * @param String $password\r
-     */\r
-    function setPassword($password)\r
-    {\r
-        $this->password = $password;\r
-    }\r
-\r
-    /**\r
-     * Defines the public key\r
-     *\r
-     * Some private key formats define the public exponent and some don't.  Those that don't define it are problematic when\r
-     * used in certain contexts.  For example, in SSH-2, RSA authentication works by sending the public key along with a\r
-     * message signed by the private key to the server.  The SSH-2 server looks the public key up in an index of public keys\r
-     * and if it's present then proceeds to verify the signature.  Problem is, if your private key doesn't include the public\r
-     * exponent this won't work unless you manually add the public exponent.\r
-     *\r
-     * Do note that when a new key is loaded the index will be cleared.\r
-     *\r
-     * Returns true on success, false on failure\r
-     *\r
-     * @see getPublicKey()\r
-     * @access public\r
-     * @param String $key\r
-     * @param Integer $type optional\r
-     * @return Boolean\r
-     */\r
-    function setPublicKey($key, $type = CRYPT_RSA_PUBLIC_FORMAT_PKCS1)\r
-    {\r
-        $components = $this->_parseKey($key, $type);\r
-        if (empty($this->modulus) || !$this->modulus->equals($components['modulus'])) {\r
-            return false;\r
-        }\r
-        $this->publicExponent = $components['publicExponent'];\r
-    }\r
-\r
-    /**\r
-     * Returns the public key\r
-     *\r
-     * The public key is only returned under two circumstances - if the private key had the public key embedded within it\r
-     * or if the public key was set via setPublicKey().  If the currently loaded key is supposed to be the public key this\r
-     * function won't return it since this library, for the most part, doesn't distinguish between public and private keys.\r
-     *\r
-     * @see getPublicKey()\r
-     * @access public\r
-     * @param String $key\r
-     * @param Integer $type optional\r
-     */\r
-    function getPublicKey($type = CRYPT_RSA_PUBLIC_FORMAT_PKCS1)\r
-    {\r
-        if (empty($this->modulus) || empty($this->publicExponent)) {\r
-            return false;\r
-        }\r
-\r
-        $oldFormat = $this->publicKeyFormat;\r
-        $this->publicKeyFormat = $type;\r
-        $temp = $this->_convertPublicKey($this->modulus, $this->publicExponent);\r
-        $this->publicKeyFormat = $oldFormat;\r
-        return $temp;\r
-    }\r
-\r
-    /**\r
-     * Generates the smallest and largest numbers requiring $bits bits\r
-     *\r
-     * @access private\r
-     * @param Integer $bits\r
-     * @return Array\r
-     */\r
-    function _generateMinMax($bits)\r
-    {\r
-        $bytes = $bits >> 3;\r
-        $min = str_repeat(chr(0), $bytes);\r
-        $max = str_repeat(chr(0xFF), $bytes);\r
-        $msb = $bits & 7;\r
-        if ($msb) {\r
-            $min = chr(1 << ($msb - 1)) . $min;\r
-            $max = chr((1 << $msb) - 1) . $max;\r
-        } else {\r
-            $min[0] = chr(0x80);\r
-        }\r
-\r
-        return array(\r
-            'min' => new Math_BigInteger($min, 256),\r
-            'max' => new Math_BigInteger($max, 256)\r
-        );\r
-    }\r
-\r
-    /**\r
-     * DER-decode the length\r
-     *\r
-     * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4.  See\r
-     * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 § 8.1.3} for more information.\r
-     *\r
-     * @access private\r
-     * @param String $string\r
-     * @return Integer\r
-     */\r
-    function _decodeLength(&$string)\r
-    {\r
-        $length = ord($this->_string_shift($string));\r
-        if ( $length & 0x80 ) { // definite length, long form\r
-            $length&= 0x7F;\r
-            $temp = $this->_string_shift($string, $length);\r
-            list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4));\r
-        }\r
-        return $length;\r
-    }\r
-\r
-    /**\r
-     * DER-encode the length\r
-     *\r
-     * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4.  See\r
-     * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 § 8.1.3} for more information.\r
-     *\r
-     * @access private\r
-     * @param Integer $length\r
-     * @return String\r
-     */\r
-    function _encodeLength($length)\r
-    {\r
-        if ($length <= 0x7F) {\r
-            return chr($length);\r
-        }\r
-\r
-        $temp = ltrim(pack('N', $length), chr(0));\r
-        return pack('Ca*', 0x80 | strlen($temp), $temp);\r
-    }\r
-\r
-    /**\r
-     * String Shift\r
-     *\r
-     * Inspired by array_shift\r
-     *\r
-     * @param String $string\r
-     * @param optional Integer $index\r
-     * @return String\r
-     * @access private\r
-     */\r
-    function _string_shift(&$string, $index = 1)\r
-    {\r
-        $substr = substr($string, 0, $index);\r
-        $string = substr($string, $index);\r
-        return $substr;\r
-    }\r
-\r
-    /**\r
-     * Determines the private key format\r
-     *\r
-     * @see createKey()\r
-     * @access public\r
-     * @param Integer $format\r
-     */\r
-    function setPrivateKeyFormat($format)\r
-    {\r
-        $this->privateKeyFormat = $format;\r
-    }\r
-\r
-    /**\r
-     * Determines the public key format\r
-     *\r
-     * @see createKey()\r
-     * @access public\r
-     * @param Integer $format\r
-     */\r
-    function setPublicKeyFormat($format)\r
-    {\r
-        $this->publicKeyFormat = $format;\r
-    }\r
-\r
-    /**\r
-     * Determines which hashing function should be used\r
-     *\r
-     * Used with signature production / verification and (if the encryption mode is CRYPT_RSA_ENCRYPTION_OAEP) encryption and\r
-     * decryption.  If $hash isn't supported, sha1 is used.\r
-     *\r
-     * @access public\r
-     * @param String $hash\r
-     */\r
-    function setHash($hash)\r
-    {\r
-        // Crypt_Hash supports algorithms that PKCS#1 doesn't support.  md5-96 and sha1-96, for example.\r
-        switch ($hash) {\r
-            case 'md2':\r
-            case 'md5':\r
-            case 'sha1':\r
-            case 'sha256':\r
-            case 'sha384':\r
-            case 'sha512':\r
-                $this->hash = new Crypt_Hash($hash);\r
-                $this->hashName = $hash;\r
-                break;\r
-            default:\r
-                $this->hash = new Crypt_Hash('sha1');\r
-                $this->hashName = 'sha1';\r
-        }\r
-        $this->hLen = $this->hash->getLength();\r
-    }\r
-\r
-    /**\r
-     * Determines which hashing function should be used for the mask generation function\r
-     *\r
-     * The mask generation function is used by CRYPT_RSA_ENCRYPTION_OAEP and CRYPT_RSA_SIGNATURE_PSS and although it's\r
-     * best if Hash and MGFHash are set to the same thing this is not a requirement.\r
-     *\r
-     * @access public\r
-     * @param String $hash\r
-     */\r
-    function setMGFHash($hash)\r
-    {\r
-        // Crypt_Hash supports algorithms that PKCS#1 doesn't support.  md5-96 and sha1-96, for example.\r
-        switch ($hash) {\r
-            case 'md2':\r
-            case 'md5':\r
-            case 'sha1':\r
-            case 'sha256':\r
-            case 'sha384':\r
-            case 'sha512':\r
-                $this->mgfHash = new Crypt_Hash($hash);\r
-                break;\r
-            default:\r
-                $this->mgfHash = new Crypt_Hash('sha1');\r
-        }\r
-        $this->mgfHLen = $this->mgfHash->getLength();\r
-    }\r
-\r
-    /**\r
-     * Determines the salt length\r
-     *\r
-     * To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}:\r
-     *\r
-     *    Typical salt lengths in octets are hLen (the length of the output\r
-     *    of the hash function Hash) and 0.\r
-     *\r
-     * @access public\r
-     * @param Integer $format\r
-     */\r
-    function setSaltLength($sLen)\r
-    {\r
-        $this->sLen = $sLen;\r
-    }\r
-\r
-    /**\r
-     * Generates a random string x bytes long\r
-     *\r
-     * @access public\r
-     * @param Integer $bytes\r
-     * @param optional Integer $nonzero\r
-     * @return String\r
-     */\r
-    function _random($bytes, $nonzero = false)\r
-    {\r
-        $temp = '';\r
-        if ($nonzero) {\r
-            for ($i = 0; $i < $bytes; $i++) {\r
-                $temp.= chr(crypt_random(1, 255));\r
-            }\r
-        } else {\r
-            $ints = ($bytes + 1) >> 2;\r
-            for ($i = 0; $i < $ints; $i++) {\r
-                $temp.= pack('N', crypt_random());\r
-            }\r
-            $temp = substr($temp, 0, $bytes);\r
-        }\r
-        return $temp;\r
-    }\r
-\r
-    /**\r
-     * Integer-to-Octet-String primitive\r
-     *\r
-     * See {@link http://tools.ietf.org/html/rfc3447#section-4.1 RFC3447#section-4.1}.\r
-     *\r
-     * @access private\r
-     * @param Math_BigInteger $x\r
-     * @param Integer $xLen\r
-     * @return String\r
-     */\r
-    function _i2osp($x, $xLen)\r
-    {\r
-        $x = $x->toBytes();\r
-        if (strlen($x) > $xLen) {\r
-            user_error('Integer too large', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-        return str_pad($x, $xLen, chr(0), STR_PAD_LEFT);\r
-    }\r
-\r
-    /**\r
-     * Octet-String-to-Integer primitive\r
-     *\r
-     * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}.\r
-     *\r
-     * @access private\r
-     * @param String $x\r
-     * @return Math_BigInteger\r
-     */\r
-    function _os2ip($x)\r
-    {\r
-        return new Math_BigInteger($x, 256);\r
-    }\r
-\r
-    /**\r
-     * Exponentiate with or without Chinese Remainder Theorem\r
-     *\r
-     * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.2}.\r
-     *\r
-     * @access private\r
-     * @param Math_BigInteger $x\r
-     * @return Math_BigInteger\r
-     */\r
-    function _exponentiate($x)\r
-    {\r
-        if (empty($this->primes) || empty($this->coefficients) || empty($this->exponents)) {\r
-            return $x->modPow($this->exponent, $this->modulus);\r
-        }\r
-\r
-        $num_primes = count($this->primes);\r
-\r
-        if (defined('CRYPT_RSA_DISABLE_BLINDING')) {\r
-            $m_i = array(\r
-                1 => $x->modPow($this->exponents[1], $this->primes[1]),\r
-                2 => $x->modPow($this->exponents[2], $this->primes[2])\r
-            );\r
-            $h = $m_i[1]->subtract($m_i[2]);\r
-            $h = $h->multiply($this->coefficients[2]);\r
-            list(, $h) = $h->divide($this->primes[1]);\r
-            $m = $m_i[2]->add($h->multiply($this->primes[2]));\r
-\r
-            $r = $this->primes[1];\r
-            for ($i = 3; $i <= $num_primes; $i++) {\r
-                $m_i = $x->modPow($this->exponents[$i], $this->primes[$i]);\r
-\r
-                $r = $r->multiply($this->primes[$i - 1]);\r
-\r
-                $h = $m_i->subtract($m);\r
-                $h = $h->multiply($this->coefficients[$i]);\r
-                list(, $h) = $h->divide($this->primes[$i]);\r
-\r
-                $m = $m->add($r->multiply($h));\r
-            }\r
-        } else {\r
-            $smallest = $this->primes[1];\r
-            for ($i = 2; $i <= $num_primes; $i++) {\r
-                if ($smallest->compare($this->primes[$i]) > 0) {\r
-                    $smallest = $this->primes[$i];\r
-                }\r
-            }\r
-\r
-            $one = new Math_BigInteger(1);\r
-            $one->setRandomGenerator('crypt_random');\r
-\r
-            $r = $one->random($one, $smallest->subtract($one));\r
-\r
-            $m_i = array(\r
-                1 => $this->_blind($x, $r, 1),\r
-                2 => $this->_blind($x, $r, 2)\r
-            );\r
-            $h = $m_i[1]->subtract($m_i[2]);\r
-            $h = $h->multiply($this->coefficients[2]);\r
-            list(, $h) = $h->divide($this->primes[1]);\r
-            $m = $m_i[2]->add($h->multiply($this->primes[2]));\r
-\r
-            $r = $this->primes[1];\r
-            for ($i = 3; $i <= $num_primes; $i++) {\r
-                $m_i = $this->_blind($x, $r, $i);\r
-\r
-                $r = $r->multiply($this->primes[$i - 1]);\r
-\r
-                $h = $m_i->subtract($m);\r
-                $h = $h->multiply($this->coefficients[$i]);\r
-                list(, $h) = $h->divide($this->primes[$i]);\r
-\r
-                $m = $m->add($r->multiply($h));\r
-            }\r
-        }\r
-\r
-        return $m;\r
-    }\r
-\r
-    /**\r
-     * Performs RSA Blinding\r
-     *\r
-     * Protects against timing attacks by employing RSA Blinding.\r
-     * Returns $x->modPow($this->exponents[$i], $this->primes[$i])\r
-     *\r
-     * @access private\r
-     * @param Math_BigInteger $x\r
-     * @param Math_BigInteger $r\r
-     * @param Integer $i\r
-     * @return Math_BigInteger\r
-     */\r
-    function _blind($x, $r, $i)\r
-    {\r
-        $x = $x->multiply($r->modPow($this->publicExponent, $this->primes[$i]));\r
-\r
-        $x = $x->modPow($this->exponents[$i], $this->primes[$i]);\r
-\r
-        $r = $r->modInverse($this->primes[$i]);\r
-        $x = $x->multiply($r);\r
-        list(, $x) = $x->divide($this->primes[$i]);\r
-\r
-        return $x;\r
-    }\r
-\r
-    /**\r
-     * RSAEP\r
-     *\r
-     * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.1}.\r
-     *\r
-     * @access private\r
-     * @param Math_BigInteger $m\r
-     * @return Math_BigInteger\r
-     */\r
-    function _rsaep($m)\r
-    {\r
-        if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) {\r
-            user_error('Message representative out of range', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-        return $this->_exponentiate($m);\r
-    }\r
-\r
-    /**\r
-     * RSADP\r
-     *\r
-     * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.2 RFC3447#section-5.1.2}.\r
-     *\r
-     * @access private\r
-     * @param Math_BigInteger $c\r
-     * @return Math_BigInteger\r
-     */\r
-    function _rsadp($c)\r
-    {\r
-        if ($c->compare($this->zero) < 0 || $c->compare($this->modulus) > 0) {\r
-            user_error('Ciphertext representative out of range', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-        return $this->_exponentiate($c);\r
-    }\r
-\r
-    /**\r
-     * RSASP1\r
-     *\r
-     * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.1 RFC3447#section-5.2.1}.\r
-     *\r
-     * @access private\r
-     * @param Math_BigInteger $m\r
-     * @return Math_BigInteger\r
-     */\r
-    function _rsasp1($m)\r
-    {\r
-        if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) {\r
-            user_error('Message representative out of range', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-        return $this->_exponentiate($m);\r
-    }\r
-\r
-    /**\r
-     * RSAVP1\r
-     *\r
-     * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.2 RFC3447#section-5.2.2}.\r
-     *\r
-     * @access private\r
-     * @param Math_BigInteger $s\r
-     * @return Math_BigInteger\r
-     */\r
-    function _rsavp1($s)\r
-    {\r
-        if ($s->compare($this->zero) < 0 || $s->compare($this->modulus) > 0) {\r
-            user_error('Signature representative out of range', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-        return $this->_exponentiate($s);\r
-    }\r
-\r
-    /**\r
-     * MGF1\r
-     *\r
-     * See {@link http://tools.ietf.org/html/rfc3447#appendix-B.2.1 RFC3447#appendix-B.2.1}.\r
-     *\r
-     * @access private\r
-     * @param String $mgfSeed\r
-     * @param Integer $mgfLen\r
-     * @return String\r
-     */\r
-    function _mgf1($mgfSeed, $maskLen)\r
-    {\r
-        // if $maskLen would yield strings larger than 4GB, PKCS#1 suggests a "Mask too long" error be output.\r
-\r
-        $t = '';\r
-        $count = ceil($maskLen / $this->mgfHLen);\r
-        for ($i = 0; $i < $count; $i++) {\r
-            $c = pack('N', $i);\r
-            $t.= $this->mgfHash->hash($mgfSeed . $c);\r
-        }\r
-\r
-        return substr($t, 0, $maskLen);\r
-    }\r
-\r
-    /**\r
-     * RSAES-OAEP-ENCRYPT\r
-     *\r
-     * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.1 RFC3447#section-7.1.1} and\r
-     * {http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding OAES}.\r
-     *\r
-     * @access private\r
-     * @param String $m\r
-     * @param String $l\r
-     * @return String\r
-     */\r
-    function _rsaes_oaep_encrypt($m, $l = '')\r
-    {\r
-        $mLen = strlen($m);\r
-\r
-        // Length checking\r
-\r
-        // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error\r
-        // be output.\r
-\r
-        if ($mLen > $this->k - 2 * $this->hLen - 2) {\r
-            user_error('Message too long', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        // EME-OAEP encoding\r
-\r
-        $lHash = $this->hash->hash($l);\r
-        $ps = str_repeat(chr(0), $this->k - $mLen - 2 * $this->hLen - 2);\r
-        $db = $lHash . $ps . chr(1) . $m;\r
-        $seed = $this->_random($this->hLen);\r
-        $dbMask = $this->_mgf1($seed, $this->k - $this->hLen - 1);\r
-        $maskedDB = $db ^ $dbMask;\r
-        $seedMask = $this->_mgf1($maskedDB, $this->hLen);\r
-        $maskedSeed = $seed ^ $seedMask;\r
-        $em = chr(0) . $maskedSeed . $maskedDB;\r
-\r
-        // RSA encryption\r
-\r
-        $m = $this->_os2ip($em);\r
-        $c = $this->_rsaep($m);\r
-        $c = $this->_i2osp($c, $this->k);\r
-\r
-        // Output the ciphertext C\r
-\r
-        return $c;\r
-    }\r
-\r
-    /**\r
-     * RSAES-OAEP-DECRYPT\r
-     *\r
-     * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.2 RFC3447#section-7.1.2}.  The fact that the error\r
-     * messages aren't distinguishable from one another hinders debugging, but, to quote from RFC3447#section-7.1.2:\r
-     * \r
-     *    Note.  Care must be taken to ensure that an opponent cannot\r
-     *    distinguish the different error conditions in Step 3.g, whether by\r
-     *    error message or timing, or, more generally, learn partial\r
-     *    information about the encoded message EM.  Otherwise an opponent may\r
-     *    be able to obtain useful information about the decryption of the\r
-     *    ciphertext C, leading to a chosen-ciphertext attack such as the one\r
-     *    observed by Manger [36].\r
-     *\r
-     * As for $l...  to quote from {@link http://tools.ietf.org/html/rfc3447#page-17 RFC3447#page-17}:\r
-     *\r
-     *    Both the encryption and the decryption operations of RSAES-OAEP take\r
-     *    the value of a label L as input.  In this version of PKCS #1, L is\r
-     *    the empty string; other uses of the label are outside the scope of\r
-     *    this document.\r
-     *\r
-     * @access private\r
-     * @param String $c\r
-     * @param String $l\r
-     * @return String\r
-     */\r
-    function _rsaes_oaep_decrypt($c, $l = '')\r
-    {\r
-        // Length checking\r
-\r
-        // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error\r
-        // be output.\r
-\r
-        if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) {\r
-            user_error('Decryption error', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        // RSA decryption\r
-\r
-        $c = $this->_os2ip($c);\r
-        $m = $this->_rsadp($c);\r
-        if ($m === false) {\r
-            user_error('Decryption error', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-        $em = $this->_i2osp($m, $this->k);\r
-\r
-        // EME-OAEP decoding\r
-\r
-        $lHash = $this->hash->hash($l);\r
-        $y = ord($em[0]);\r
-        $maskedSeed = substr($em, 1, $this->hLen);\r
-        $maskedDB = substr($em, $this->hLen + 1);\r
-        $seedMask = $this->_mgf1($maskedDB, $this->hLen);\r
-        $seed = $maskedSeed ^ $seedMask;\r
-        $dbMask = $this->_mgf1($seed, $this->k - $this->hLen - 1);\r
-        $db = $maskedDB ^ $dbMask;\r
-        $lHash2 = substr($db, 0, $this->hLen);\r
-        $m = substr($db, $this->hLen);\r
-        if ($lHash != $lHash2) {\r
-            user_error('Decryption error', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-        $m = ltrim($m, chr(0));\r
-        if (ord($m[0]) != 1) {\r
-            user_error('Decryption error', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        // Output the message M\r
-\r
-        return substr($m, 1);\r
-    }\r
-\r
-    /**\r
-     * RSAES-PKCS1-V1_5-ENCRYPT\r
-     *\r
-     * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.1 RFC3447#section-7.2.1}.\r
-     *\r
-     * @access private\r
-     * @param String $m\r
-     * @return String\r
-     */\r
-    function _rsaes_pkcs1_v1_5_encrypt($m)\r
-    {\r
-        $mLen = strlen($m);\r
-\r
-        // Length checking\r
-\r
-        if ($mLen > $this->k - 11) {\r
-            user_error('Message too long', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        // EME-PKCS1-v1_5 encoding\r
-\r
-        $ps = $this->_random($this->k - $mLen - 3, true);\r
-        $em = chr(0) . chr(2) . $ps . chr(0) . $m;\r
-\r
-        // RSA encryption\r
-        $m = $this->_os2ip($em);\r
-        $c = $this->_rsaep($m);\r
-        $c = $this->_i2osp($c, $this->k);\r
-\r
-        // Output the ciphertext C\r
-\r
-        return $c;\r
-    }\r
-\r
-    /**\r
-     * RSAES-PKCS1-V1_5-DECRYPT\r
-     *\r
-     * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.2 RFC3447#section-7.2.2}.\r
-     *\r
-     * For compatability purposes, this function departs slightly from the description given in RFC3447.\r
-     * The reason being that RFC2313#section-8.1 (PKCS#1 v1.5) states that ciphertext's encrypted by the\r
-     * private key should have the second byte set to either 0 or 1 and that ciphertext's encrypted by the\r
-     * public key should have the second byte set to 2.  In RFC3447 (PKCS#1 v2.1), the second byte is supposed\r
-     * to be 2 regardless of which key is used.  for compatability purposes, we'll just check to make sure the\r
-     * second byte is 2 or less.  If it is, we'll accept the decrypted string as valid.\r
-     *\r
-     * As a consequence of this, a private key encrypted ciphertext produced with Crypt_RSA may not decrypt\r
-     * with a strictly PKCS#1 v1.5 compliant RSA implementation.  Public key encrypted ciphertext's should but\r
-     * not private key encrypted ciphertext's.\r
-     *\r
-     * @access private\r
-     * @param String $c\r
-     * @return String\r
-     */\r
-    function _rsaes_pkcs1_v1_5_decrypt($c)\r
-    {\r
-        // Length checking\r
-\r
-        if (strlen($c) != $this->k) { // or if k < 11\r
-            user_error('Decryption error', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        // RSA decryption\r
-\r
-        $c = $this->_os2ip($c);\r
-        $m = $this->_rsadp($c);\r
-        if ($m === false) {\r
-            user_error('Decryption error', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-        $em = $this->_i2osp($m, $this->k);\r
-\r
-        // EME-PKCS1-v1_5 decoding\r
-\r
-        if (ord($em[0]) != 0 || ord($em[1]) > 2) {\r
-            user_error('Decryption error', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        $ps = substr($em, 2, strpos($em, chr(0), 2) - 2);\r
-        $m = substr($em, strlen($ps) + 3);\r
-\r
-        if (strlen($ps) < 8) {\r
-            user_error('Decryption error', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        // Output M\r
-\r
-        return $m;\r
-    }\r
-\r
-    /**\r
-     * EMSA-PSS-ENCODE\r
-     *\r
-     * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.1 RFC3447#section-9.1.1}.\r
-     *\r
-     * @access private\r
-     * @param String $m\r
-     * @param Integer $emBits\r
-     */\r
-    function _emsa_pss_encode($m, $emBits)\r
-    {\r
-        // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error\r
-        // be output.\r
-\r
-        $emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8)\r
-        $sLen = $this->sLen == false ? $this->hLen : $this->sLen;\r
-\r
-        $mHash = $this->hash->hash($m);\r
-        if ($emLen < $this->hLen + $sLen + 2) {\r
-            user_error('Encoding error', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        $salt = $this->_random($sLen);\r
-        $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt;\r
-        $h = $this->hash->hash($m2);\r
-        $ps = str_repeat(chr(0), $emLen - $sLen - $this->hLen - 2);\r
-        $db = $ps . chr(1) . $salt;\r
-        $dbMask = $this->_mgf1($h, $emLen - $this->hLen - 1);\r
-        $maskedDB = $db ^ $dbMask;\r
-        $maskedDB[0] = ~chr(0xFF << ($emBits & 7)) & $maskedDB[0];\r
-        $em = $maskedDB . $h . chr(0xBC);\r
-\r
-        return $em;\r
-    }\r
-\r
-    /**\r
-     * EMSA-PSS-VERIFY\r
-     *\r
-     * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.2 RFC3447#section-9.1.2}.\r
-     *\r
-     * @access private\r
-     * @param String $m\r
-     * @param String $em\r
-     * @param Integer $emBits\r
-     * @return String\r
-     */\r
-    function _emsa_pss_verify($m, $em, $emBits)\r
-    {\r
-        // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error\r
-        // be output.\r
-\r
-        $emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8);\r
-        $sLen = $this->sLen == false ? $this->hLen : $this->sLen;\r
-\r
-        $mHash = $this->hash->hash($m);\r
-        if ($emLen < $this->hLen + $sLen + 2) {\r
-            return false;\r
-        }\r
-\r
-        if ($em[strlen($em) - 1] != chr(0xBC)) {\r
-            return false;\r
-        }\r
-\r
-        $maskedDB = substr($em, 0, $em - $this->hLen - 1);\r
-        $h = substr($em, $em - $this->hLen - 1, $this->hLen);\r
-        $temp = chr(0xFF << ($emBits & 7));\r
-        if ((~$maskedDB[0] & $temp) != $temp) {\r
-            return false;\r
-        }\r
-        $dbMask = $this->_mgf1($h, $emLen - $this->hLen - 1);\r
-        $db = $maskedDB ^ $dbMask;\r
-        $db[0] = ~chr(0xFF << ($emBits & 7)) & $db[0];\r
-        $temp = $emLen - $this->hLen - $sLen - 2;\r
-        if (substr($db, 0, $temp) != str_repeat(chr(0), $temp) || ord($db[$temp]) != 1) {\r
-            return false;\r
-        }\r
-        $salt = substr($db, $temp + 1); // should be $sLen long\r
-        $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt;\r
-        $h2 = $this->hash->hash($m2);\r
-        return $h == $h2;\r
-    }\r
-\r
-    /**\r
-     * RSASSA-PSS-SIGN\r
-     *\r
-     * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.1 RFC3447#section-8.1.1}.\r
-     *\r
-     * @access private\r
-     * @param String $m\r
-     * @return String\r
-     */\r
-    function _rsassa_pss_sign($m)\r
-    {\r
-        // EMSA-PSS encoding\r
-\r
-        $em = $this->_emsa_pss_encode($m, 8 * $this->k - 1);\r
-\r
-        // RSA signature\r
-\r
-        $m = $this->_os2ip($em);\r
-        $s = $this->_rsasp1($m);\r
-        $s = $this->_i2osp($s, $this->k);\r
-\r
-        // Output the signature S\r
-\r
-        return $s;\r
-    }\r
-\r
-    /**\r
-     * RSASSA-PSS-VERIFY\r
-     *\r
-     * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.2 RFC3447#section-8.1.2}.\r
-     *\r
-     * @access private\r
-     * @param String $m\r
-     * @param String $s\r
-     * @return String\r
-     */\r
-    function _rsassa_pss_verify($m, $s)\r
-    {\r
-        // Length checking\r
-\r
-        if (strlen($s) != $this->k) {\r
-            user_error('Invalid signature', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        // RSA verification\r
-\r
-        $modBits = 8 * $this->k;\r
-\r
-        $s2 = $this->_os2ip($s);\r
-        $m2 = $this->_rsavp1($s2);\r
-        if ($m2 === false) {\r
-            user_error('Invalid signature', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-        $em = $this->_i2osp($m2, $modBits >> 3);\r
-        if ($em === false) {\r
-            user_error('Invalid signature', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        // EMSA-PSS verification\r
-\r
-        return $this->_emsa_pss_verify($m, $em, $modBits - 1);\r
-    }\r
-\r
-    /**\r
-     * EMSA-PKCS1-V1_5-ENCODE\r
-     *\r
-     * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}.\r
-     *\r
-     * @access private\r
-     * @param String $m\r
-     * @param Integer $emLen\r
-     * @return String\r
-     */\r
-    function _emsa_pkcs1_v1_5_encode($m, $emLen)\r
-    {\r
-        $h = $this->hash->hash($m);\r
-        if ($h === false) {\r
-            return false;\r
-        }\r
-\r
-        // see http://tools.ietf.org/html/rfc3447#page-43\r
-        switch ($this->hashName) {\r
-            case 'md2':\r
-                $t = pack('H*', '3020300c06082a864886f70d020205000410');\r
-                break;\r
-            case 'md5':\r
-                $t = pack('H*', '3020300c06082a864886f70d020505000410');\r
-                break;\r
-            case 'sha1':\r
-                $t = pack('H*', '3021300906052b0e03021a05000414');\r
-                break;\r
-            case 'sha256':\r
-                $t = pack('H*', '3031300d060960864801650304020105000420');\r
-                break;\r
-            case 'sha384':\r
-                $t = pack('H*', '3041300d060960864801650304020205000430');\r
-                break;\r
-            case 'sha512':\r
-                $t = pack('H*', '3051300d060960864801650304020305000440');\r
-        }\r
-        $t.= $h;\r
-        $tLen = strlen($t);\r
-\r
-        if ($emLen < $tLen + 11) {\r
-            user_error('Intended encoded message length too short', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);\r
-\r
-        $em = "\0\1$ps\0$t";\r
-\r
-        return $em;\r
-    }\r
-\r
-    /**\r
-     * RSASSA-PKCS1-V1_5-SIGN\r
-     *\r
-     * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.1 RFC3447#section-8.2.1}.\r
-     *\r
-     * @access private\r
-     * @param String $m\r
-     * @return String\r
-     */\r
-    function _rsassa_pkcs1_v1_5_sign($m)\r
-    {\r
-        // EMSA-PKCS1-v1_5 encoding\r
-\r
-        $em = $this->_emsa_pkcs1_v1_5_encode($m, $this->k);\r
-        if ($em === false) {\r
-            user_error('RSA modulus too short', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        // RSA signature\r
-\r
-        $m = $this->_os2ip($em);\r
-        $s = $this->_rsasp1($m);\r
-        $s = $this->_i2osp($s, $this->k);\r
-\r
-        // Output the signature S\r
-\r
-        return $s;\r
-    }\r
-\r
-    /**\r
-     * RSASSA-PKCS1-V1_5-VERIFY\r
-     *\r
-     * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.2 RFC3447#section-8.2.2}.\r
-     *\r
-     * @access private\r
-     * @param String $m\r
-     * @return String\r
-     */\r
-    function _rsassa_pkcs1_v1_5_verify($m, $s)\r
-    {\r
-        // Length checking\r
-\r
-        if (strlen($s) != $this->k) {\r
-            user_error('Invalid signature', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        // RSA verification\r
-\r
-        $s = $this->_os2ip($s);\r
-        $m2 = $this->_rsavp1($s);\r
-        if ($m2 === false) {\r
-            user_error('Invalid signature', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-        $em = $this->_i2osp($m2, $this->k);\r
-        if ($em === false) {\r
-            user_error('Invalid signature', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        // EMSA-PKCS1-v1_5 encoding\r
-\r
-        $em2 = $this->_emsa_pkcs1_v1_5_encode($m, $this->k);\r
-        if ($em2 === false) {\r
-            user_error('RSA modulus too short', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        // Compare\r
-\r
-        return $em === $em2;\r
-    }\r
-\r
-    /**\r
-     * Set Encryption Mode\r
-     *\r
-     * Valid values include CRYPT_RSA_ENCRYPTION_OAEP and CRYPT_RSA_ENCRYPTION_PKCS1.\r
-     *\r
-     * @access public\r
-     * @param Integer $mode\r
-     */\r
-    function setEncryptionMode($mode)\r
-    {\r
-        $this->encryptionMode = $mode;\r
-    }\r
-\r
-    /**\r
-     * Set Signature Mode\r
-     *\r
-     * Valid values include CRYPT_RSA_SIGNATURE_PSS and CRYPT_RSA_SIGNATURE_PKCS1\r
-     *\r
-     * @access public\r
-     * @param Integer $mode\r
-     */\r
-    function setSignatureMode($mode)\r
-    {\r
-        $this->signatureMode = $mode;\r
-    }\r
-\r
-    /**\r
-     * Encryption\r
-     *\r
-     * Both CRYPT_RSA_ENCRYPTION_OAEP and CRYPT_RSA_ENCRYPTION_PKCS1 both place limits on how long $plaintext can be.\r
-     * If $plaintext exceeds those limits it will be broken up so that it does and the resultant ciphertext's will\r
-     * be concatenated together.\r
-     *\r
-     * @see decrypt()\r
-     * @access public\r
-     * @param String $plaintext\r
-     * @return String\r
-     */\r
-    function encrypt($plaintext)\r
-    {\r
-        switch ($this->encryptionMode) {\r
-            case CRYPT_RSA_ENCRYPTION_PKCS1:\r
-                $length = $this->k - 11;\r
-                if ($length <= 0) {\r
-                    return false;\r
-                }\r
-\r
-                $plaintext = str_split($plaintext, $length);\r
-                $ciphertext = '';\r
-                foreach ($plaintext as $m) {\r
-                    $ciphertext.= $this->_rsaes_pkcs1_v1_5_encrypt($m);\r
-                }\r
-                return $ciphertext;\r
-            //case CRYPT_RSA_ENCRYPTION_OAEP:\r
-            default:\r
-                $length = $this->k - 2 * $this->hLen - 2;\r
-                if ($length <= 0) {\r
-                    return false;\r
-                }\r
-\r
-                $plaintext = str_split($plaintext, $length);\r
-                $ciphertext = '';\r
-                foreach ($plaintext as $m) {\r
-                    $ciphertext.= $this->_rsaes_oaep_encrypt($m);\r
-                }\r
-                return $ciphertext;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Decryption\r
-     *\r
-     * @see encrypt()\r
-     * @access public\r
-     * @param String $plaintext\r
-     * @return String\r
-     */\r
-    function decrypt($ciphertext)\r
-    {\r
-        if ($this->k <= 0) {\r
-            return false;\r
-        }\r
-\r
-        $ciphertext = str_split($ciphertext, $this->k);\r
-        $plaintext = '';\r
-\r
-        switch ($this->encryptionMode) {\r
-            case CRYPT_RSA_ENCRYPTION_PKCS1:\r
-                $decrypt = '_rsaes_pkcs1_v1_5_decrypt';\r
-                break;\r
-            //case CRYPT_RSA_ENCRYPTION_OAEP:\r
-            default:\r
-                $decrypt = '_rsaes_oaep_decrypt';\r
-        }\r
-\r
-        foreach ($ciphertext as $c) {\r
-            $temp = $this->$decrypt($c);\r
-            if ($temp === false) {\r
-                return false;\r
-            }\r
-            $plaintext.= $temp;\r
-        }\r
-\r
-        return $plaintext;\r
-    }\r
-\r
-    /**\r
-     * Create a signature\r
-     *\r
-     * @see verify()\r
-     * @access public\r
-     * @param String $message\r
-     * @return String\r
-     */\r
-    function sign($message)\r
-    {\r
-        if (empty($this->modulus) || empty($this->exponent)) {\r
-            return false;\r
-        }\r
-\r
-        switch ($this->signatureMode) {\r
-            case CRYPT_RSA_SIGNATURE_PKCS1:\r
-                return $this->_rsassa_pkcs1_v1_5_sign($message);\r
-            //case CRYPT_RSA_SIGNATURE_PSS:\r
-            default:\r
-                return $this->_rsassa_pss_sign($message);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Verifies a signature\r
-     *\r
-     * @see sign()\r
-     * @access public\r
-     * @param String $message\r
-     * @param String $signature\r
-     * @return Boolean\r
-     */\r
-    function verify($message, $signature)\r
-    {\r
-        if (empty($this->modulus) || empty($this->exponent)) {\r
-            return false;\r
-        }\r
-\r
-        switch ($this->signatureMode) {\r
-            case CRYPT_RSA_SIGNATURE_PKCS1:\r
-                return $this->_rsassa_pkcs1_v1_5_verify($message, $signature);\r
-            //case CRYPT_RSA_SIGNATURE_PSS:\r
-            default:\r
-                return $this->_rsassa_pss_verify($message, $signature);\r
-        }\r
-    }\r
-}
\ No newline at end of file
diff --git a/library/phpsec/Crypt/Random.php b/library/phpsec/Crypt/Random.php
deleted file mode 100644 (file)
index a91c4d3..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-<?php\r
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */\r
-\r
-/**\r
- * Random Number Generator\r
- *\r
- * PHP versions 4 and 5\r
- *\r
- * Here's a short example of how to use this library:\r
- * <code>\r
- * <?php\r
- *    include('Crypt/Random.php');\r
- *\r
- *    echo crypt_random();\r
- * ?>\r
- * </code>\r
- *\r
- * LICENSE: This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,\r
- * MA  02111-1307  USA\r
- *\r
- * @category   Crypt\r
- * @package    Crypt_Random\r
- * @author     Jim Wigginton <terrafrost@php.net>\r
- * @copyright  MMVII Jim Wigginton\r
- * @license    http://www.gnu.org/licenses/lgpl.txt\r
- * @version    $Id: Random.php,v 1.9 2010/04/24 06:40:48 terrafrost Exp $\r
- * @link       http://phpseclib.sourceforge.net\r
- */\r
-\r
-/**\r
- * Generate a random value.\r
- *\r
- * On 32-bit machines, the largest distance that can exist between $min and $max is 2**31.\r
- * If $min and $max are farther apart than that then the last ($max - range) numbers.\r
- *\r
- * Depending on how this is being used, it may be worth while to write a replacement.  For example,\r
- * a PHP-based web app that stores its data in an SQL database can collect more entropy than this function\r
- * can.\r
- *\r
- * @param optional Integer $min\r
- * @param optional Integer $max\r
- * @return Integer\r
- * @access public\r
- */\r
-function crypt_random($min = 0, $max = 0x7FFFFFFF)\r
-{\r
-    if ($min == $max) {\r
-        return $min;\r
-    }\r
-\r
-    // see http://en.wikipedia.org/wiki//dev/random\r
-    // if open_basedir is enabled file_exists() will ouput an "open_basedir restriction in effect" warning,\r
-    // so we suppress it.\r
-    if (@file_exists('/dev/urandom')) {\r
-        static $fp;\r
-        if (!$fp) {\r
-            $fp = fopen('/dev/urandom', 'rb');\r
-        }\r
-        extract(unpack('Nrandom', fread($fp, 4)));\r
-\r
-        // say $min = 0 and $max = 3.  if we didn't do abs() then we could have stuff like this:\r
-        // -4 % 3 + 0 = -1, even though -1 < $min\r
-        return abs($random) % ($max - $min) + $min;\r
-    }\r
-\r
-    /* Prior to PHP 4.2.0, mt_srand() had to be called before mt_rand() could be called.\r
-       Prior to PHP 5.2.6, mt_rand()'s automatic seeding was subpar, as elaborated here:\r
-\r
-       http://www.suspekt.org/2008/08/17/mt_srand-and-not-so-random-numbers/\r
-\r
-       The seeding routine is pretty much ripped from PHP's own internal GENERATE_SEED() macro:\r
-\r
-       http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3_2/ext/standard/php_rand.h?view=markup */\r
-    if (version_compare(PHP_VERSION, '5.2.5', '<=')) { \r
-        static $seeded;\r
-        if (!isset($seeded)) {\r
-            $seeded = true;\r
-            mt_srand(fmod(time() * getmypid(), 0x7FFFFFFF) ^ fmod(1000000 * lcg_value(), 0x7FFFFFFF));\r
-        }\r
-    }\r
-\r
-    static $crypto;\r
-\r
-    // The CSPRNG's Yarrow and Fortuna periodically reseed.  This function can be reseeded by hitting F5\r
-    // in the browser and reloading the page.\r
-\r
-    if (!isset($crypto)) {\r
-        $key = $iv = '';\r
-        for ($i = 0; $i < 8; $i++) {\r
-            $key.= pack('n', mt_rand(0, 0xFFFF));\r
-            $iv .= pack('n', mt_rand(0, 0xFFFF));\r
-        }\r
-        switch (true) {\r
-            case class_exists('Crypt_AES'):\r
-                $crypto = new Crypt_AES(CRYPT_AES_MODE_CTR);\r
-                break;\r
-            case class_exists('Crypt_TripleDES'):\r
-                $crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);\r
-                break;\r
-            case class_exists('Crypt_DES'):\r
-                $crypto = new Crypt_DES(CRYPT_DES_MODE_CTR);\r
-                break;\r
-            case class_exists('Crypt_RC4'):\r
-                $crypto = new Crypt_RC4();\r
-                break;\r
-            default:\r
-                extract(unpack('Nrandom', pack('H*', sha1(mt_rand(0, 0x7FFFFFFF)))));\r
-                return abs($random) % ($max - $min) + $min;\r
-        }\r
-        $crypto->setKey($key);\r
-        $crypto->setIV($iv);\r
-        $crypto->enableContinuousBuffer();\r
-    }\r
-\r
-    extract(unpack('Nrandom', $crypto->encrypt("\0\0\0\0")));\r
-    return abs($random) % ($max - $min) + $min;\r
-}\r
-?>
\ No newline at end of file
diff --git a/library/phpsec/Crypt/Rijndael.php b/library/phpsec/Crypt/Rijndael.php
deleted file mode 100644 (file)
index f141f37..0000000
+++ /dev/null
@@ -1,1242 +0,0 @@
-<?php\r
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */\r
-\r
-/**\r
- * Pure-PHP implementation of Rijndael.\r
- *\r
- * Does not use mcrypt, even when available, for reasons that are explained below.\r
- *\r
- * PHP versions 4 and 5\r
- *\r
- * If {@link Crypt_Rijndael::setBlockLength() setBlockLength()} isn't called, it'll be assumed to be 128 bits.  If \r
- * {@link Crypt_Rijndael::setKeyLength() setKeyLength()} isn't called, it'll be calculated from \r
- * {@link Crypt_Rijndael::setKey() setKey()}.  ie. if the key is 128-bits, the key length will be 128-bits.  If it's \r
- * 136-bits it'll be null-padded to 160-bits and 160 bits will be the key length until \r
- * {@link Crypt_Rijndael::setKey() setKey()} is called, again, at which point, it'll be recalculated.\r
- *\r
- * Not all Rijndael implementations may support 160-bits or 224-bits as the block length / key length.  mcrypt, for example,\r
- * does not.  AES, itself, only supports block lengths of 128 and key lengths of 128, 192, and 256.\r
- * {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=10 Rijndael-ammended.pdf#page=10} defines the\r
- * algorithm for block lengths of 192 and 256 but not for block lengths / key lengths of 160 and 224.  Indeed, 160 and 224\r
- * are first defined as valid key / block lengths in \r
- * {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=44 Rijndael-ammended.pdf#page=44}: \r
- * Extensions: Other block and Cipher Key lengths.\r
- *\r
- * {@internal The variable names are the same as those in \r
- * {@link http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf#page=10 fips-197.pdf#page=10}.}}\r
- *\r
- * Here's a short example of how to use this library:\r
- * <code>\r
- * <?php\r
- *    include('Crypt/Rijndael.php');\r
- *\r
- *    $rijndael = new Crypt_Rijndael();\r
- *\r
- *    $rijndael->setKey('abcdefghijklmnop');\r
- *\r
- *    $size = 10 * 1024;\r
- *    $plaintext = '';\r
- *    for ($i = 0; $i < $size; $i++) {\r
- *        $plaintext.= 'a';\r
- *    }\r
- *\r
- *    echo $rijndael->decrypt($rijndael->encrypt($plaintext));\r
- * ?>\r
- * </code>\r
- *\r
- * LICENSE: This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,\r
- * MA  02111-1307  USA\r
- *\r
- * @category   Crypt\r
- * @package    Crypt_Rijndael\r
- * @author     Jim Wigginton <terrafrost@php.net>\r
- * @copyright  MMVIII Jim Wigginton\r
- * @license    http://www.gnu.org/licenses/lgpl.txt\r
- * @version    $Id: Rijndael.php,v 1.12 2010/02/09 06:10:26 terrafrost Exp $\r
- * @link       http://phpseclib.sourceforge.net\r
- */\r
-\r
-/**#@+\r
- * @access public\r
- * @see Crypt_Rijndael::encrypt()\r
- * @see Crypt_Rijndael::decrypt()\r
- */\r
-/**\r
- * Encrypt / decrypt using the Counter mode.\r
- *\r
- * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.\r
- *\r
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29\r
- */\r
-define('CRYPT_RIJNDAEL_MODE_CTR', -1);\r
-/**\r
- * Encrypt / decrypt using the Electronic Code Book mode.\r
- *\r
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29\r
- */\r
-define('CRYPT_RIJNDAEL_MODE_ECB', 1);\r
-/**\r
- * Encrypt / decrypt using the Code Book Chaining mode.\r
- *\r
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29\r
- */\r
-define('CRYPT_RIJNDAEL_MODE_CBC', 2);\r
-/**#@-*/\r
-\r
-/**#@+\r
- * @access private\r
- * @see Crypt_Rijndael::Crypt_Rijndael()\r
- */\r
-/**\r
- * Toggles the internal implementation\r
- */\r
-define('CRYPT_RIJNDAEL_MODE_INTERNAL', 1);\r
-/**\r
- * Toggles the mcrypt implementation\r
- */\r
-define('CRYPT_RIJNDAEL_MODE_MCRYPT', 2);\r
-/**#@-*/\r
-\r
-/**\r
- * Pure-PHP implementation of Rijndael.\r
- *\r
- * @author  Jim Wigginton <terrafrost@php.net>\r
- * @version 0.1.0\r
- * @access  public\r
- * @package Crypt_Rijndael\r
- */\r
-class Crypt_Rijndael {\r
-    /**\r
-     * The Encryption Mode\r
-     *\r
-     * @see Crypt_Rijndael::Crypt_Rijndael()\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $mode;\r
-\r
-    /**\r
-     * The Key\r
-     *\r
-     * @see Crypt_Rijndael::setKey()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";\r
-\r
-    /**\r
-     * The Initialization Vector\r
-     *\r
-     * @see Crypt_Rijndael::setIV()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $iv = '';\r
-\r
-    /**\r
-     * A "sliding" Initialization Vector\r
-     *\r
-     * @see Crypt_Rijndael::enableContinuousBuffer()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $encryptIV = '';\r
-\r
-    /**\r
-     * A "sliding" Initialization Vector\r
-     *\r
-     * @see Crypt_Rijndael::enableContinuousBuffer()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $decryptIV = '';\r
-\r
-    /**\r
-     * Continuous Buffer status\r
-     *\r
-     * @see Crypt_Rijndael::enableContinuousBuffer()\r
-     * @var Boolean\r
-     * @access private\r
-     */\r
-    var $continuousBuffer = false;\r
-\r
-    /**\r
-     * Padding status\r
-     *\r
-     * @see Crypt_Rijndael::enablePadding()\r
-     * @var Boolean\r
-     * @access private\r
-     */\r
-    var $padding = true;\r
-\r
-    /**\r
-     * Does the key schedule need to be (re)calculated?\r
-     *\r
-     * @see setKey()\r
-     * @see setBlockLength()\r
-     * @see setKeyLength()\r
-     * @var Boolean\r
-     * @access private\r
-     */\r
-    var $changed = true;\r
-\r
-    /**\r
-     * Has the key length explicitly been set or should it be derived from the key, itself?\r
-     *\r
-     * @see setKeyLength()\r
-     * @var Boolean\r
-     * @access private\r
-     */\r
-    var $explicit_key_length = false;\r
-\r
-    /**\r
-     * The Key Schedule\r
-     *\r
-     * @see _setup()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $w;\r
-\r
-    /**\r
-     * The Inverse Key Schedule\r
-     *\r
-     * @see _setup()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $dw;\r
-\r
-    /**\r
-     * The Block Length\r
-     *\r
-     * @see setBlockLength()\r
-     * @var Integer\r
-     * @access private\r
-     * @internal The max value is 32, the min value is 16.  All valid values are multiples of 4.  Exists in conjunction with\r
-     *     $Nb because we need this value and not $Nb to pad strings appropriately.  \r
-     */\r
-    var $block_size = 16;\r
-\r
-    /**\r
-     * The Block Length divided by 32\r
-     *\r
-     * @see setBlockLength()\r
-     * @var Integer\r
-     * @access private\r
-     * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4.  Exists in conjunction with $block_size \r
-     *    because the encryption / decryption / key schedule creation requires this number and not $block_size.  We could \r
-     *    derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu\r
-     *    of that, we'll just precompute it once.\r
-     *\r
-     */\r
-    var $Nb = 4;\r
-\r
-    /**\r
-     * The Key Length\r
-     *\r
-     * @see setKeyLength()\r
-     * @var Integer\r
-     * @access private\r
-     * @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16.  Exists in conjunction with $key_size\r
-     *    because the encryption / decryption / key schedule creation requires this number and not $key_size.  We could \r
-     *    derive this from $key_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu\r
-     *    of that, we'll just precompute it once.\r
-     */\r
-    var $key_size = 16;\r
-\r
-    /**\r
-     * The Key Length divided by 32\r
-     *\r
-     * @see setKeyLength()\r
-     * @var Integer\r
-     * @access private\r
-     * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4\r
-     */\r
-    var $Nk = 4;\r
-\r
-    /**\r
-     * The Number of Rounds\r
-     *\r
-     * @var Integer\r
-     * @access private\r
-     * @internal The max value is 14, the min value is 10.\r
-     */\r
-    var $Nr;\r
-\r
-    /**\r
-     * Shift offsets\r
-     *\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $c;\r
-\r
-    /**\r
-     * Precomputed mixColumns table\r
-     *\r
-     * @see Crypt_Rijndael()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $t0;\r
-\r
-    /**\r
-     * Precomputed mixColumns table\r
-     *\r
-     * @see Crypt_Rijndael()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $t1;\r
-\r
-    /**\r
-     * Precomputed mixColumns table\r
-     *\r
-     * @see Crypt_Rijndael()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $t2;\r
-\r
-    /**\r
-     * Precomputed mixColumns table\r
-     *\r
-     * @see Crypt_Rijndael()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $t3;\r
-\r
-    /**\r
-     * Precomputed invMixColumns table\r
-     *\r
-     * @see Crypt_Rijndael()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $dt0;\r
-\r
-    /**\r
-     * Precomputed invMixColumns table\r
-     *\r
-     * @see Crypt_Rijndael()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $dt1;\r
-\r
-    /**\r
-     * Precomputed invMixColumns table\r
-     *\r
-     * @see Crypt_Rijndael()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $dt2;\r
-\r
-    /**\r
-     * Precomputed invMixColumns table\r
-     *\r
-     * @see Crypt_Rijndael()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $dt3;\r
-\r
-    /**\r
-     * Default Constructor.\r
-     *\r
-     * Determines whether or not the mcrypt extension should be used.  $mode should only, at present, be\r
-     * CRYPT_RIJNDAEL_MODE_ECB or CRYPT_RIJNDAEL_MODE_CBC.  If not explictly set, CRYPT_RIJNDAEL_MODE_CBC will be used.\r
-     *\r
-     * @param optional Integer $mode\r
-     * @return Crypt_Rijndael\r
-     * @access public\r
-     */\r
-    function Crypt_Rijndael($mode = CRYPT_RIJNDAEL_MODE_CBC)\r
-    {\r
-        switch ($mode) {\r
-            case CRYPT_RIJNDAEL_MODE_ECB:\r
-            case CRYPT_RIJNDAEL_MODE_CBC:\r
-            case CRYPT_RIJNDAEL_MODE_CTR:\r
-                $this->mode = $mode;\r
-                break;\r
-            default:\r
-                $this->mode = CRYPT_RIJNDAEL_MODE_CBC;\r
-        }\r
-\r
-        $t3 = &$this->t3;\r
-        $t2 = &$this->t2;\r
-        $t1 = &$this->t1;\r
-        $t0 = &$this->t0;\r
-\r
-        $dt3 = &$this->dt3;\r
-        $dt2 = &$this->dt2;\r
-        $dt1 = &$this->dt1;\r
-        $dt0 = &$this->dt0;\r
-\r
-        // according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=19> (section 5.2.1), \r
-        // precomputed tables can be used in the mixColumns phase.  in that example, they're assigned t0...t3, so\r
-        // those are the names we'll use.\r
-        $t3 = array(\r
-            0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491, \r
-            0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC, \r
-            0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB, \r
-            0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B, \r
-            0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83, \r
-            0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A, \r
-            0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F, \r
-            0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA, \r
-            0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B, \r
-            0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713, \r
-            0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6, \r
-            0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85, \r
-            0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411, \r
-            0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B, \r
-            0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1, \r
-            0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF, \r
-            0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E, \r
-            0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6, \r
-            0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B, \r
-            0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD, \r
-            0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8, \r
-            0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2, \r
-            0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049, \r
-            0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810, \r
-            0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197, \r
-            0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F, \r
-            0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C, \r
-            0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927, \r
-            0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733, \r
-            0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5, \r
-            0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0, \r
-            0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C\r
-        );\r
-\r
-        $dt3 = array(\r
-            0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B, \r
-            0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5, \r
-            0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B, \r
-            0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E, \r
-            0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D, \r
-            0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9, \r
-            0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66, \r
-            0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED, \r
-            0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4, \r
-            0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD, \r
-            0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60, \r
-            0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79, \r
-            0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C, \r
-            0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24, \r
-            0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C, \r
-            0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814, \r
-            0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B, \r
-            0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084, \r
-            0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077, \r
-            0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22, \r
-            0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F, \r
-            0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582, \r
-            0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB, \r
-            0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF, \r
-            0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035, \r
-            0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17, \r
-            0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46, \r
-            0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D, \r
-            0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A, \r
-            0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678, \r
-            0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF, \r
-            0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0\r
-        );\r
-\r
-        for ($i = 0; $i < 256; $i++) {\r
-            $t2[$i <<  8] = (($t3[$i] <<  8) & 0xFFFFFF00) | (($t3[$i] >> 24) & 0x000000FF);\r
-            $t1[$i << 16] = (($t3[$i] << 16) & 0xFFFF0000) | (($t3[$i] >> 16) & 0x0000FFFF);\r
-            $t0[$i << 24] = (($t3[$i] << 24) & 0xFF000000) | (($t3[$i] >>  8) & 0x00FFFFFF);\r
-\r
-            $dt2[$i <<  8] = (($this->dt3[$i] <<  8) & 0xFFFFFF00) | (($dt3[$i] >> 24) & 0x000000FF);\r
-            $dt1[$i << 16] = (($this->dt3[$i] << 16) & 0xFFFF0000) | (($dt3[$i] >> 16) & 0x0000FFFF);\r
-            $dt0[$i << 24] = (($this->dt3[$i] << 24) & 0xFF000000) | (($dt3[$i] >>  8) & 0x00FFFFFF);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Sets the key.\r
-     *\r
-     * Keys can be of any length.  Rijndael, itself, requires the use of a key that's between 128-bits and 256-bits long and\r
-     * whose length is a multiple of 32.  If the key is less than 256-bits and the key length isn't set, we round the length\r
-     * up to the closest valid key length, padding $key with null bytes.  If the key is more than 256-bits, we trim the\r
-     * excess bits.\r
-     *\r
-     * If the key is not explicitly set, it'll be assumed to be all null bytes.\r
-     *\r
-     * @access public\r
-     * @param String $key\r
-     */\r
-    function setKey($key)\r
-    {\r
-        $this->key = $key;\r
-        $this->changed = true;\r
-    }\r
-\r
-    /**\r
-     * Sets the initialization vector. (optional)\r
-     *\r
-     * SetIV is not required when CRYPT_RIJNDAEL_MODE_ECB is being used.  If not explictly set, it'll be assumed\r
-     * to be all zero's.\r
-     *\r
-     * @access public\r
-     * @param String $iv\r
-     */\r
-    function setIV($iv)\r
-    {\r
-        $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, $this->block_size), $this->block_size, chr(0));;\r
-    }\r
-\r
-    /**\r
-     * Sets the key length\r
-     *\r
-     * Valid key lengths are 128, 160, 192, 224, and 256.  If the length is less than 128, it will be rounded up to\r
-     * 128.  If the length is greater then 128 and invalid, it will be rounded down to the closest valid amount.\r
-     *\r
-     * @access public\r
-     * @param Integer $length\r
-     */\r
-    function setKeyLength($length)\r
-    {\r
-        $length >>= 5;\r
-        if ($length > 8) {\r
-            $length = 8;\r
-        } else if ($length < 4) {\r
-            $length = 4;\r
-        }\r
-        $this->Nk = $length;\r
-        $this->key_size = $length << 2;\r
-\r
-        $this->explicit_key_length = true;\r
-        $this->changed = true;\r
-    }\r
-\r
-    /**\r
-     * Sets the block length\r
-     *\r
-     * Valid block lengths are 128, 160, 192, 224, and 256.  If the length is less than 128, it will be rounded up to\r
-     * 128.  If the length is greater then 128 and invalid, it will be rounded down to the closest valid amount.\r
-     *\r
-     * @access public\r
-     * @param Integer $length\r
-     */\r
-    function setBlockLength($length)\r
-    {\r
-        $length >>= 5;\r
-        if ($length > 8) {\r
-            $length = 8;\r
-        } else if ($length < 4) {\r
-            $length = 4;\r
-        }\r
-        $this->Nb = $length;\r
-        $this->block_size = $length << 2;\r
-        $this->changed = true;\r
-    }\r
-\r
-    /**\r
-     * Generate CTR XOR encryption key\r
-     *\r
-     * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the\r
-     * plaintext / ciphertext in CTR mode.\r
-     *\r
-     * @see Crypt_Rijndael::decrypt()\r
-     * @see Crypt_Rijndael::encrypt()\r
-     * @access public\r
-     * @param Integer $length\r
-     * @param String $iv\r
-     */\r
-    function _generate_xor($length, &$iv)\r
-    {\r
-        $xor = '';\r
-        $block_size = $this->block_size;\r
-        $num_blocks = floor(($length + ($block_size - 1)) / $block_size);\r
-        for ($i = 0; $i < $num_blocks; $i++) {\r
-            $xor.= $iv;\r
-            for ($j = 4; $j <= $block_size; $j+=4) {\r
-                $temp = substr($iv, -$j, 4);\r
-                switch ($temp) {\r
-                    case "\xFF\xFF\xFF\xFF":\r
-                        $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);\r
-                        break;\r
-                    case "\x7F\xFF\xFF\xFF":\r
-                        $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);\r
-                        break 2;\r
-                    default:\r
-                        extract(unpack('Ncount', $temp));\r
-                        $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);\r
-                        break 2;\r
-                }\r
-            }\r
-        }\r
-\r
-        return $xor;\r
-    }\r
-\r
-    /**\r
-     * Encrypts a message.\r
-     *\r
-     * $plaintext will be padded with additional bytes such that it's length is a multiple of the block size.  Other Rjindael\r
-     * implementations may or may not pad in the same manner.  Other common approaches to padding and the reasons why it's\r
-     * necessary are discussed in the following\r
-     * URL:\r
-     *\r
-     * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}\r
-     *\r
-     * An alternative to padding is to, separately, send the length of the file.  This is what SSH, in fact, does.\r
-     * strlen($plaintext) will still need to be a multiple of 8, however, arbitrary values can be added to make it that\r
-     * length.\r
-     *\r
-     * @see Crypt_Rijndael::decrypt()\r
-     * @access public\r
-     * @param String $plaintext\r
-     */\r
-    function encrypt($plaintext)\r
-    {\r
-        $this->_setup();\r
-        if ($this->mode != CRYPT_RIJNDAEL_MODE_CTR) {\r
-            $plaintext = $this->_pad($plaintext);\r
-        }\r
-\r
-        $block_size = $this->block_size;\r
-        $ciphertext = '';\r
-        switch ($this->mode) {\r
-            case CRYPT_RIJNDAEL_MODE_ECB:\r
-                for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {\r
-                    $ciphertext.= $this->_encryptBlock(substr($plaintext, $i, $block_size));\r
-                }\r
-                break;\r
-            case CRYPT_RIJNDAEL_MODE_CBC:\r
-                $xor = $this->encryptIV;\r
-                for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {\r
-                    $block = substr($plaintext, $i, $block_size);\r
-                    $block = $this->_encryptBlock($block ^ $xor);\r
-                    $xor = $block;\r
-                    $ciphertext.= $block;\r
-                }\r
-                if ($this->continuousBuffer) {\r
-                    $this->encryptIV = $xor;\r
-                }\r
-                break;\r
-            case CRYPT_RIJNDAEL_MODE_CTR:\r
-                $xor = $this->encryptIV;\r
-                for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {\r
-                    $block = substr($plaintext, $i, $block_size);\r
-                    $key = $this->_encryptBlock($this->_generate_xor($block_size, $xor));\r
-                    $ciphertext.= $block ^ $key;\r
-                }\r
-                if ($this->continuousBuffer) {\r
-                    $this->encryptIV = $xor;\r
-                }\r
-        }\r
-\r
-        return $ciphertext;\r
-    }\r
-\r
-    /**\r
-     * Decrypts a message.\r
-     *\r
-     * If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until\r
-     * it is.\r
-     *\r
-     * @see Crypt_Rijndael::encrypt()\r
-     * @access public\r
-     * @param String $ciphertext\r
-     */\r
-    function decrypt($ciphertext)\r
-    {\r
-        $this->_setup();\r
-\r
-        if ($this->mode != CRYPT_RIJNDAEL_MODE_CTR) {\r
-            // we pad with chr(0) since that's what mcrypt_generic does.  to quote from http://php.net/function.mcrypt-generic :\r
-            // "The data is padded with "\0" to make sure the length of the data is n * blocksize."\r
-            $ciphertext = str_pad($ciphertext, (strlen($ciphertext) + $this->block_size - 1) % $this->block_size, chr(0));\r
-        }\r
-\r
-        $block_size = $this->block_size;\r
-        $plaintext = '';\r
-        switch ($this->mode) {\r
-            case CRYPT_RIJNDAEL_MODE_ECB:\r
-                for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {\r
-                    $plaintext.= $this->_decryptBlock(substr($ciphertext, $i, $block_size));\r
-                }\r
-                break;\r
-            case CRYPT_RIJNDAEL_MODE_CBC:\r
-                $xor = $this->decryptIV;\r
-                for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {\r
-                    $block = substr($ciphertext, $i, $block_size);\r
-                    $plaintext.= $this->_decryptBlock($block) ^ $xor;\r
-                    $xor = $block;\r
-                }\r
-                if ($this->continuousBuffer) {\r
-                    $this->decryptIV = $xor;\r
-                }\r
-                break;\r
-            case CRYPT_RIJNDAEL_MODE_CTR:\r
-                $xor = $this->decryptIV;\r
-                for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {\r
-                    $block = substr($ciphertext, $i, $block_size);\r
-                    $key = $this->_encryptBlock($this->_generate_xor($block_size, $xor));\r
-                    $plaintext.= $block ^ $key;\r
-                }\r
-                if ($this->continuousBuffer) {\r
-                    $this->decryptIV = $xor;\r
-                }\r
-        }\r
-\r
-        return $this->mode != CRYPT_RIJNDAEL_MODE_CTR ? $this->_unpad($plaintext) : $plaintext;\r
-    }\r
-\r
-    /**\r
-     * Encrypts a block\r
-     *\r
-     * @access private\r
-     * @param String $in\r
-     * @return String\r
-     */\r
-    function _encryptBlock($in)\r
-    {\r
-        $state = array();\r
-        $words = unpack('N*word', $in);\r
-\r
-        $w = $this->w;\r
-        $t0 = $this->t0;\r
-        $t1 = $this->t1;\r
-        $t2 = $this->t2;\r
-        $t3 = $this->t3;\r
-        $Nb = $this->Nb;\r
-        $Nr = $this->Nr;\r
-        $c = $this->c;\r
-\r
-        // addRoundKey\r
-        $i = 0;\r
-        foreach ($words as $word) {\r
-            $state[] = $word ^ $w[0][$i++];\r
-        }\r
-\r
-        // fips-197.pdf#page=19, "Figure 5. Pseudo Code for the Cipher", states that this loop has four components - \r
-        // subBytes, shiftRows, mixColumns, and addRoundKey. fips-197.pdf#page=30, "Implementation Suggestions Regarding \r
-        // Various Platforms" suggests that performs enhanced implementations are described in Rijndael-ammended.pdf.\r
-        // Rijndael-ammended.pdf#page=20, "Implementation aspects / 32-bit processor", discusses such an optimization.\r
-        // Unfortunately, the description given there is not quite correct.  Per aes.spec.v316.pdf#page=19 [1], \r
-        // equation (7.4.7) is supposed to use addition instead of subtraction, so we'll do that here, as well.\r
-\r
-        // [1] http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.v316.pdf\r
-        $temp = array();\r
-        for ($round = 1; $round < $Nr; $round++) {\r
-            $i = 0; // $c[0] == 0\r
-            $j = $c[1];\r
-            $k = $c[2];\r
-            $l = $c[3];\r
-\r
-            while ($i < $this->Nb) {\r
-                $temp[$i] = $t0[$state[$i] & 0xFF000000] ^ \r
-                            $t1[$state[$j] & 0x00FF0000] ^ \r
-                            $t2[$state[$k] & 0x0000FF00] ^ \r
-                            $t3[$state[$l] & 0x000000FF] ^ \r
-                            $w[$round][$i];\r
-                $i++;\r
-                $j = ($j + 1) % $Nb;\r
-                $k = ($k + 1) % $Nb;\r
-                $l = ($l + 1) % $Nb;\r
-            }\r
-\r
-            for ($i = 0; $i < $Nb; $i++) {\r
-                $state[$i] = $temp[$i];\r
-            }\r
-        }\r
-\r
-        // subWord\r
-        for ($i = 0; $i < $Nb; $i++) {\r
-            $state[$i] = $this->_subWord($state[$i]);\r
-        }\r
-\r
-        // shiftRows + addRoundKey\r
-        $i = 0; // $c[0] == 0\r
-        $j = $c[1];\r
-        $k = $c[2];\r
-        $l = $c[3];\r
-        while ($i < $this->Nb) {\r
-            $temp[$i] = ($state[$i] & 0xFF000000) ^ \r
-                        ($state[$j] & 0x00FF0000) ^ \r
-                        ($state[$k] & 0x0000FF00) ^ \r
-                        ($state[$l] & 0x000000FF) ^\r
-                         $w[$Nr][$i];\r
-            $i++;\r
-            $j = ($j + 1) % $Nb;\r
-            $k = ($k + 1) % $Nb;\r
-            $l = ($l + 1) % $Nb;\r
-        }\r
-        $state = $temp;\r
-\r
-        array_unshift($state, 'N*');\r
-\r
-        return call_user_func_array('pack', $state);\r
-    }\r
-\r
-    /**\r
-     * Decrypts a block\r
-     *\r
-     * @access private\r
-     * @param String $in\r
-     * @return String\r
-     */\r
-    function _decryptBlock($in)\r
-    {\r
-        $state = array();\r
-        $words = unpack('N*word', $in);\r
-\r
-        $num_states = count($state);\r
-        $dw = $this->dw;\r
-        $dt0 = $this->dt0;\r
-        $dt1 = $this->dt1;\r
-        $dt2 = $this->dt2;\r
-        $dt3 = $this->dt3;\r
-        $Nb = $this->Nb;\r
-        $Nr = $this->Nr;\r
-        $c = $this->c;\r
-\r
-        // addRoundKey\r
-        $i = 0;\r
-        foreach ($words as $word) {\r
-            $state[] = $word ^ $dw[$Nr][$i++];\r
-        }\r
-\r
-        $temp = array();\r
-        for ($round = $Nr - 1; $round > 0; $round--) {\r
-            $i = 0; // $c[0] == 0\r
-            $j = $Nb - $c[1];\r
-            $k = $Nb - $c[2];\r
-            $l = $Nb - $c[3];\r
-\r
-            while ($i < $Nb) {\r
-                $temp[$i] = $dt0[$state[$i] & 0xFF000000] ^ \r
-                            $dt1[$state[$j] & 0x00FF0000] ^ \r
-                            $dt2[$state[$k] & 0x0000FF00] ^ \r
-                            $dt3[$state[$l] & 0x000000FF] ^ \r
-                            $dw[$round][$i];\r
-                $i++;\r
-                $j = ($j + 1) % $Nb;\r
-                $k = ($k + 1) % $Nb;\r
-                $l = ($l + 1) % $Nb;\r
-            }\r
-\r
-            for ($i = 0; $i < $Nb; $i++) {\r
-                $state[$i] = $temp[$i];\r
-            }\r
-        }\r
-\r
-        // invShiftRows + invSubWord + addRoundKey\r
-        $i = 0; // $c[0] == 0\r
-        $j = $Nb - $c[1];\r
-        $k = $Nb - $c[2];\r
-        $l = $Nb - $c[3];\r
-\r
-        while ($i < $Nb) {\r
-            $temp[$i] = $dw[0][$i] ^ \r
-                        $this->_invSubWord(($state[$i] & 0xFF000000) | \r
-                                           ($state[$j] & 0x00FF0000) | \r
-                                           ($state[$k] & 0x0000FF00) | \r
-                                           ($state[$l] & 0x000000FF));\r
-            $i++;\r
-            $j = ($j + 1) % $Nb;\r
-            $k = ($k + 1) % $Nb;\r
-            $l = ($l + 1) % $Nb;\r
-        }\r
-\r
-        $state = $temp;\r
-\r
-        array_unshift($state, 'N*');\r
-\r
-        return call_user_func_array('pack', $state);\r
-    }\r
-\r
-    /**\r
-     * Setup Rijndael\r
-     *\r
-     * Validates all the variables and calculates $Nr - the number of rounds that need to be performed - and $w - the key\r
-     * key schedule.\r
-     *\r
-     * @access private\r
-     */\r
-    function _setup()\r
-    {\r
-        // Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field.\r
-        // See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse\r
-        static $rcon = array(0,\r
-            0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,\r
-            0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000,\r
-            0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000,\r
-            0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000,\r
-            0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000,\r
-            0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000\r
-        );\r
-\r
-        if (!$this->changed) {\r
-            return;\r
-        }\r
-\r
-        if (!$this->explicit_key_length) {\r
-            // we do >> 2, here, and not >> 5, as we do above, since strlen($this->key) tells us the number of bytes - not bits\r
-            $length = strlen($this->key) >> 2;\r
-            if ($length > 8) {\r
-                $length = 8;\r
-            } else if ($length < 4) {\r
-                $length = 4;\r
-            }\r
-            $this->Nk = $length;\r
-            $this->key_size = $length << 2;\r
-        }\r
-\r
-        $this->key = str_pad(substr($this->key, 0, $this->key_size), $this->key_size, chr(0));\r
-        $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($this->iv, 0, $this->block_size), $this->block_size, chr(0));\r
-\r
-        // see Rijndael-ammended.pdf#page=44\r
-        $this->Nr = max($this->Nk, $this->Nb) + 6;\r
-\r
-        // shift offsets for Nb = 5, 7 are defined in Rijndael-ammended.pdf#page=44,\r
-        //     "Table 8: Shift offsets in Shiftrow for the alternative block lengths"\r
-        // shift offsets for Nb = 4, 6, 8 are defined in Rijndael-ammended.pdf#page=14,\r
-        //     "Table 2: Shift offsets for different block lengths"\r
-        switch ($this->Nb) {\r
-            case 4:\r
-            case 5:\r
-            case 6:\r
-                $this->c = array(0, 1, 2, 3);\r
-                break;\r
-            case 7:\r
-                $this->c = array(0, 1, 2, 4);\r
-                break;\r
-            case 8:\r
-                $this->c = array(0, 1, 3, 4);\r
-        }\r
-\r
-        $key = $this->key;\r
-\r
-        $w = array_values(unpack('N*words', $key));\r
-\r
-        $length = $this->Nb * ($this->Nr + 1);\r
-        for ($i = $this->Nk; $i < $length; $i++) {\r
-            $temp = $w[$i - 1];\r
-            if ($i % $this->Nk == 0) {\r
-                // according to <http://php.net/language.types.integer>, "the size of an integer is platform-dependent".\r
-                // on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine,\r
-                // 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and'\r
-                // with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is.\r
-                $temp = (($temp << 8) & 0xFFFFFF00) | (($temp >> 24) & 0x000000FF); // rotWord\r
-                $temp = $this->_subWord($temp) ^ $rcon[$i / $this->Nk];\r
-            } else if ($this->Nk > 6 && $i % $this->Nk == 4) {\r
-                $temp = $this->_subWord($temp);\r
-            }\r
-            $w[$i] = $w[$i - $this->Nk] ^ $temp;\r
-        }\r
-\r
-        // convert the key schedule from a vector of $Nb * ($Nr + 1) length to a matrix with $Nr + 1 rows and $Nb columns\r
-        // and generate the inverse key schedule.  more specifically,\r
-        // according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=23> (section 5.3.3), \r
-        // "The key expansion for the Inverse Cipher is defined as follows:\r
-        //        1. Apply the Key Expansion.\r
-        //        2. Apply InvMixColumn to all Round Keys except the first and the last one."\r
-        // also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher"\r
-        $temp = array();\r
-        for ($i = $row = $col = 0; $i < $length; $i++, $col++) {\r
-            if ($col == $this->Nb) {\r
-                if ($row == 0) {\r
-                    $this->dw[0] = $this->w[0];\r
-                } else {\r
-                    // subWord + invMixColumn + invSubWord = invMixColumn\r
-                    $j = 0;\r
-                    while ($j < $this->Nb) {\r
-                        $dw = $this->_subWord($this->w[$row][$j]);\r
-                        $temp[$j] = $this->dt0[$dw & 0xFF000000] ^ \r
-                                    $this->dt1[$dw & 0x00FF0000] ^ \r
-                                    $this->dt2[$dw & 0x0000FF00] ^ \r
-                                    $this->dt3[$dw & 0x000000FF];\r
-                        $j++;\r
-                    }\r
-                    $this->dw[$row] = $temp;\r
-                }\r
-\r
-                $col = 0;\r
-                $row++;\r
-            }\r
-            $this->w[$row][$col] = $w[$i];\r
-        }\r
-\r
-        $this->dw[$row] = $this->w[$row];\r
-\r
-        $this->changed = false;\r
-    }\r
-\r
-    /**\r
-     * Performs S-Box substitutions\r
-     *\r
-     * @access private\r
-     */\r
-    function _subWord($word)\r
-    {\r
-        static $sbox0, $sbox1, $sbox2, $sbox3;\r
-\r
-        if (empty($sbox0)) {\r
-            $sbox0 = array(\r
-                0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,\r
-                0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,\r
-                0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,\r
-                0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,\r
-                0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,\r
-                0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,\r
-                0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,\r
-                0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,\r
-                0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,\r
-                0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,\r
-                0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,\r
-                0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,\r
-                0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,\r
-                0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,\r
-                0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,\r
-                0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16\r
-            );\r
-\r
-            $sbox1 = array();\r
-            $sbox2 = array();\r
-            $sbox3 = array();\r
-\r
-            for ($i = 0; $i < 256; $i++) {\r
-                $sbox1[$i <<  8] = $sbox0[$i] <<  8;\r
-                $sbox2[$i << 16] = $sbox0[$i] << 16;\r
-                $sbox3[$i << 24] = $sbox0[$i] << 24;\r
-            }\r
-        }\r
-\r
-        return $sbox0[$word & 0x000000FF] | \r
-               $sbox1[$word & 0x0000FF00] | \r
-               $sbox2[$word & 0x00FF0000] | \r
-               $sbox3[$word & 0xFF000000];\r
-    }\r
-\r
-    /**\r
-     * Performs inverse S-Box substitutions\r
-     *\r
-     * @access private\r
-     */\r
-    function _invSubWord($word)\r
-    {\r
-        static $sbox0, $sbox1, $sbox2, $sbox3;\r
-\r
-        if (empty($sbox0)) {\r
-            $sbox0 = array(\r
-                0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,\r
-                0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,\r
-                0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,\r
-                0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,\r
-                0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,\r
-                0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,\r
-                0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,\r
-                0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,\r
-                0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,\r
-                0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,\r
-                0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,\r
-                0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,\r
-                0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,\r
-                0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,\r
-                0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,\r
-                0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D\r
-            );\r
-\r
-            $sbox1 = array();\r
-            $sbox2 = array();\r
-            $sbox3 = array();\r
-\r
-            for ($i = 0; $i < 256; $i++) {\r
-                $sbox1[$i <<  8] = $sbox0[$i] <<  8;\r
-                $sbox2[$i << 16] = $sbox0[$i] << 16;\r
-                $sbox3[$i << 24] = $sbox0[$i] << 24;\r
-            }\r
-        }\r
-\r
-        return $sbox0[$word & 0x000000FF] | \r
-               $sbox1[$word & 0x0000FF00] | \r
-               $sbox2[$word & 0x00FF0000] | \r
-               $sbox3[$word & 0xFF000000];\r
-    }\r
-\r
-    /**\r
-     * Pad "packets".\r
-     *\r
-     * Rijndael works by encrypting between sixteen and thirty-two bytes at a time, provided that number is also a multiple\r
-     * of four.  If you ever need to encrypt or decrypt something that isn't of the proper length, it becomes necessary to\r
-     * pad the input so that it is of the proper length.\r
-     *\r
-     * Padding is enabled by default.  Sometimes, however, it is undesirable to pad strings.  Such is the case in SSH,\r
-     * where "packets" are padded with random bytes before being encrypted.  Unpad these packets and you risk stripping\r
-     * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is\r
-     * transmitted separately)\r
-     *\r
-     * @see Crypt_Rijndael::disablePadding()\r
-     * @access public\r
-     */\r
-    function enablePadding()\r
-    {\r
-        $this->padding = true;\r
-    }\r
-\r
-    /**\r
-     * Do not pad packets.\r
-     *\r
-     * @see Crypt_Rijndael::enablePadding()\r
-     * @access public\r
-     */\r
-    function disablePadding()\r
-    {\r
-        $this->padding = false;\r
-    }\r
-\r
-    /**\r
-     * Pads a string\r
-     *\r
-     * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize.\r
-     * $block_size - (strlen($text) % $block_size) bytes are added, each of which is equal to \r
-     * chr($block_size - (strlen($text) % $block_size)\r
-     *\r
-     * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless\r
-     * and padding will, hence forth, be enabled.\r
-     *\r
-     * @see Crypt_Rijndael::_unpad()\r
-     * @access private\r
-     */\r
-    function _pad($text)\r
-    {\r
-        $length = strlen($text);\r
-\r
-        if (!$this->padding) {\r
-            if ($length % $this->block_size == 0) {\r
-                return $text;\r
-            } else {\r
-                user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})", E_USER_NOTICE);\r
-                $this->padding = true;\r
-            }\r
-        }\r
-\r
-        $pad = $this->block_size - ($length % $this->block_size);\r
-\r
-        return str_pad($text, $length + $pad, chr($pad));\r
-    }\r
-\r
-    /**\r
-     * Unpads a string.\r
-     *\r
-     * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong\r
-     * and false will be returned.\r
-     *\r
-     * @see Crypt_Rijndael::_pad()\r
-     * @access private\r
-     */\r
-    function _unpad($text)\r
-    {\r
-        if (!$this->padding) {\r
-            return $text;\r
-        }\r
-\r
-        $length = ord($text[strlen($text) - 1]);\r
-\r
-        if (!$length || $length > $this->block_size) {\r
-            return false;\r
-        }\r
-\r
-        return substr($text, 0, -$length);\r
-    }\r
-\r
-    /**\r
-     * Treat consecutive "packets" as if they are a continuous buffer.\r
-     *\r
-     * Say you have a 32-byte plaintext $plaintext.  Using the default behavior, the two following code snippets\r
-     * will yield different outputs:\r
-     *\r
-     * <code>\r
-     *    echo $rijndael->encrypt(substr($plaintext,  0, 16));\r
-     *    echo $rijndael->encrypt(substr($plaintext, 16, 16));\r
-     * </code>\r
-     * <code>\r
-     *    echo $rijndael->encrypt($plaintext);\r
-     * </code>\r
-     *\r
-     * The solution is to enable the continuous buffer.  Although this will resolve the above discrepancy, it creates\r
-     * another, as demonstrated with the following:\r
-     *\r
-     * <code>\r
-     *    $rijndael->encrypt(substr($plaintext, 0, 16));\r
-     *    echo $rijndael->decrypt($des->encrypt(substr($plaintext, 16, 16)));\r
-     * </code>\r
-     * <code>\r
-     *    echo $rijndael->decrypt($des->encrypt(substr($plaintext, 16, 16)));\r
-     * </code>\r
-     *\r
-     * With the continuous buffer disabled, these would yield the same output.  With it enabled, they yield different\r
-     * outputs.  The reason is due to the fact that the initialization vector's change after every encryption /\r
-     * decryption round when the continuous buffer is enabled.  When it's disabled, they remain constant.\r
-     *\r
-     * Put another way, when the continuous buffer is enabled, the state of the Crypt_Rijndael() object changes after each\r
-     * encryption / decryption round, whereas otherwise, it'd remain constant.  For this reason, it's recommended that\r
-     * continuous buffers not be used.  They do offer better security and are, in fact, sometimes required (SSH uses them),\r
-     * however, they are also less intuitive and more likely to cause you problems.\r
-     *\r
-     * @see Crypt_Rijndael::disableContinuousBuffer()\r
-     * @access public\r
-     */\r
-    function enableContinuousBuffer()\r
-    {\r
-        $this->continuousBuffer = true;\r
-    }\r
-\r
-    /**\r
-     * Treat consecutive packets as if they are a discontinuous buffer.\r
-     *\r
-     * The default behavior.\r
-     *\r
-     * @see Crypt_Rijndael::enableContinuousBuffer()\r
-     * @access public\r
-     */\r
-    function disableContinuousBuffer()\r
-    {\r
-        $this->continuousBuffer = false;\r
-        $this->encryptIV = $this->iv;\r
-        $this->decryptIV = $this->iv;\r
-    }\r
-\r
-    /**\r
-     * String Shift\r
-     *\r
-     * Inspired by array_shift\r
-     *\r
-     * @param String $string\r
-     * @param optional Integer $index\r
-     * @return String\r
-     * @access private\r
-     */\r
-    function _string_shift(&$string, $index = 1)\r
-    {\r
-        $substr = substr($string, 0, $index);\r
-        $string = substr($string, $index);\r
-        return $substr;\r
-    }\r
-}\r
-\r
-// vim: ts=4:sw=4:et:\r
-// vim6: fdl=1:
\ No newline at end of file
diff --git a/library/phpsec/Crypt/TripleDES.php b/library/phpsec/Crypt/TripleDES.php
deleted file mode 100644 (file)
index 4d0dbbc..0000000
+++ /dev/null
@@ -1,690 +0,0 @@
-<?php\r
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */\r
-\r
-/**\r
- * Pure-PHP implementation of Triple DES.\r
- *\r
- * Uses mcrypt, if available, and an internal implementation, otherwise.  Operates in the EDE3 mode (encrypt-decrypt-encrypt).\r
- *\r
- * PHP versions 4 and 5\r
- *\r
- * Here's a short example of how to use this library:\r
- * <code>\r
- * <?php\r
- *    include('Crypt/TripleDES.php');\r
- *\r
- *    $des = new Crypt_TripleDES();\r
- *\r
- *    $des->setKey('abcdefghijklmnopqrstuvwx');\r
- *\r
- *    $size = 10 * 1024;\r
- *    $plaintext = '';\r
- *    for ($i = 0; $i < $size; $i++) {\r
- *        $plaintext.= 'a';\r
- *    }\r
- *\r
- *    echo $des->decrypt($des->encrypt($plaintext));\r
- * ?>\r
- * </code>\r
- *\r
- * LICENSE: This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,\r
- * MA  02111-1307  USA\r
- *\r
- * @category   Crypt\r
- * @package    Crypt_TripleDES\r
- * @author     Jim Wigginton <terrafrost@php.net>\r
- * @copyright  MMVII Jim Wigginton\r
- * @license    http://www.gnu.org/licenses/lgpl.txt\r
- * @version    $Id: TripleDES.php,v 1.13 2010/02/26 03:40:25 terrafrost Exp $\r
- * @link       http://phpseclib.sourceforge.net\r
- */\r
-\r
-/**\r
- * Include Crypt_DES\r
- */\r
-require_once 'DES.php';\r
-\r
-/**\r
- * Encrypt / decrypt using inner chaining\r
- *\r
- * Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (CRYPT_DES_MODE_CBC3).\r
- */\r
-define('CRYPT_DES_MODE_3CBC', 3);\r
-\r
-/**\r
- * Encrypt / decrypt using outer chaining\r
- *\r
- * Outer chaining is used by SSH-2 and when the mode is set to CRYPT_DES_MODE_CBC.\r
- */\r
-define('CRYPT_DES_MODE_CBC3', CRYPT_DES_MODE_CBC);\r
-\r
-/**\r
- * Pure-PHP implementation of Triple DES.\r
- *\r
- * @author  Jim Wigginton <terrafrost@php.net>\r
- * @version 0.1.0\r
- * @access  public\r
- * @package Crypt_TerraDES\r
- */\r
-class Crypt_TripleDES {\r
-    /**\r
-     * The Three Keys\r
-     *\r
-     * @see Crypt_TripleDES::setKey()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $key = "\0\0\0\0\0\0\0\0";\r
-\r
-    /**\r
-     * The Encryption Mode\r
-     *\r
-     * @see Crypt_TripleDES::Crypt_TripleDES()\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $mode = CRYPT_DES_MODE_CBC;\r
-\r
-    /**\r
-     * Continuous Buffer status\r
-     *\r
-     * @see Crypt_TripleDES::enableContinuousBuffer()\r
-     * @var Boolean\r
-     * @access private\r
-     */\r
-    var $continuousBuffer = false;\r
-\r
-    /**\r
-     * Padding status\r
-     *\r
-     * @see Crypt_TripleDES::enablePadding()\r
-     * @var Boolean\r
-     * @access private\r
-     */\r
-    var $padding = true;\r
-\r
-    /**\r
-     * The Initialization Vector\r
-     *\r
-     * @see Crypt_TripleDES::setIV()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $iv = "\0\0\0\0\0\0\0\0";\r
-\r
-    /**\r
-     * A "sliding" Initialization Vector\r
-     *\r
-     * @see Crypt_TripleDES::enableContinuousBuffer()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $encryptIV = "\0\0\0\0\0\0\0\0";\r
-\r
-    /**\r
-     * A "sliding" Initialization Vector\r
-     *\r
-     * @see Crypt_TripleDES::enableContinuousBuffer()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $decryptIV = "\0\0\0\0\0\0\0\0";\r
-\r
-    /**\r
-     * The Crypt_DES objects\r
-     *\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $des;\r
-\r
-    /**\r
-     * mcrypt resource for encryption\r
-     *\r
-     * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.\r
-     * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.\r
-     *\r
-     * @see Crypt_AES::encrypt()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $enmcrypt;\r
-\r
-    /**\r
-     * mcrypt resource for decryption\r
-     *\r
-     * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.\r
-     * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.\r
-     *\r
-     * @see Crypt_AES::decrypt()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $demcrypt;\r
-\r
-    /**\r
-     * Does the (en|de)mcrypt resource need to be (re)initialized?\r
-     *\r
-     * @see setKey()\r
-     * @see setIV()\r
-     * @var Boolean\r
-     * @access private\r
-     */\r
-    var $changed = true;\r
-\r
-    /**\r
-     * Default Constructor.\r
-     *\r
-     * Determines whether or not the mcrypt extension should be used.  $mode should only, at present, be\r
-     * CRYPT_DES_MODE_ECB or CRYPT_DES_MODE_CBC.  If not explictly set, CRYPT_DES_MODE_CBC will be used.\r
-     *\r
-     * @param optional Integer $mode\r
-     * @return Crypt_TripleDES\r
-     * @access public\r
-     */\r
-    function Crypt_TripleDES($mode = CRYPT_DES_MODE_CBC)\r
-    {\r
-        if ( !defined('CRYPT_DES_MODE') ) {\r
-            switch (true) {\r
-                case extension_loaded('mcrypt'):\r
-                    // i'd check to see if des was supported, by doing in_array('des', mcrypt_list_algorithms('')),\r
-                    // but since that can be changed after the object has been created, there doesn't seem to be\r
-                    // a lot of point...\r
-                    define('CRYPT_DES_MODE', CRYPT_DES_MODE_MCRYPT);\r
-                    break;\r
-                default:\r
-                    define('CRYPT_DES_MODE', CRYPT_DES_MODE_INTERNAL);\r
-            }\r
-        }\r
-\r
-        if ( $mode == CRYPT_DES_MODE_3CBC ) {\r
-            $this->mode = CRYPT_DES_MODE_3CBC;\r
-            $this->des = array(\r
-                new Crypt_DES(CRYPT_DES_MODE_CBC),\r
-                new Crypt_DES(CRYPT_DES_MODE_CBC),\r
-                new Crypt_DES(CRYPT_DES_MODE_CBC)\r
-            );\r
-\r
-            // we're going to be doing the padding, ourselves, so disable it in the Crypt_DES objects\r
-            $this->des[0]->disablePadding();\r
-            $this->des[1]->disablePadding();\r
-            $this->des[2]->disablePadding();\r
-\r
-            return;\r
-        }\r
-\r
-        switch ( CRYPT_DES_MODE ) {\r
-            case CRYPT_DES_MODE_MCRYPT:\r
-                switch ($mode) {\r
-                    case CRYPT_DES_MODE_ECB:\r
-                        $this->mode = MCRYPT_MODE_ECB;\r
-                        break;\r
-                    case CRYPT_DES_MODE_CTR:\r
-                        $this->mode = 'ctr';\r
-                        break;\r
-                    case CRYPT_DES_MODE_CBC:\r
-                    default:\r
-                        $this->mode = MCRYPT_MODE_CBC;\r
-                }\r
-\r
-                break;\r
-            default:\r
-                $this->des = array(\r
-                    new Crypt_DES(CRYPT_DES_MODE_ECB),\r
-                    new Crypt_DES(CRYPT_DES_MODE_ECB),\r
-                    new Crypt_DES(CRYPT_DES_MODE_ECB)\r
-                );\r
\r
-                // we're going to be doing the padding, ourselves, so disable it in the Crypt_DES objects\r
-                $this->des[0]->disablePadding();\r
-                $this->des[1]->disablePadding();\r
-                $this->des[2]->disablePadding();\r
-\r
-                switch ($mode) {\r
-                    case CRYPT_DES_MODE_ECB:\r
-                    case CRYPT_DES_MODE_CTR:\r
-                    case CRYPT_DES_MODE_CBC:\r
-                        $this->mode = $mode;\r
-                        break;\r
-                    default:\r
-                        $this->mode = CRYPT_DES_MODE_CBC;\r
-                }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Sets the key.\r
-     *\r
-     * Keys can be of any length.  Triple DES, itself, can use 128-bit (eg. strlen($key) == 16) or\r
-     * 192-bit (eg. strlen($key) == 24) keys.  This function pads and truncates $key as appropriate.\r
-     *\r
-     * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.\r
-     *\r
-     * If the key is not explicitly set, it'll be assumed to be all zero's.\r
-     *\r
-     * @access public\r
-     * @param String $key\r
-     */\r
-    function setKey($key)\r
-    {\r
-        $length = strlen($key);\r
-        if ($length > 8) {\r
-            $key = str_pad($key, 24, chr(0));\r
-            // if $key is between 64 and 128-bits, use the first 64-bits as the last, per this:\r
-            // http://php.net/function.mcrypt-encrypt#47973\r
-            //$key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24);\r
-        }\r
-        $this->key = $key;\r
-        switch (true) {\r
-            case CRYPT_DES_MODE == CRYPT_DES_MODE_INTERNAL:\r
-            case $this->mode == CRYPT_DES_MODE_3CBC:\r
-                $this->des[0]->setKey(substr($key,  0, 8));\r
-                $this->des[1]->setKey(substr($key,  8, 8));\r
-                $this->des[2]->setKey(substr($key, 16, 8));\r
-        }\r
-        $this->changed = true;\r
-    }\r
-\r
-    /**\r
-     * Sets the initialization vector. (optional)\r
-     *\r
-     * SetIV is not required when CRYPT_DES_MODE_ECB is being used.  If not explictly set, it'll be assumed\r
-     * to be all zero's.\r
-     *\r
-     * @access public\r
-     * @param String $iv\r
-     */\r
-    function setIV($iv)\r
-    {\r
-        $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, 8), 8, chr(0));\r
-        if ($this->mode == CRYPT_DES_MODE_3CBC) {\r
-            $this->des[0]->setIV($iv);\r
-            $this->des[1]->setIV($iv);\r
-            $this->des[2]->setIV($iv);\r
-        }\r
-        $this->changed = true;\r
-    }\r
-\r
-    /**\r
-     * Generate CTR XOR encryption key\r
-     *\r
-     * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the\r
-     * plaintext / ciphertext in CTR mode.\r
-     *\r
-     * @see Crypt_DES::decrypt()\r
-     * @see Crypt_DES::encrypt()\r
-     * @access public\r
-     * @param Integer $length\r
-     * @param String $iv\r
-     */\r
-    function _generate_xor($length, &$iv)\r
-    {\r
-        $xor = '';\r
-        $num_blocks = ($length + 7) >> 3;\r
-        for ($i = 0; $i < $num_blocks; $i++) {\r
-            $xor.= $iv;\r
-            for ($j = 4; $j <= 8; $j+=4) {\r
-                $temp = substr($iv, -$j, 4);\r
-                switch ($temp) {\r
-                    case "\xFF\xFF\xFF\xFF":\r
-                        $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);\r
-                        break;\r
-                    case "\x7F\xFF\xFF\xFF":\r
-                        $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);\r
-                        break 2;\r
-                    default:\r
-                        extract(unpack('Ncount', $temp));\r
-                        $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);\r
-                        break 2;\r
-                }\r
-            }\r
-        }\r
-\r
-        return $xor;\r
-    }\r
-\r
-    /**\r
-     * Encrypts a message.\r
-     *\r
-     * @access public\r
-     * @param String $plaintext\r
-     */\r
-    function encrypt($plaintext)\r
-    {\r
-        if ($this->mode != CRYPT_DES_MODE_CTR && $this->mode != 'ctr') {\r
-            $plaintext = $this->_pad($plaintext);\r
-        }\r
-\r
-        // if the key is smaller then 8, do what we'd normally do\r
-        if ($this->mode == CRYPT_DES_MODE_3CBC && strlen($this->key) > 8) {\r
-            $ciphertext = $this->des[2]->encrypt($this->des[1]->decrypt($this->des[0]->encrypt($plaintext)));\r
-\r
-            return $ciphertext;\r
-        }\r
-\r
-        if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {\r
-            if ($this->changed) {\r
-                if (!isset($this->enmcrypt)) {\r
-                    $this->enmcrypt = mcrypt_module_open(MCRYPT_3DES, '', $this->mode, '');\r
-                }\r
-                mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);\r
-                $this->changed = false;\r
-            }\r
-\r
-            $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);\r
-\r
-            if (!$this->continuousBuffer) {\r
-                mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);\r
-            }\r
-\r
-            return $ciphertext;\r
-        }\r
-\r
-        if (strlen($this->key) <= 8) {\r
-            $this->des[0]->mode = $this->mode;\r
-\r
-            return $this->des[0]->encrypt($plaintext);\r
-        }\r
-\r
-        // we pad with chr(0) since that's what mcrypt_generic does.  to quote from http://php.net/function.mcrypt-generic :\r
-        // "The data is padded with "\0" to make sure the length of the data is n * blocksize."\r
-        $plaintext = str_pad($plaintext, ceil(strlen($plaintext) / 8) * 8, chr(0));\r
-\r
-        $des = $this->des;\r
-\r
-        $ciphertext = '';\r
-        switch ($this->mode) {\r
-            case CRYPT_DES_MODE_ECB:\r
-                for ($i = 0; $i < strlen($plaintext); $i+=8) {\r
-                    $block = substr($plaintext, $i, 8);\r
-                    $block = $des[0]->_processBlock($block, CRYPT_DES_ENCRYPT);\r
-                    $block = $des[1]->_processBlock($block, CRYPT_DES_DECRYPT);\r
-                    $block = $des[2]->_processBlock($block, CRYPT_DES_ENCRYPT);\r
-                    $ciphertext.= $block;\r
-                }\r
-                break;\r
-            case CRYPT_DES_MODE_CBC:\r
-                $xor = $this->encryptIV;\r
-                for ($i = 0; $i < strlen($plaintext); $i+=8) {\r
-                    $block = substr($plaintext, $i, 8) ^ $xor;\r
-                    $block = $des[0]->_processBlock($block, CRYPT_DES_ENCRYPT);\r
-                    $block = $des[1]->_processBlock($block, CRYPT_DES_DECRYPT);\r
-                    $block = $des[2]->_processBlock($block, CRYPT_DES_ENCRYPT);\r
-                    $xor = $block;\r
-                    $ciphertext.= $block;\r
-                }\r
-                if ($this->continuousBuffer) {\r
-                    $this->encryptIV = $xor;\r
-                }\r
-                break;\r
-            case CRYPT_DES_MODE_CTR:\r
-                $xor = $this->encryptIV;\r
-                for ($i = 0; $i < strlen($plaintext); $i+=8) {\r
-                    $key = $this->_generate_xor(8, $xor);\r
-                    $key = $des[0]->_processBlock($key, CRYPT_DES_ENCRYPT);\r
-                    $key = $des[1]->_processBlock($key, CRYPT_DES_DECRYPT);\r
-                    $key = $des[2]->_processBlock($key, CRYPT_DES_ENCRYPT);\r
-                    $block = substr($plaintext, $i, 8);\r
-                    $ciphertext.= $block ^ $key;\r
-                }\r
-                if ($this->continuousBuffer) {\r
-                    $this->encryptIV = $xor;\r
-                }\r
-        }\r
-\r
-        return $ciphertext;\r
-    }\r
-\r
-    /**\r
-     * Decrypts a message.\r
-     *\r
-     * @access public\r
-     * @param String $ciphertext\r
-     */\r
-    function decrypt($ciphertext)\r
-    {\r
-        if ($this->mode == CRYPT_DES_MODE_3CBC && strlen($this->key) > 8) {\r
-            $plaintext = $this->des[0]->decrypt($this->des[1]->encrypt($this->des[2]->decrypt($ciphertext)));\r
-\r
-            return $this->_unpad($plaintext);\r
-        }\r
-\r
-        // we pad with chr(0) since that's what mcrypt_generic does.  to quote from http://php.net/function.mcrypt-generic :\r
-        // "The data is padded with "\0" to make sure the length of the data is n * blocksize."\r
-        $ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, chr(0));\r
-\r
-        if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {\r
-            if ($this->changed) {\r
-                if (!isset($this->demcrypt)) {\r
-                    $this->demcrypt = mcrypt_module_open(MCRYPT_3DES, '', $this->mode, '');\r
-                }\r
-                mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);\r
-                $this->changed = false;\r
-            }\r
-\r
-            $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);\r
-\r
-            if (!$this->continuousBuffer) {\r
-                mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);\r
-            }\r
-\r
-            return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext;\r
-        }\r
-\r
-        if (strlen($this->key) <= 8) {\r
-            $this->des[0]->mode = $this->mode;\r
-\r
-            return $this->_unpad($this->des[0]->decrypt($plaintext));\r
-        }\r
-\r
-        $des = $this->des;\r
-\r
-        $plaintext = '';\r
-        switch ($this->mode) {\r
-            case CRYPT_DES_MODE_ECB:\r
-                for ($i = 0; $i < strlen($ciphertext); $i+=8) {\r
-                    $block = substr($ciphertext, $i, 8);\r
-                    $block = $des[2]->_processBlock($block, CRYPT_DES_DECRYPT);\r
-                    $block = $des[1]->_processBlock($block, CRYPT_DES_ENCRYPT);\r
-                    $block = $des[0]->_processBlock($block, CRYPT_DES_DECRYPT);\r
-                    $plaintext.= $block;\r
-                }\r
-                break;\r
-            case CRYPT_DES_MODE_CBC:\r
-                $xor = $this->decryptIV;\r
-                for ($i = 0; $i < strlen($ciphertext); $i+=8) {\r
-                    $orig = $block = substr($ciphertext, $i, 8);\r
-                    $block = $des[2]->_processBlock($block, CRYPT_DES_DECRYPT);\r
-                    $block = $des[1]->_processBlock($block, CRYPT_DES_ENCRYPT);\r
-                    $block = $des[0]->_processBlock($block, CRYPT_DES_DECRYPT);\r
-                    $plaintext.= $block ^ $xor;\r
-                    $xor = $orig;\r
-                }\r
-                if ($this->continuousBuffer) {\r
-                    $this->decryptIV = $xor;\r
-                }\r
-                break;\r
-            case CRYPT_DES_MODE_CTR:\r
-                $xor = $this->decryptIV;\r
-                for ($i = 0; $i < strlen($ciphertext); $i+=8) {\r
-                    $key = $this->_generate_xor(8, $xor);\r
-                    $key = $des[0]->_processBlock($key, CRYPT_DES_ENCRYPT);\r
-                    $key = $des[1]->_processBlock($key, CRYPT_DES_DECRYPT);\r
-                    $key = $des[2]->_processBlock($key, CRYPT_DES_ENCRYPT);\r
-                    $block = substr($ciphertext, $i, 8);\r
-                    $plaintext.= $block ^ $key;\r
-                }\r
-                if ($this->continuousBuffer) {\r
-                    $this->decryptIV = $xor;\r
-                }\r
-        }\r
-\r
-        return $this->mode != CRYPT_DES_MODE_CTR ? $this->_unpad($plaintext) : $plaintext;\r
-    }\r
-\r
-    /**\r
-     * Treat consecutive "packets" as if they are a continuous buffer.\r
-     *\r
-     * Say you have a 16-byte plaintext $plaintext.  Using the default behavior, the two following code snippets\r
-     * will yield different outputs:\r
-     *\r
-     * <code>\r
-     *    echo $des->encrypt(substr($plaintext, 0, 8));\r
-     *    echo $des->encrypt(substr($plaintext, 8, 8));\r
-     * </code>\r
-     * <code>\r
-     *    echo $des->encrypt($plaintext);\r
-     * </code>\r
-     *\r
-     * The solution is to enable the continuous buffer.  Although this will resolve the above discrepancy, it creates\r
-     * another, as demonstrated with the following:\r
-     *\r
-     * <code>\r
-     *    $des->encrypt(substr($plaintext, 0, 8));\r
-     *    echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));\r
-     * </code>\r
-     * <code>\r
-     *    echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));\r
-     * </code>\r
-     *\r
-     * With the continuous buffer disabled, these would yield the same output.  With it enabled, they yield different\r
-     * outputs.  The reason is due to the fact that the initialization vector's change after every encryption /\r
-     * decryption round when the continuous buffer is enabled.  When it's disabled, they remain constant.\r
-     *\r
-     * Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each\r
-     * encryption / decryption round, whereas otherwise, it'd remain constant.  For this reason, it's recommended that\r
-     * continuous buffers not be used.  They do offer better security and are, in fact, sometimes required (SSH uses them),\r
-     * however, they are also less intuitive and more likely to cause you problems.\r
-     *\r
-     * @see Crypt_TripleDES::disableContinuousBuffer()\r
-     * @access public\r
-     */\r
-    function enableContinuousBuffer()\r
-    {\r
-        $this->continuousBuffer = true;\r
-        if ($this->mode == CRYPT_DES_MODE_3CBC) {\r
-            $this->des[0]->enableContinuousBuffer();\r
-            $this->des[1]->enableContinuousBuffer();\r
-            $this->des[2]->enableContinuousBuffer();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Treat consecutive packets as if they are a discontinuous buffer.\r
-     *\r
-     * The default behavior.\r
-     *\r
-     * @see Crypt_TripleDES::enableContinuousBuffer()\r
-     * @access public\r
-     */\r
-    function disableContinuousBuffer()\r
-    {\r
-        $this->continuousBuffer = false;\r
-        $this->encryptIV = $this->iv;\r
-        $this->decryptIV = $this->iv;\r
-\r
-        if ($this->mode == CRYPT_DES_MODE_3CBC) {\r
-            $this->des[0]->disableContinuousBuffer();\r
-            $this->des[1]->disableContinuousBuffer();\r
-            $this->des[2]->disableContinuousBuffer();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Pad "packets".\r
-     *\r
-     * DES works by encrypting eight bytes at a time.  If you ever need to encrypt or decrypt something that's not\r
-     * a multiple of eight, it becomes necessary to pad the input so that it's length is a multiple of eight.\r
-     *\r
-     * Padding is enabled by default.  Sometimes, however, it is undesirable to pad strings.  Such is the case in SSH1,\r
-     * where "packets" are padded with random bytes before being encrypted.  Unpad these packets and you risk stripping\r
-     * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is\r
-     * transmitted separately)\r
-     *\r
-     * @see Crypt_TripleDES::disablePadding()\r
-     * @access public\r
-     */\r
-    function enablePadding()\r
-    {\r
-        $this->padding = true;\r
-    }\r
-\r
-    /**\r
-     * Do not pad packets.\r
-     *\r
-     * @see Crypt_TripleDES::enablePadding()\r
-     * @access public\r
-     */\r
-    function disablePadding()\r
-    {\r
-        $this->padding = false;\r
-    }\r
-\r
-    /**\r
-     * Pads a string\r
-     *\r
-     * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize (8).\r
-     * 8 - (strlen($text) & 7) bytes are added, each of which is equal to chr(8 - (strlen($text) & 7)\r
-     *\r
-     * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless\r
-     * and padding will, hence forth, be enabled.\r
-     *\r
-     * @see Crypt_TripleDES::_unpad()\r
-     * @access private\r
-     */\r
-    function _pad($text)\r
-    {\r
-        $length = strlen($text);\r
-\r
-        if (!$this->padding) {\r
-            if (($length & 7) == 0) {\r
-                return $text;\r
-            } else {\r
-                user_error("The plaintext's length ($length) is not a multiple of the block size (8)", E_USER_NOTICE);\r
-                $this->padding = true;\r
-            }\r
-        }\r
-\r
-        $pad = 8 - ($length & 7);\r
-        return str_pad($text, $length + $pad, chr($pad));\r
-    }\r
-\r
-    /**\r
-     * Unpads a string\r
-     *\r
-     * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong\r
-     * and false will be returned.\r
-     *\r
-     * @see Crypt_TripleDES::_pad()\r
-     * @access private\r
-     */\r
-    function _unpad($text)\r
-    {\r
-        if (!$this->padding) {\r
-            return $text;\r
-        }\r
-\r
-        $length = ord($text[strlen($text) - 1]);\r
-\r
-        if (!$length || $length > 8) {\r
-            return false;\r
-        }\r
-\r
-        return substr($text, 0, -$length);\r
-    }\r
-}\r
-\r
-// vim: ts=4:sw=4:et:\r
-// vim6: fdl=1:
\ No newline at end of file
diff --git a/library/phpsec/Math/BigInteger.php b/library/phpsec/Math/BigInteger.php
deleted file mode 100644 (file)
index 5b3a4fc..0000000
+++ /dev/null
@@ -1,3545 +0,0 @@
-<?php\r
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */\r
-\r
-/**\r
- * Pure-PHP arbitrary precision integer arithmetic library.\r
- *\r
- * Supports base-2, base-10, base-16, and base-256 numbers.  Uses the GMP or BCMath extensions, if available,\r
- * and an internal implementation, otherwise.\r
- *\r
- * PHP versions 4 and 5\r
- *\r
- * {@internal (all DocBlock comments regarding implementation - such as the one that follows - refer to the \r
- * {@link MATH_BIGINTEGER_MODE_INTERNAL MATH_BIGINTEGER_MODE_INTERNAL} mode)\r
- *\r
- * Math_BigInteger uses base-2**26 to perform operations such as multiplication and division and\r
- * base-2**52 (ie. two base 2**26 digits) to perform addition and subtraction.  Because the largest possible\r
- * value when multiplying two base-2**26 numbers together is a base-2**52 number, double precision floating\r
- * point numbers - numbers that should be supported on most hardware and whose significand is 53 bits - are\r
- * used.  As a consequence, bitwise operators such as >> and << cannot be used, nor can the modulo operator %,\r
- * which only supports integers.  Although this fact will slow this library down, the fact that such a high\r
- * base is being used should more than compensate.\r
- *\r
- * When PHP version 6 is officially released, we'll be able to use 64-bit integers.  This should, once again,\r
- * allow bitwise operators, and will increase the maximum possible base to 2**31 (or 2**62 for addition /\r
- * subtraction).\r
- *\r
- * Numbers are stored in {@link http://en.wikipedia.org/wiki/Endianness little endian} format.  ie.\r
- * (new Math_BigInteger(pow(2, 26)))->value = array(0, 1)\r
- *\r
- * Useful resources are as follows:\r
- *\r
- *  - {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf Handbook of Applied Cryptography (HAC)}\r
- *  - {@link http://math.libtomcrypt.com/files/tommath.pdf Multi-Precision Math (MPM)}\r
- *  - Java's BigInteger classes.  See /j2se/src/share/classes/java/math in jdk-1_5_0-src-jrl.zip\r
- *\r
- * Here's an example of how to use this library:\r
- * <code>\r
- * <?php\r
- *    include('Math/BigInteger.php');\r
- *\r
- *    $a = new Math_BigInteger(2);\r
- *    $b = new Math_BigInteger(3);\r
- *\r
- *    $c = $a->add($b);\r
- *\r
- *    echo $c->toString(); // outputs 5\r
- * ?>\r
- * </code>\r
- *\r
- * LICENSE: This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,\r
- * MA  02111-1307  USA\r
- *\r
- * @category   Math\r
- * @package    Math_BigInteger\r
- * @author     Jim Wigginton <terrafrost@php.net>\r
- * @copyright  MMVI Jim Wigginton\r
- * @license    http://www.gnu.org/licenses/lgpl.txt\r
- * @version    $Id: BigInteger.php,v 1.33 2010/03/22 22:32:03 terrafrost Exp $\r
- * @link       http://pear.php.net/package/Math_BigInteger\r
- */\r
-\r
-/**#@+\r
- * Reduction constants\r
- *\r
- * @access private\r
- * @see Math_BigInteger::_reduce()\r
- */\r
-/**\r
- * @see Math_BigInteger::_montgomery()\r
- * @see Math_BigInteger::_prepMontgomery()\r
- */\r
-define('MATH_BIGINTEGER_MONTGOMERY', 0);\r
-/**\r
- * @see Math_BigInteger::_barrett()\r
- */\r
-define('MATH_BIGINTEGER_BARRETT', 1);\r
-/**\r
- * @see Math_BigInteger::_mod2()\r
- */\r
-define('MATH_BIGINTEGER_POWEROF2', 2);\r
-/**\r
- * @see Math_BigInteger::_remainder()\r
- */\r
-define('MATH_BIGINTEGER_CLASSIC', 3);\r
-/**\r
- * @see Math_BigInteger::__clone()\r
- */\r
-define('MATH_BIGINTEGER_NONE', 4);\r
-/**#@-*/\r
-\r
-/**#@+\r
- * Array constants\r
- *\r
- * Rather than create a thousands and thousands of new Math_BigInteger objects in repeated function calls to add() and\r
- * multiply() or whatever, we'll just work directly on arrays, taking them in as parameters and returning them.\r
- *\r
- * @access private\r
- */\r
-/**\r
- * $result[MATH_BIGINTEGER_VALUE] contains the value.\r
- */\r
-define('MATH_BIGINTEGER_VALUE', 0);\r
-/**\r
- * $result[MATH_BIGINTEGER_SIGN] contains the sign.\r
- */\r
-define('MATH_BIGINTEGER_SIGN', 1);\r
-/**#@-*/\r
-\r
-/**#@+\r
- * @access private\r
- * @see Math_BigInteger::_montgomery()\r
- * @see Math_BigInteger::_barrett()\r
- */\r
-/**\r
- * Cache constants\r
- *\r
- * $cache[MATH_BIGINTEGER_VARIABLE] tells us whether or not the cached data is still valid.\r
- */\r
-define('MATH_BIGINTEGER_VARIABLE', 0);\r
-/**\r
- * $cache[MATH_BIGINTEGER_DATA] contains the cached data.\r
- */\r
-define('MATH_BIGINTEGER_DATA', 1);\r
-/**#@-*/\r
-\r
-/**#@+\r
- * Mode constants.\r
- *\r
- * @access private\r
- * @see Math_BigInteger::Math_BigInteger()\r
- */\r
-/**\r
- * To use the pure-PHP implementation\r
- */\r
-define('MATH_BIGINTEGER_MODE_INTERNAL', 1);\r
-/**\r
- * To use the BCMath library\r
- *\r
- * (if enabled; otherwise, the internal implementation will be used)\r
- */\r
-define('MATH_BIGINTEGER_MODE_BCMATH', 2);\r
-/**\r
- * To use the GMP library\r
- *\r
- * (if present; otherwise, either the BCMath or the internal implementation will be used)\r
- */\r
-define('MATH_BIGINTEGER_MODE_GMP', 3);\r
-/**#@-*/\r
-\r
-/**\r
- * The largest digit that may be used in addition / subtraction\r
- *\r
- * (we do pow(2, 52) instead of using 4503599627370496, directly, because some PHP installations\r
- *  will truncate 4503599627370496)\r
- *\r
- * @access private\r
- */\r
-define('MATH_BIGINTEGER_MAX_DIGIT52', pow(2, 52));\r
-\r
-/**\r
- * Karatsuba Cutoff\r
- *\r
- * At what point do we switch between Karatsuba multiplication and schoolbook long multiplication?\r
- *\r
- * @access private\r
- */\r
-define('MATH_BIGINTEGER_KARATSUBA_CUTOFF', 25);\r
-\r
-/**\r
- * Pure-PHP arbitrary precision integer arithmetic library. Supports base-2, base-10, base-16, and base-256\r
- * numbers.\r
- *\r
- * @author  Jim Wigginton <terrafrost@php.net>\r
- * @version 1.0.0RC4\r
- * @access  public\r
- * @package Math_BigInteger\r
- */\r
-class Math_BigInteger {\r
-    /**\r
-     * Holds the BigInteger's value.\r
-     *\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $value;\r
-\r
-    /**\r
-     * Holds the BigInteger's magnitude.\r
-     *\r
-     * @var Boolean\r
-     * @access private\r
-     */\r
-    var $is_negative = false;\r
-\r
-    /**\r
-     * Random number generator function\r
-     *\r
-     * @see setRandomGenerator()\r
-     * @access private\r
-     */\r
-    var $generator = 'mt_rand';\r
-\r
-    /**\r
-     * Precision\r
-     *\r
-     * @see setPrecision()\r
-     * @access private\r
-     */\r
-    var $precision = -1;\r
-\r
-    /**\r
-     * Precision Bitmask\r
-     *\r
-     * @see setPrecision()\r
-     * @access private\r
-     */\r
-    var $bitmask = false;\r
-\r
-    /**\r
-     * Mode independant value used for serialization.\r
-     *\r
-     * If the bcmath or gmp extensions are installed $this->value will be a non-serializable resource, hence the need for \r
-     * a variable that'll be serializable regardless of whether or not extensions are being used.  Unlike $this->value,\r
-     * however, $this->hex is only calculated when $this->__sleep() is called.\r
-     *\r
-     * @see __sleep()\r
-     * @see __wakeup()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $hex;\r
-\r
-    /**\r
-     * Converts base-2, base-10, base-16, and binary strings (eg. base-256) to BigIntegers.\r
-     *\r
-     * If the second parameter - $base - is negative, then it will be assumed that the number's are encoded using\r
-     * two's compliment.  The sole exception to this is -10, which is treated the same as 10 is.\r
-     *\r
-     * Here's an example:\r
-     * <code>\r
-     * <?php\r
-     *    include('Math/BigInteger.php');\r
-     *\r
-     *    $a = new Math_BigInteger('0x32', 16); // 50 in base-16\r
-     *\r
-     *    echo $a->toString(); // outputs 50\r
-     * ?>\r
-     * </code>\r
-     *\r
-     * @param optional $x base-10 number or base-$base number if $base set.\r
-     * @param optional integer $base\r
-     * @return Math_BigInteger\r
-     * @access public\r
-     */\r
-    function Math_BigInteger($x = 0, $base = 10)\r
-    {\r
-        if ( !defined('MATH_BIGINTEGER_MODE') ) {\r
-            switch (true) {\r
-                case extension_loaded('gmp'):\r
-                    define('MATH_BIGINTEGER_MODE', MATH_BIGINTEGER_MODE_GMP);\r
-                    break;\r
-                case extension_loaded('bcmath'):\r
-                    define('MATH_BIGINTEGER_MODE', MATH_BIGINTEGER_MODE_BCMATH);\r
-                    break;\r
-                default:\r
-                    define('MATH_BIGINTEGER_MODE', MATH_BIGINTEGER_MODE_INTERNAL);\r
-            }\r
-        }\r
-\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                if (is_resource($x) && get_resource_type($x) == 'GMP integer') {\r
-                    $this->value = $x;\r
-                    return;\r
-                }\r
-                $this->value = gmp_init(0);\r
-                break;\r
-            case MATH_BIGINTEGER_MODE_BCMATH:\r
-                $this->value = '0';\r
-                break;\r
-            default:\r
-                $this->value = array();\r
-        }\r
-\r
-        if (empty($x)) {\r
-            return;\r
-        }\r
-\r
-        switch ($base) {\r
-            case -256:\r
-                if (ord($x[0]) & 0x80) {\r
-                    $x = ~$x;\r
-                    $this->is_negative = true;\r
-                }\r
-            case  256:\r
-                switch ( MATH_BIGINTEGER_MODE ) {\r
-                    case MATH_BIGINTEGER_MODE_GMP:\r
-                        $sign = $this->is_negative ? '-' : '';\r
-                        $this->value = gmp_init($sign . '0x' . bin2hex($x));\r
-                        break;\r
-                    case MATH_BIGINTEGER_MODE_BCMATH:\r
-                        // round $len to the nearest 4 (thanks, DavidMJ!)\r
-                        $len = (strlen($x) + 3) & 0xFFFFFFFC;\r
-\r
-                        $x = str_pad($x, $len, chr(0), STR_PAD_LEFT);\r
-\r
-                        for ($i = 0; $i < $len; $i+= 4) {\r
-                            $this->value = bcmul($this->value, '4294967296', 0); // 4294967296 == 2**32\r
-                            $this->value = bcadd($this->value, 0x1000000 * ord($x[$i]) + ((ord($x[$i + 1]) << 16) | (ord($x[$i + 2]) << 8) | ord($x[$i + 3])), 0);\r
-                        }\r
-\r
-                        if ($this->is_negative) {\r
-                            $this->value = '-' . $this->value;\r
-                        }\r
-\r
-                        break;\r
-                    // converts a base-2**8 (big endian / msb) number to base-2**26 (little endian / lsb)\r
-                    default:\r
-                        while (strlen($x)) {\r
-                            $this->value[] = $this->_bytes2int($this->_base256_rshift($x, 26));\r
-                        }\r
-                }\r
-\r
-                if ($this->is_negative) {\r
-                    if (MATH_BIGINTEGER_MODE != MATH_BIGINTEGER_MODE_INTERNAL) {\r
-                        $this->is_negative = false;\r
-                    }\r
-                    $temp = $this->add(new Math_BigInteger('-1'));\r
-                    $this->value = $temp->value;\r
-                }\r
-                break;\r
-            case  16:\r
-            case -16:\r
-                if ($base > 0 && $x[0] == '-') {\r
-                    $this->is_negative = true;\r
-                    $x = substr($x, 1);\r
-                }\r
-\r
-                $x = preg_replace('#^(?:0x)?([A-Fa-f0-9]*).*#', '$1', $x);\r
-\r
-                $is_negative = false;\r
-                if ($base < 0 && hexdec($x[0]) >= 8) {\r
-                    $this->is_negative = $is_negative = true;\r
-                    $x = bin2hex(~pack('H*', $x));\r
-                }\r
-\r
-                switch ( MATH_BIGINTEGER_MODE ) {\r
-                    case MATH_BIGINTEGER_MODE_GMP:\r
-                        $temp = $this->is_negative ? '-0x' . $x : '0x' . $x;\r
-                        $this->value = gmp_init($temp);\r
-                        $this->is_negative = false;\r
-                        break;\r
-                    case MATH_BIGINTEGER_MODE_BCMATH:\r
-                        $x = ( strlen($x) & 1 ) ? '0' . $x : $x;\r
-                        $temp = new Math_BigInteger(pack('H*', $x), 256);\r
-                        $this->value = $this->is_negative ? '-' . $temp->value : $temp->value;\r
-                        $this->is_negative = false;\r
-                        break;\r
-                    default:\r
-                        $x = ( strlen($x) & 1 ) ? '0' . $x : $x;\r
-                        $temp = new Math_BigInteger(pack('H*', $x), 256);\r
-                        $this->value = $temp->value;\r
-                }\r
-\r
-                if ($is_negative) {\r
-                    $temp = $this->add(new Math_BigInteger('-1'));\r
-                    $this->value = $temp->value;\r
-                }\r
-                break;\r
-            case  10:\r
-            case -10:\r
-                $x = preg_replace('#^(-?[0-9]*).*#', '$1', $x);\r
-\r
-                switch ( MATH_BIGINTEGER_MODE ) {\r
-                    case MATH_BIGINTEGER_MODE_GMP:\r
-                        $this->value = gmp_init($x);\r
-                        break;\r
-                    case MATH_BIGINTEGER_MODE_BCMATH:\r
-                        // explicitly casting $x to a string is necessary, here, since doing $x[0] on -1 yields different\r
-                        // results then doing it on '-1' does (modInverse does $x[0])\r
-                        $this->value = (string) $x;\r
-                        break;\r
-                    default:\r
-                        $temp = new Math_BigInteger();\r
-\r
-                        // array(10000000) is 10**7 in base-2**26.  10**7 is the closest to 2**26 we can get without passing it.\r
-                        $multiplier = new Math_BigInteger();\r
-                        $multiplier->value = array(10000000);\r
-\r
-                        if ($x[0] == '-') {\r
-                            $this->is_negative = true;\r
-                            $x = substr($x, 1);\r
-                        }\r
-\r
-                        $x = str_pad($x, strlen($x) + (6 * strlen($x)) % 7, 0, STR_PAD_LEFT);\r
-\r
-                        while (strlen($x)) {\r
-                            $temp = $temp->multiply($multiplier);\r
-                            $temp = $temp->add(new Math_BigInteger($this->_int2bytes(substr($x, 0, 7)), 256));\r
-                            $x = substr($x, 7);\r
-                        }\r
-\r
-                        $this->value = $temp->value;\r
-                }\r
-                break;\r
-            case  2: // base-2 support originally implemented by Lluis Pamies - thanks!\r
-            case -2:\r
-                if ($base > 0 && $x[0] == '-') {\r
-                    $this->is_negative = true;\r
-                    $x = substr($x, 1);\r
-                }\r
-\r
-                $x = preg_replace('#^([01]*).*#', '$1', $x);\r
-                $x = str_pad($x, strlen($x) + (3 * strlen($x)) % 4, 0, STR_PAD_LEFT);\r
-\r
-                $str = '0x';\r
-                while (strlen($x)) {\r
-                    $part = substr($x, 0, 4);\r
-                    $str.= dechex(bindec($part));\r
-                    $x = substr($x, 4);\r
-                }\r
-\r
-                if ($this->is_negative) {\r
-                    $str = '-' . $str;\r
-                }\r
-\r
-                $temp = new Math_BigInteger($str, 8 * $base); // ie. either -16 or +16\r
-                $this->value = $temp->value;\r
-                $this->is_negative = $temp->is_negative;\r
-\r
-                break;\r
-            default:\r
-                // base not supported, so we'll let $this == 0\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Converts a BigInteger to a byte string (eg. base-256).\r
-     *\r
-     * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're\r
-     * saved as two's compliment.\r
-     *\r
-     * Here's an example:\r
-     * <code>\r
-     * <?php\r
-     *    include('Math/BigInteger.php');\r
-     *\r
-     *    $a = new Math_BigInteger('65');\r
-     *\r
-     *    echo $a->toBytes(); // outputs chr(65)\r
-     * ?>\r
-     * </code>\r
-     *\r
-     * @param Boolean $twos_compliment\r
-     * @return String\r
-     * @access public\r
-     * @internal Converts a base-2**26 number to base-2**8\r
-     */\r
-    function toBytes($twos_compliment = false)\r
-    {\r
-        if ($twos_compliment) {\r
-            $comparison = $this->compare(new Math_BigInteger());\r
-            if ($comparison == 0) {\r
-                return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';\r
-            }\r
-\r
-            $temp = $comparison < 0 ? $this->add(new Math_BigInteger(1)) : $this->copy();\r
-            $bytes = $temp->toBytes();\r
-\r
-            if (empty($bytes)) { // eg. if the number we're trying to convert is -1\r
-                $bytes = chr(0);\r
-            }\r
-\r
-            if (ord($bytes[0]) & 0x80) {\r
-                $bytes = chr(0) . $bytes;\r
-            }\r
-\r
-            return $comparison < 0 ? ~$bytes : $bytes;\r
-        }\r
-\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                if (gmp_cmp($this->value, gmp_init(0)) == 0) {\r
-                    return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';\r
-                }\r
-\r
-                $temp = gmp_strval(gmp_abs($this->value), 16);\r
-                $temp = ( strlen($temp) & 1 ) ? '0' . $temp : $temp;\r
-                $temp = pack('H*', $temp);\r
-\r
-                return $this->precision > 0 ?\r
-                    substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) :\r
-                    ltrim($temp, chr(0));\r
-            case MATH_BIGINTEGER_MODE_BCMATH:\r
-                if ($this->value === '0') {\r
-                    return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';\r
-                }\r
-\r
-                $value = '';\r
-                $current = $this->value;\r
-\r
-                if ($current[0] == '-') {\r
-                    $current = substr($current, 1);\r
-                }\r
-\r
-                while (bccomp($current, '0', 0) > 0) {\r
-                    $temp = bcmod($current, '16777216');\r
-                    $value = chr($temp >> 16) . chr($temp >> 8) . chr($temp) . $value;\r
-                    $current = bcdiv($current, '16777216', 0);\r
-                }\r
-\r
-                return $this->precision > 0 ?\r
-                    substr(str_pad($value, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) :\r
-                    ltrim($value, chr(0));\r
-        }\r
-\r
-        if (!count($this->value)) {\r
-            return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';\r
-        }\r
-        $result = $this->_int2bytes($this->value[count($this->value) - 1]);\r
-\r
-        $temp = $this->copy();\r
-\r
-        for ($i = count($temp->value) - 2; $i >= 0; --$i) {\r
-            $temp->_base256_lshift($result, 26);\r
-            $result = $result | str_pad($temp->_int2bytes($temp->value[$i]), strlen($result), chr(0), STR_PAD_LEFT);\r
-        }\r
-\r
-        return $this->precision > 0 ?\r
-            str_pad(substr($result, -(($this->precision + 7) >> 3)), ($this->precision + 7) >> 3, chr(0), STR_PAD_LEFT) :\r
-            $result;\r
-    }\r
-\r
-    /**\r
-     * Converts a BigInteger to a hex string (eg. base-16)).\r
-     *\r
-     * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're\r
-     * saved as two's compliment.\r
-     *\r
-     * Here's an example:\r
-     * <code>\r
-     * <?php\r
-     *    include('Math/BigInteger.php');\r
-     *\r
-     *    $a = new Math_BigInteger('65');\r
-     *\r
-     *    echo $a->toHex(); // outputs '41'\r
-     * ?>\r
-     * </code>\r
-     *\r
-     * @param Boolean $twos_compliment\r
-     * @return String\r
-     * @access public\r
-     * @internal Converts a base-2**26 number to base-2**8\r
-     */\r
-    function toHex($twos_compliment = false)\r
-    {\r
-        return bin2hex($this->toBytes($twos_compliment));\r
-    }\r
-\r
-    /**\r
-     * Converts a BigInteger to a bit string (eg. base-2).\r
-     *\r
-     * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're\r
-     * saved as two's compliment.\r
-     *\r
-     * Here's an example:\r
-     * <code>\r
-     * <?php\r
-     *    include('Math/BigInteger.php');\r
-     *\r
-     *    $a = new Math_BigInteger('65');\r
-     *\r
-     *    echo $a->toBits(); // outputs '1000001'\r
-     * ?>\r
-     * </code>\r
-     *\r
-     * @param Boolean $twos_compliment\r
-     * @return String\r
-     * @access public\r
-     * @internal Converts a base-2**26 number to base-2**2\r
-     */\r
-    function toBits($twos_compliment = false)\r
-    {\r
-        $hex = $this->toHex($twos_compliment);\r
-        $bits = '';\r
-        for ($i = 0; $i < strlen($hex); $i+=8) {\r
-            $bits.= str_pad(decbin(hexdec(substr($hex, $i, 8))), 32, '0', STR_PAD_LEFT);\r
-        }\r
-        return $this->precision > 0 ? substr($bits, -$this->precision) : ltrim($bits, '0');\r
-    }\r
-\r
-    /**\r
-     * Converts a BigInteger to a base-10 number.\r
-     *\r
-     * Here's an example:\r
-     * <code>\r
-     * <?php\r
-     *    include('Math/BigInteger.php');\r
-     *\r
-     *    $a = new Math_BigInteger('50');\r
-     *\r
-     *    echo $a->toString(); // outputs 50\r
-     * ?>\r
-     * </code>\r
-     *\r
-     * @return String\r
-     * @access public\r
-     * @internal Converts a base-2**26 number to base-10**7 (which is pretty much base-10)\r
-     */\r
-    function toString()\r
-    {\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                return gmp_strval($this->value);\r
-            case MATH_BIGINTEGER_MODE_BCMATH:\r
-                if ($this->value === '0') {\r
-                    return '0';\r
-                }\r
-\r
-                return ltrim($this->value, '0');\r
-        }\r
-\r
-        if (!count($this->value)) {\r
-            return '0';\r
-        }\r
-\r
-        $temp = $this->copy();\r
-        $temp->is_negative = false;\r
-\r
-        $divisor = new Math_BigInteger();\r
-        $divisor->value = array(10000000); // eg. 10**7\r
-        $result = '';\r
-        while (count($temp->value)) {\r
-            list($temp, $mod) = $temp->divide($divisor);\r
-            $result = str_pad(isset($mod->value[0]) ? $mod->value[0] : '', 7, '0', STR_PAD_LEFT) . $result;\r
-        }\r
-        $result = ltrim($result, '0');\r
-        if (empty($result)) {\r
-            $result = '0';\r
-        }\r
-\r
-        if ($this->is_negative) {\r
-            $result = '-' . $result;\r
-        }\r
-\r
-        return $result;\r
-    }\r
-\r
-    /**\r
-     * Copy an object\r
-     *\r
-     * PHP5 passes objects by reference while PHP4 passes by value.  As such, we need a function to guarantee\r
-     * that all objects are passed by value, when appropriate.  More information can be found here:\r
-     *\r
-     * {@link http://php.net/language.oop5.basic#51624}\r
-     *\r
-     * @access public\r
-     * @see __clone()\r
-     * @return Math_BigInteger\r
-     */\r
-    function copy()\r
-    {\r
-        $temp = new Math_BigInteger();\r
-        $temp->value = $this->value;\r
-        $temp->is_negative = $this->is_negative;\r
-        $temp->generator = $this->generator;\r
-        $temp->precision = $this->precision;\r
-        $temp->bitmask = $this->bitmask;\r
-        return $temp;\r
-    }\r
-\r
-    /**\r
-     *  __toString() magic method\r
-     *\r
-     * Will be called, automatically, if you're supporting just PHP5.  If you're supporting PHP4, you'll need to call\r
-     * toString().\r
-     *\r
-     * @access public\r
-     * @internal Implemented per a suggestion by Techie-Michael - thanks!\r
-     */\r
-    function __toString()\r
-    {\r
-        return $this->toString();\r
-    }\r
-\r
-    /**\r
-     * __clone() magic method\r
-     *\r
-     * Although you can call Math_BigInteger::__toString() directly in PHP5, you cannot call Math_BigInteger::__clone()\r
-     * directly in PHP5.  You can in PHP4 since it's not a magic method, but in PHP5, you have to call it by using the PHP5\r
-     * only syntax of $y = clone $x.  As such, if you're trying to write an application that works on both PHP4 and PHP5,\r
-     * call Math_BigInteger::copy(), instead.\r
-     *\r
-     * @access public\r
-     * @see copy()\r
-     * @return Math_BigInteger\r
-     */\r
-    function __clone()\r
-    {\r
-        return $this->copy();\r
-    }\r
-\r
-    /**\r
-     *  __sleep() magic method\r
-     *\r
-     * Will be called, automatically, when serialize() is called on a Math_BigInteger object.\r
-     *\r
-     * @see __wakeup()\r
-     * @access public\r
-     */\r
-    function __sleep()\r
-    {\r
-        $this->hex = $this->toHex(true);\r
-        $vars = array('hex');\r
-        if ($this->generator != 'mt_rand') {\r
-            $vars[] = 'generator';\r
-        }\r
-        if ($this->precision > 0) {\r
-            $vars[] = 'precision';\r
-        }\r
-        return $vars;\r
-        \r
-    }\r
-\r
-    /**\r
-     *  __wakeup() magic method\r
-     *\r
-     * Will be called, automatically, when unserialize() is called on a Math_BigInteger object.\r
-     *\r
-     * @see __sleep()\r
-     * @access public\r
-     */\r
-    function __wakeup()\r
-    {\r
-        $temp = new Math_BigInteger($this->hex, -16);\r
-        $this->value = $temp->value;\r
-        $this->is_negative = $temp->is_negative;\r
-        $this->setRandomGenerator($this->generator);\r
-        if ($this->precision > 0) {\r
-            // recalculate $this->bitmask\r
-            $this->setPrecision($this->precision);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Adds two BigIntegers.\r
-     *\r
-     * Here's an example:\r
-     * <code>\r
-     * <?php\r
-     *    include('Math/BigInteger.php');\r
-     *\r
-     *    $a = new Math_BigInteger('10');\r
-     *    $b = new Math_BigInteger('20');\r
-     *\r
-     *    $c = $a->add($b);\r
-     *\r
-     *    echo $c->toString(); // outputs 30\r
-     * ?>\r
-     * </code>\r
-     *\r
-     * @param Math_BigInteger $y\r
-     * @return Math_BigInteger\r
-     * @access public\r
-     * @internal Performs base-2**52 addition\r
-     */\r
-    function add($y)\r
-    {\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                $temp = new Math_BigInteger();\r
-                $temp->value = gmp_add($this->value, $y->value);\r
-\r
-                return $this->_normalize($temp);\r
-            case MATH_BIGINTEGER_MODE_BCMATH:\r
-                $temp = new Math_BigInteger();\r
-                $temp->value = bcadd($this->value, $y->value, 0);\r
-\r
-                return $this->_normalize($temp);\r
-        }\r
-\r
-        $temp = $this->_add($this->value, $this->is_negative, $y->value, $y->is_negative);\r
-\r
-        $result = new Math_BigInteger();\r
-        $result->value = $temp[MATH_BIGINTEGER_VALUE];\r
-        $result->is_negative = $temp[MATH_BIGINTEGER_SIGN];\r
-\r
-        return $this->_normalize($result);\r
-    }\r
-\r
-    /**\r
-     * Performs addition.\r
-     *\r
-     * @param Array $x_value\r
-     * @param Boolean $x_negative\r
-     * @param Array $y_value\r
-     * @param Boolean $y_negative\r
-     * @return Array\r
-     * @access private\r
-     */\r
-    function _add($x_value, $x_negative, $y_value, $y_negative)\r
-    {\r
-        $x_size = count($x_value);\r
-        $y_size = count($y_value);\r
-\r
-        if ($x_size == 0) {\r
-            return array(\r
-                MATH_BIGINTEGER_VALUE => $y_value,\r
-                MATH_BIGINTEGER_SIGN => $y_negative\r
-            );\r
-        } else if ($y_size == 0) {\r
-            return array(\r
-                MATH_BIGINTEGER_VALUE => $x_value,\r
-                MATH_BIGINTEGER_SIGN => $x_negative\r
-            );\r
-        }\r
-\r
-        // subtract, if appropriate\r
-        if ( $x_negative != $y_negative ) {\r
-            if ( $x_value == $y_value ) {\r
-                return array(\r
-                    MATH_BIGINTEGER_VALUE => array(),\r
-                    MATH_BIGINTEGER_SIGN => false\r
-                );\r
-            }\r
-\r
-            $temp = $this->_subtract($x_value, false, $y_value, false);\r
-            $temp[MATH_BIGINTEGER_SIGN] = $this->_compare($x_value, false, $y_value, false) > 0 ?\r
-                                          $x_negative : $y_negative;\r
-\r
-            return $temp;\r
-        }\r
-\r
-        if ($x_size < $y_size) {\r
-            $size = $x_size;\r
-            $value = $y_value;\r
-        } else {\r
-            $size = $y_size;\r
-            $value = $x_value;\r
-        }\r
-\r
-        $value[] = 0; // just in case the carry adds an extra digit\r
-\r
-        $carry = 0;\r
-        for ($i = 0, $j = 1; $j < $size; $i+=2, $j+=2) {\r
-            $sum = $x_value[$j] * 0x4000000 + $x_value[$i] + $y_value[$j] * 0x4000000 + $y_value[$i] + $carry;\r
-            $carry = $sum >= MATH_BIGINTEGER_MAX_DIGIT52; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1\r
-            $sum = $carry ? $sum - MATH_BIGINTEGER_MAX_DIGIT52 : $sum;\r
-\r
-            $temp = (int) ($sum / 0x4000000);\r
-\r
-            $value[$i] = (int) ($sum - 0x4000000 * $temp); // eg. a faster alternative to fmod($sum, 0x4000000)\r
-            $value[$j] = $temp;\r
-        }\r
-\r
-        if ($j == $size) { // ie. if $y_size is odd\r
-            $sum = $x_value[$i] + $y_value[$i] + $carry;\r
-            $carry = $sum >= 0x4000000;\r
-            $value[$i] = $carry ? $sum - 0x4000000 : $sum;\r
-            ++$i; // ie. let $i = $j since we've just done $value[$i]\r
-        }\r
-\r
-        if ($carry) {\r
-            for (; $value[$i] == 0x3FFFFFF; ++$i) {\r
-                $value[$i] = 0;\r
-            }\r
-            ++$value[$i];\r
-        }\r
-\r
-        return array(\r
-            MATH_BIGINTEGER_VALUE => $this->_trim($value),\r
-            MATH_BIGINTEGER_SIGN => $x_negative\r
-        );\r
-    }\r
-\r
-    /**\r
-     * Subtracts two BigIntegers.\r
-     *\r
-     * Here's an example:\r
-     * <code>\r
-     * <?php\r
-     *    include('Math/BigInteger.php');\r
-     *\r
-     *    $a = new Math_BigInteger('10');\r
-     *    $b = new Math_BigInteger('20');\r
-     *\r
-     *    $c = $a->subtract($b);\r
-     *\r
-     *    echo $c->toString(); // outputs -10\r
-     * ?>\r
-     * </code>\r
-     *\r
-     * @param Math_BigInteger $y\r
-     * @return Math_BigInteger\r
-     * @access public\r
-     * @internal Performs base-2**52 subtraction\r
-     */\r
-    function subtract($y)\r
-    {\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                $temp = new Math_BigInteger();\r
-                $temp->value = gmp_sub($this->value, $y->value);\r
-\r
-                return $this->_normalize($temp);\r
-            case MATH_BIGINTEGER_MODE_BCMATH:\r
-                $temp = new Math_BigInteger();\r
-                $temp->value = bcsub($this->value, $y->value, 0);\r
-\r
-                return $this->_normalize($temp);\r
-        }\r
-\r
-        $temp = $this->_subtract($this->value, $this->is_negative, $y->value, $y->is_negative);\r
-\r
-        $result = new Math_BigInteger();\r
-        $result->value = $temp[MATH_BIGINTEGER_VALUE];\r
-        $result->is_negative = $temp[MATH_BIGINTEGER_SIGN];\r
-\r
-        return $this->_normalize($result);\r
-    }\r
-\r
-    /**\r
-     * Performs subtraction.\r
-     *\r
-     * @param Array $x_value\r
-     * @param Boolean $x_negative\r
-     * @param Array $y_value\r
-     * @param Boolean $y_negative\r
-     * @return Array\r
-     * @access private\r
-     */\r
-    function _subtract($x_value, $x_negative, $y_value, $y_negative)\r
-    {\r
-        $x_size = count($x_value);\r
-        $y_size = count($y_value);\r
-\r
-        if ($x_size == 0) {\r
-            return array(\r
-                MATH_BIGINTEGER_VALUE => $y_value,\r
-                MATH_BIGINTEGER_SIGN => !$y_negative\r
-            );\r
-        } else if ($y_size == 0) {\r
-            return array(\r
-                MATH_BIGINTEGER_VALUE => $x_value,\r
-                MATH_BIGINTEGER_SIGN => $x_negative\r
-            );\r
-        }\r
-\r
-        // add, if appropriate (ie. -$x - +$y or +$x - -$y)\r
-        if ( $x_negative != $y_negative ) {\r
-            $temp = $this->_add($x_value, false, $y_value, false);\r
-            $temp[MATH_BIGINTEGER_SIGN] = $x_negative;\r
-\r
-            return $temp;\r
-        }\r
-\r
-        $diff = $this->_compare($x_value, $x_negative, $y_value, $y_negative);\r
-\r
-        if ( !$diff ) {\r
-            return array(\r
-                MATH_BIGINTEGER_VALUE => array(),\r
-                MATH_BIGINTEGER_SIGN => false\r
-            );\r
-        }\r
-\r
-        // switch $x and $y around, if appropriate.\r
-        if ( (!$x_negative && $diff < 0) || ($x_negative && $diff > 0) ) {\r
-            $temp = $x_value;\r
-            $x_value = $y_value;\r
-            $y_value = $temp;\r
-\r
-            $x_negative = !$x_negative;\r
-\r
-            $x_size = count($x_value);\r
-            $y_size = count($y_value);\r
-        }\r
-\r
-        // at this point, $x_value should be at least as big as - if not bigger than - $y_value\r
-\r
-        $carry = 0;\r
-        for ($i = 0, $j = 1; $j < $y_size; $i+=2, $j+=2) {\r
-            $sum = $x_value[$j] * 0x4000000 + $x_value[$i] - $y_value[$j] * 0x4000000 - $y_value[$i] - $carry;\r
-            $carry = $sum < 0; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1\r
-            $sum = $carry ? $sum + MATH_BIGINTEGER_MAX_DIGIT52 : $sum;\r
-\r
-            $temp = (int) ($sum / 0x4000000);\r
-\r
-            $x_value[$i] = (int) ($sum - 0x4000000 * $temp);\r
-            $x_value[$j] = $temp;\r
-        }\r
-\r
-        if ($j == $y_size) { // ie. if $y_size is odd\r
-            $sum = $x_value[$i] - $y_value[$i] - $carry;\r
-            $carry = $sum < 0;\r
-            $x_value[$i] = $carry ? $sum + 0x4000000 : $sum;\r
-            ++$i;\r
-        }\r
-\r
-        if ($carry) {\r
-            for (; !$x_value[$i]; ++$i) {\r
-                $x_value[$i] = 0x3FFFFFF;\r
-            }\r
-            --$x_value[$i];\r
-        }\r
-\r
-        return array(\r
-            MATH_BIGINTEGER_VALUE => $this->_trim($x_value),\r
-            MATH_BIGINTEGER_SIGN => $x_negative\r
-        );\r
-    }\r
-\r
-    /**\r
-     * Multiplies two BigIntegers\r
-     *\r
-     * Here's an example:\r
-     * <code>\r
-     * <?php\r
-     *    include('Math/BigInteger.php');\r
-     *\r
-     *    $a = new Math_BigInteger('10');\r
-     *    $b = new Math_BigInteger('20');\r
-     *\r
-     *    $c = $a->multiply($b);\r
-     *\r
-     *    echo $c->toString(); // outputs 200\r
-     * ?>\r
-     * </code>\r
-     *\r
-     * @param Math_BigInteger $x\r
-     * @return Math_BigInteger\r
-     * @access public\r
-     */\r
-    function multiply($x)\r
-    {\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                $temp = new Math_BigInteger();\r
-                $temp->value = gmp_mul($this->value, $x->value);\r
-\r
-                return $this->_normalize($temp);\r
-            case MATH_BIGINTEGER_MODE_BCMATH:\r
-                $temp = new Math_BigInteger();\r
-                $temp->value = bcmul($this->value, $x->value, 0);\r
-\r
-                return $this->_normalize($temp);\r
-        }\r
-\r
-        $temp = $this->_multiply($this->value, $this->is_negative, $x->value, $x->is_negative);\r
-\r
-        $product = new Math_BigInteger();\r
-        $product->value = $temp[MATH_BIGINTEGER_VALUE];\r
-        $product->is_negative = $temp[MATH_BIGINTEGER_SIGN];\r
-\r
-        return $this->_normalize($product);\r
-    }\r
-\r
-    /**\r
-     * Performs multiplication.\r
-     *\r
-     * @param Array $x_value\r
-     * @param Boolean $x_negative\r
-     * @param Array $y_value\r
-     * @param Boolean $y_negative\r
-     * @return Array\r
-     * @access private\r
-     */\r
-    function _multiply($x_value, $x_negative, $y_value, $y_negative)\r
-    {\r
-        //if ( $x_value == $y_value ) {\r
-        //    return array(\r
-        //        MATH_BIGINTEGER_VALUE => $this->_square($x_value),\r
-        //        MATH_BIGINTEGER_SIGN => $x_sign != $y_value\r
-        //    );\r
-        //}\r
-\r
-        $x_length = count($x_value);\r
-        $y_length = count($y_value);\r
-\r
-        if ( !$x_length || !$y_length ) { // a 0 is being multiplied\r
-            return array(\r
-                MATH_BIGINTEGER_VALUE => array(),\r
-                MATH_BIGINTEGER_SIGN => false\r
-            );\r
-        }\r
-\r
-        return array(\r
-            MATH_BIGINTEGER_VALUE => min($x_length, $y_length) < 2 * MATH_BIGINTEGER_KARATSUBA_CUTOFF ?\r
-                $this->_trim($this->_regularMultiply($x_value, $y_value)) :\r
-                $this->_trim($this->_karatsuba($x_value, $y_value)),\r
-            MATH_BIGINTEGER_SIGN => $x_negative != $y_negative\r
-        );\r
-    }\r
-\r
-    /**\r
-     * Performs long multiplication on two BigIntegers\r
-     *\r
-     * Modeled after 'multiply' in MutableBigInteger.java.\r
-     *\r
-     * @param Array $x_value\r
-     * @param Array $y_value\r
-     * @return Array\r
-     * @access private\r
-     */\r
-    function _regularMultiply($x_value, $y_value)\r
-    {\r
-        $x_length = count($x_value);\r
-        $y_length = count($y_value);\r
-\r
-        if ( !$x_length || !$y_length ) { // a 0 is being multiplied\r
-            return array();\r
-        }\r
-\r
-        if ( $x_length < $y_length ) {\r
-            $temp = $x_value;\r
-            $x_value = $y_value;\r
-            $y_value = $temp;\r
-\r
-            $x_length = count($x_value);\r
-            $y_length = count($y_value);\r
-        }\r
-\r
-        $product_value = $this->_array_repeat(0, $x_length + $y_length);\r
-\r
-        // the following for loop could be removed if the for loop following it\r
-        // (the one with nested for loops) initially set $i to 0, but\r
-        // doing so would also make the result in one set of unnecessary adds,\r
-        // since on the outermost loops first pass, $product->value[$k] is going\r
-        // to always be 0\r
-\r
-        $carry = 0;\r
-\r
-        for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0\r
-            $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0\r
-            $carry = (int) ($temp / 0x4000000);\r
-            $product_value[$j] = (int) ($temp - 0x4000000 * $carry);\r
-        }\r
-\r
-        $product_value[$j] = $carry;\r
-\r
-        // the above for loop is what the previous comment was talking about.  the\r
-        // following for loop is the "one with nested for loops"\r
-        for ($i = 1; $i < $y_length; ++$i) {\r
-            $carry = 0;\r
-\r
-            for ($j = 0, $k = $i; $j < $x_length; ++$j, ++$k) {\r
-                $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry;\r
-                $carry = (int) ($temp / 0x4000000);\r
-                $product_value[$k] = (int) ($temp - 0x4000000 * $carry);\r
-            }\r
-\r
-            $product_value[$k] = $carry;\r
-        }\r
-\r
-        return $product_value;\r
-    }\r
-\r
-    /**\r
-     * Performs Karatsuba multiplication on two BigIntegers\r
-     *\r
-     * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and\r
-     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=120 MPM 5.2.3}.\r
-     *\r
-     * @param Array $x_value\r
-     * @param Array $y_value\r
-     * @return Array\r
-     * @access private\r
-     */\r
-    function _karatsuba($x_value, $y_value)\r
-    {\r
-        $m = min(count($x_value) >> 1, count($y_value) >> 1);\r
-\r
-        if ($m < MATH_BIGINTEGER_KARATSUBA_CUTOFF) {\r
-            return $this->_regularMultiply($x_value, $y_value);\r
-        }\r
-\r
-        $x1 = array_slice($x_value, $m);\r
-        $x0 = array_slice($x_value, 0, $m);\r
-        $y1 = array_slice($y_value, $m);\r
-        $y0 = array_slice($y_value, 0, $m);\r
-\r
-        $z2 = $this->_karatsuba($x1, $y1);\r
-        $z0 = $this->_karatsuba($x0, $y0);\r
-\r
-        $z1 = $this->_add($x1, false, $x0, false);\r
-        $temp = $this->_add($y1, false, $y0, false);\r
-        $z1 = $this->_karatsuba($z1[MATH_BIGINTEGER_VALUE], $temp[MATH_BIGINTEGER_VALUE]);\r
-        $temp = $this->_add($z2, false, $z0, false);\r
-        $z1 = $this->_subtract($z1, false, $temp[MATH_BIGINTEGER_VALUE], false);\r
-\r
-        $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2);\r
-        $z1[MATH_BIGINTEGER_VALUE] = array_merge(array_fill(0, $m, 0), $z1[MATH_BIGINTEGER_VALUE]);\r
-\r
-        $xy = $this->_add($z2, false, $z1[MATH_BIGINTEGER_VALUE], $z1[MATH_BIGINTEGER_SIGN]);\r
-        $xy = $this->_add($xy[MATH_BIGINTEGER_VALUE], $xy[MATH_BIGINTEGER_SIGN], $z0, false);\r
-\r
-        return $xy[MATH_BIGINTEGER_VALUE];\r
-    }\r
-\r
-    /**\r
-     * Performs squaring\r
-     *\r
-     * @param Array $x\r
-     * @return Array\r
-     * @access private\r
-     */\r
-    function _square($x = false)\r
-    {\r
-        return count($x) < 2 * MATH_BIGINTEGER_KARATSUBA_CUTOFF ?\r
-            $this->_trim($this->_baseSquare($x)) :\r
-            $this->_trim($this->_karatsubaSquare($x));\r
-    }\r
-\r
-    /**\r
-     * Performs traditional squaring on two BigIntegers\r
-     *\r
-     * Squaring can be done faster than multiplying a number by itself can be.  See\r
-     * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=7 HAC 14.2.4} /\r
-     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=141 MPM 5.3} for more information.\r
-     *\r
-     * @param Array $value\r
-     * @return Array\r
-     * @access private\r
-     */\r
-    function _baseSquare($value)\r
-    {\r
-        if ( empty($value) ) {\r
-            return array();\r
-        }\r
-        $square_value = $this->_array_repeat(0, 2 * count($value));\r
-\r
-        for ($i = 0, $max_index = count($value) - 1; $i <= $max_index; ++$i) {\r
-            $i2 = $i << 1;\r
-\r
-            $temp = $square_value[$i2] + $value[$i] * $value[$i];\r
-            $carry = (int) ($temp / 0x4000000);\r
-            $square_value[$i2] = (int) ($temp - 0x4000000 * $carry);\r
-\r
-            // note how we start from $i+1 instead of 0 as we do in multiplication.\r
-            for ($j = $i + 1, $k = $i2 + 1; $j <= $max_index; ++$j, ++$k) {\r
-                $temp = $square_value[$k] + 2 * $value[$j] * $value[$i] + $carry;\r
-                $carry = (int) ($temp / 0x4000000);\r
-                $square_value[$k] = (int) ($temp - 0x4000000 * $carry);\r
-            }\r
-\r
-            // the following line can yield values larger 2**15.  at this point, PHP should switch\r
-            // over to floats.\r
-            $square_value[$i + $max_index + 1] = $carry;\r
-        }\r
-\r
-        return $square_value;\r
-    }\r
-\r
-    /**\r
-     * Performs Karatsuba "squaring" on two BigIntegers\r
-     *\r
-     * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and\r
-     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=151 MPM 5.3.4}.\r
-     *\r
-     * @param Array $value\r
-     * @return Array\r
-     * @access private\r
-     */\r
-    function _karatsubaSquare($value)\r
-    {\r
-        $m = count($value) >> 1;\r
-\r
-        if ($m < MATH_BIGINTEGER_KARATSUBA_CUTOFF) {\r
-            return $this->_baseSquare($value);\r
-        }\r
-\r
-        $x1 = array_slice($value, $m);\r
-        $x0 = array_slice($value, 0, $m);\r
-\r
-        $z2 = $this->_karatsubaSquare($x1);\r
-        $z0 = $this->_karatsubaSquare($x0);\r
-\r
-        $z1 = $this->_add($x1, false, $x0, false);\r
-        $z1 = $this->_karatsubaSquare($z1[MATH_BIGINTEGER_VALUE]);\r
-        $temp = $this->_add($z2, false, $z0, false);\r
-        $z1 = $this->_subtract($z1, false, $temp[MATH_BIGINTEGER_VALUE], false);\r
-\r
-        $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2);\r
-        $z1[MATH_BIGINTEGER_VALUE] = array_merge(array_fill(0, $m, 0), $z1[MATH_BIGINTEGER_VALUE]);\r
-\r
-        $xx = $this->_add($z2, false, $z1[MATH_BIGINTEGER_VALUE], $z1[MATH_BIGINTEGER_SIGN]);\r
-        $xx = $this->_add($xx[MATH_BIGINTEGER_VALUE], $xx[MATH_BIGINTEGER_SIGN], $z0, false);\r
-\r
-        return $xx[MATH_BIGINTEGER_VALUE];\r
-    }\r
-\r
-    /**\r
-     * Divides two BigIntegers.\r
-     *\r
-     * Returns an array whose first element contains the quotient and whose second element contains the\r
-     * "common residue".  If the remainder would be positive, the "common residue" and the remainder are the\r
-     * same.  If the remainder would be negative, the "common residue" is equal to the sum of the remainder\r
-     * and the divisor (basically, the "common residue" is the first positive modulo).\r
-     *\r
-     * Here's an example:\r
-     * <code>\r
-     * <?php\r
-     *    include('Math/BigInteger.php');\r
-     *\r
-     *    $a = new Math_BigInteger('10');\r
-     *    $b = new Math_BigInteger('20');\r
-     *\r
-     *    list($quotient, $remainder) = $a->divide($b);\r
-     *\r
-     *    echo $quotient->toString(); // outputs 0\r
-     *    echo "\r\n";\r
-     *    echo $remainder->toString(); // outputs 10\r
-     * ?>\r
-     * </code>\r
-     *\r
-     * @param Math_BigInteger $y\r
-     * @return Array\r
-     * @access public\r
-     * @internal This function is based off of {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}.\r
-     */\r
-    function divide($y)\r
-    {\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                $quotient = new Math_BigInteger();\r
-                $remainder = new Math_BigInteger();\r
-\r
-                list($quotient->value, $remainder->value) = gmp_div_qr($this->value, $y->value);\r
-\r
-                if (gmp_sign($remainder->value) < 0) {\r
-                    $remainder->value = gmp_add($remainder->value, gmp_abs($y->value));\r
-                }\r
-\r
-                return array($this->_normalize($quotient), $this->_normalize($remainder));\r
-            case MATH_BIGINTEGER_MODE_BCMATH:\r
-                $quotient = new Math_BigInteger();\r
-                $remainder = new Math_BigInteger();\r
-\r
-                $quotient->value = bcdiv($this->value, $y->value, 0);\r
-                $remainder->value = bcmod($this->value, $y->value);\r
-\r
-                if ($remainder->value[0] == '-') {\r
-                    $remainder->value = bcadd($remainder->value, $y->value[0] == '-' ? substr($y->value, 1) : $y->value, 0);\r
-                }\r
-\r
-                return array($this->_normalize($quotient), $this->_normalize($remainder));\r
-        }\r
-\r
-        if (count($y->value) == 1) {\r
-            list($q, $r) = $this->_divide_digit($this->value, $y->value[0]);\r
-            $quotient = new Math_BigInteger();\r
-            $remainder = new Math_BigInteger();\r
-            $quotient->value = $q;\r
-            $remainder->value = array($r);\r
-            $quotient->is_negative = $this->is_negative != $y->is_negative;\r
-            return array($this->_normalize($quotient), $this->_normalize($remainder));\r
-        }\r
-\r
-        static $zero;\r
-        if ( !isset($zero) ) {\r
-            $zero = new Math_BigInteger();\r
-        }\r
-\r
-        $x = $this->copy();\r
-        $y = $y->copy();\r
-\r
-        $x_sign = $x->is_negative;\r
-        $y_sign = $y->is_negative;\r
-\r
-        $x->is_negative = $y->is_negative = false;\r
-\r
-        $diff = $x->compare($y);\r
-\r
-        if ( !$diff ) {\r
-            $temp = new Math_BigInteger();\r
-            $temp->value = array(1);\r
-            $temp->is_negative = $x_sign != $y_sign;\r
-            return array($this->_normalize($temp), $this->_normalize(new Math_BigInteger()));\r
-        }\r
-\r
-        if ( $diff < 0 ) {\r
-            // if $x is negative, "add" $y.\r
-            if ( $x_sign ) {\r
-                $x = $y->subtract($x);\r
-            }\r
-            return array($this->_normalize(new Math_BigInteger()), $this->_normalize($x));\r
-        }\r
-\r
-        // normalize $x and $y as described in HAC 14.23 / 14.24\r
-        $msb = $y->value[count($y->value) - 1];\r
-        for ($shift = 0; !($msb & 0x2000000); ++$shift) {\r
-            $msb <<= 1;\r
-        }\r
-        $x->_lshift($shift);\r
-        $y->_lshift($shift);\r
-        $y_value = &$y->value;\r
-\r
-        $x_max = count($x->value) - 1;\r
-        $y_max = count($y->value) - 1;\r
-\r
-        $quotient = new Math_BigInteger();\r
-        $quotient_value = &$quotient->value;\r
-        $quotient_value = $this->_array_repeat(0, $x_max - $y_max + 1);\r
-\r
-        static $temp, $lhs, $rhs;\r
-        if (!isset($temp)) {\r
-            $temp = new Math_BigInteger();\r
-            $lhs =  new Math_BigInteger();\r
-            $rhs =  new Math_BigInteger();\r
-        }\r
-        $temp_value = &$temp->value;\r
-        $rhs_value =  &$rhs->value;\r
-\r
-        // $temp = $y << ($x_max - $y_max-1) in base 2**26\r
-        $temp_value = array_merge($this->_array_repeat(0, $x_max - $y_max), $y_value);\r
-\r
-        while ( $x->compare($temp) >= 0 ) {\r
-            // calculate the "common residue"\r
-            ++$quotient_value[$x_max - $y_max];\r
-            $x = $x->subtract($temp);\r
-            $x_max = count($x->value) - 1;\r
-        }\r
-\r
-        for ($i = $x_max; $i >= $y_max + 1; --$i) {\r
-            $x_value = &$x->value;\r
-            $x_window = array(\r
-                isset($x_value[$i]) ? $x_value[$i] : 0,\r
-                isset($x_value[$i - 1]) ? $x_value[$i - 1] : 0,\r
-                isset($x_value[$i - 2]) ? $x_value[$i - 2] : 0\r
-            );\r
-            $y_window = array(\r
-                $y_value[$y_max],\r
-                ( $y_max > 0 ) ? $y_value[$y_max - 1] : 0\r
-            );\r
-\r
-            $q_index = $i - $y_max - 1;\r
-            if ($x_window[0] == $y_window[0]) {\r
-                $quotient_value[$q_index] = 0x3FFFFFF;\r
-            } else {\r
-                $quotient_value[$q_index] = (int) (\r
-                    ($x_window[0] * 0x4000000 + $x_window[1])\r
-                    /\r
-                    $y_window[0]\r
-                );\r
-            }\r
-\r
-            $temp_value = array($y_window[1], $y_window[0]);\r
-\r
-            $lhs->value = array($quotient_value[$q_index]);\r
-            $lhs = $lhs->multiply($temp);\r
-\r
-            $rhs_value = array($x_window[2], $x_window[1], $x_window[0]);\r
-\r
-            while ( $lhs->compare($rhs) > 0 ) {\r
-                --$quotient_value[$q_index];\r
-\r
-                $lhs->value = array($quotient_value[$q_index]);\r
-                $lhs = $lhs->multiply($temp);\r
-            }\r
-\r
-            $adjust = $this->_array_repeat(0, $q_index);\r
-            $temp_value = array($quotient_value[$q_index]);\r
-            $temp = $temp->multiply($y);\r
-            $temp_value = &$temp->value;\r
-            $temp_value = array_merge($adjust, $temp_value);\r
-\r
-            $x = $x->subtract($temp);\r
-\r
-            if ($x->compare($zero) < 0) {\r
-                $temp_value = array_merge($adjust, $y_value);\r
-                $x = $x->add($temp);\r
-\r
-                --$quotient_value[$q_index];\r
-            }\r
-\r
-            $x_max = count($x_value) - 1;\r
-        }\r
-\r
-        // unnormalize the remainder\r
-        $x->_rshift($shift);\r
-\r
-        $quotient->is_negative = $x_sign != $y_sign;\r
-\r
-        // calculate the "common residue", if appropriate\r
-        if ( $x_sign ) {\r
-            $y->_rshift($shift);\r
-            $x = $y->subtract($x);\r
-        }\r
-\r
-        return array($this->_normalize($quotient), $this->_normalize($x));\r
-    }\r
-\r
-    /**\r
-     * Divides a BigInteger by a regular integer\r
-     *\r
-     * abc / x = a00 / x + b0 / x + c / x\r
-     *\r
-     * @param Array $dividend\r
-     * @param Array $divisor\r
-     * @return Array\r
-     * @access private\r
-     */\r
-    function _divide_digit($dividend, $divisor)\r
-    {\r
-        $carry = 0;\r
-        $result = array();\r
-\r
-        for ($i = count($dividend) - 1; $i >= 0; --$i) {\r
-            $temp = 0x4000000 * $carry + $dividend[$i];\r
-            $result[$i] = (int) ($temp / $divisor);\r
-            $carry = (int) ($temp - $divisor * $result[$i]);\r
-        }\r
-\r
-        return array($result, $carry);\r
-    }\r
-\r
-    /**\r
-     * Performs modular exponentiation.\r
-     *\r
-     * Here's an example:\r
-     * <code>\r
-     * <?php\r
-     *    include('Math/BigInteger.php');\r
-     *\r
-     *    $a = new Math_BigInteger('10');\r
-     *    $b = new Math_BigInteger('20');\r
-     *    $c = new Math_BigInteger('30');\r
-     *\r
-     *    $c = $a->modPow($b, $c);\r
-     *\r
-     *    echo $c->toString(); // outputs 10\r
-     * ?>\r
-     * </code>\r
-     *\r
-     * @param Math_BigInteger $e\r
-     * @param Math_BigInteger $n\r
-     * @return Math_BigInteger\r
-     * @access public\r
-     * @internal The most naive approach to modular exponentiation has very unreasonable requirements, and\r
-     *    and although the approach involving repeated squaring does vastly better, it, too, is impractical\r
-     *    for our purposes.  The reason being that division - by far the most complicated and time-consuming\r
-     *    of the basic operations (eg. +,-,*,/) - occurs multiple times within it.\r
-     *\r
-     *    Modular reductions resolve this issue.  Although an individual modular reduction takes more time\r
-     *    then an individual division, when performed in succession (with the same modulo), they're a lot faster.\r
-     *\r
-     *    The two most commonly used modular reductions are Barrett and Montgomery reduction.  Montgomery reduction,\r
-     *    although faster, only works when the gcd of the modulo and of the base being used is 1.  In RSA, when the\r
-     *    base is a power of two, the modulo - a product of two primes - is always going to have a gcd of 1 (because\r
-     *    the product of two odd numbers is odd), but what about when RSA isn't used?\r
-     *\r
-     *    In contrast, Barrett reduction has no such constraint.  As such, some bigint implementations perform a\r
-     *    Barrett reduction after every operation in the modpow function.  Others perform Barrett reductions when the\r
-     *    modulo is even and Montgomery reductions when the modulo is odd.  BigInteger.java's modPow method, however,\r
-     *    uses a trick involving the Chinese Remainder Theorem to factor the even modulo into two numbers - one odd and\r
-     *    the other, a power of two - and recombine them, later.  This is the method that this modPow function uses.\r
-     *    {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates.\r
-     */\r
-    function modPow($e, $n)\r
-    {\r
-        $n = $this->bitmask !== false && $this->bitmask->compare($n) < 0 ? $this->bitmask : $n->abs();\r
-\r
-        if ($e->compare(new Math_BigInteger()) < 0) {\r
-            $e = $e->abs();\r
-\r
-            $temp = $this->modInverse($n);\r
-            if ($temp === false) {\r
-                return false;\r
-            }\r
-\r
-            return $this->_normalize($temp->modPow($e, $n));\r
-        }\r
-\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                $temp = new Math_BigInteger();\r
-                $temp->value = gmp_powm($this->value, $e->value, $n->value);\r
-\r
-                return $this->_normalize($temp);\r
-            case MATH_BIGINTEGER_MODE_BCMATH:\r
-                $temp = new Math_BigInteger();\r
-                $temp->value = bcpowmod($this->value, $e->value, $n->value, 0);\r
-\r
-                return $this->_normalize($temp);\r
-        }\r
-\r
-        if ( empty($e->value) ) {\r
-            $temp = new Math_BigInteger();\r
-            $temp->value = array(1);\r
-            return $this->_normalize($temp);\r
-        }\r
-\r
-        if ( $e->value == array(1) ) {\r
-            list(, $temp) = $this->divide($n);\r
-            return $this->_normalize($temp);\r
-        }\r
-\r
-        if ( $e->value == array(2) ) {\r
-            $temp = new Math_BigInteger();\r
-            $temp->value = $this->_square($this->value);\r
-            list(, $temp) = $temp->divide($n);\r
-            return $this->_normalize($temp);\r
-        }\r
-\r
-        return $this->_normalize($this->_slidingWindow($e, $n, MATH_BIGINTEGER_BARRETT));\r
-\r
-        // is the modulo odd?\r
-        if ( $n->value[0] & 1 ) {\r
-            return $this->_normalize($this->_slidingWindow($e, $n, MATH_BIGINTEGER_MONTGOMERY));\r
-        }\r
-        // if it's not, it's even\r
-\r
-        // find the lowest set bit (eg. the max pow of 2 that divides $n)\r
-        for ($i = 0; $i < count($n->value); ++$i) {\r
-            if ( $n->value[$i] ) {\r
-                $temp = decbin($n->value[$i]);\r
-                $j = strlen($temp) - strrpos($temp, '1') - 1;\r
-                $j+= 26 * $i;\r
-                break;\r
-            }\r
-        }\r
-        // at this point, 2^$j * $n/(2^$j) == $n\r
-\r
-        $mod1 = $n->copy();\r
-        $mod1->_rshift($j);\r
-        $mod2 = new Math_BigInteger();\r
-        $mod2->value = array(1);\r
-        $mod2->_lshift($j);\r
-\r
-        $part1 = ( $mod1->value != array(1) ) ? $this->_slidingWindow($e, $mod1, MATH_BIGINTEGER_MONTGOMERY) : new Math_BigInteger();\r
-        $part2 = $this->_slidingWindow($e, $mod2, MATH_BIGINTEGER_POWEROF2);\r
-\r
-        $y1 = $mod2->modInverse($mod1);\r
-        $y2 = $mod1->modInverse($mod2);\r
-\r
-        $result = $part1->multiply($mod2);\r
-        $result = $result->multiply($y1);\r
-\r
-        $temp = $part2->multiply($mod1);\r
-        $temp = $temp->multiply($y2);\r
-\r
-        $result = $result->add($temp);\r
-        list(, $result) = $result->divide($n);\r
-\r
-        return $this->_normalize($result);\r
-    }\r
-\r
-    /**\r
-     * Performs modular exponentiation.\r
-     *\r
-     * Alias for Math_BigInteger::modPow()\r
-     *\r
-     * @param Math_BigInteger $e\r
-     * @param Math_BigInteger $n\r
-     * @return Math_BigInteger\r
-     * @access public\r
-     */\r
-    function powMod($e, $n)\r
-    {\r
-        return $this->modPow($e, $n);\r
-    }\r
-\r
-    /**\r
-     * Sliding Window k-ary Modular Exponentiation\r
-     *\r
-     * Based on {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=27 HAC 14.85} /\r
-     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=210 MPM 7.7}.  In a departure from those algorithims,\r
-     * however, this function performs a modular reduction after every multiplication and squaring operation.\r
-     * As such, this function has the same preconditions that the reductions being used do.\r
-     *\r
-     * @param Math_BigInteger $e\r
-     * @param Math_BigInteger $n\r
-     * @param Integer $mode\r
-     * @return Math_BigInteger\r
-     * @access private\r
-     */\r
-    function _slidingWindow($e, $n, $mode)\r
-    {\r
-        static $window_ranges = array(7, 25, 81, 241, 673, 1793); // from BigInteger.java's oddModPow function\r
-        //static $window_ranges = array(0, 7, 36, 140, 450, 1303, 3529); // from MPM 7.3.1\r
-\r
-        $e_value = $e->value;\r
-        $e_length = count($e_value) - 1;\r
-        $e_bits = decbin($e_value[$e_length]);\r
-        for ($i = $e_length - 1; $i >= 0; --$i) {\r
-            $e_bits.= str_pad(decbin($e_value[$i]), 26, '0', STR_PAD_LEFT);\r
-        }\r
-\r
-        $e_length = strlen($e_bits);\r
-\r
-        // calculate the appropriate window size.\r
-        // $window_size == 3 if $window_ranges is between 25 and 81, for example.\r
-        for ($i = 0, $window_size = 1; $e_length > $window_ranges[$i] && $i < count($window_ranges); ++$window_size, ++$i);\r
-\r
-        $n_value = $n->value;\r
-\r
-        // precompute $this^0 through $this^$window_size\r
-        $powers = array();\r
-        $powers[1] = $this->_prepareReduce($this->value, $n_value, $mode);\r
-        $powers[2] = $this->_squareReduce($powers[1], $n_value, $mode);\r
-\r
-        // we do every other number since substr($e_bits, $i, $j+1) (see below) is supposed to end\r
-        // in a 1.  ie. it's supposed to be odd.\r
-        $temp = 1 << ($window_size - 1);\r
-        for ($i = 1; $i < $temp; ++$i) {\r
-            $i2 = $i << 1;\r
-            $powers[$i2 + 1] = $this->_multiplyReduce($powers[$i2 - 1], $powers[2], $n_value, $mode);\r
-        }\r
-\r
-        $result = array(1);\r
-        $result = $this->_prepareReduce($result, $n_value, $mode);\r
-\r
-        for ($i = 0; $i < $e_length; ) {\r
-            if ( !$e_bits[$i] ) {\r
-                $result = $this->_squareReduce($result, $n_value, $mode);\r
-                ++$i;\r
-            } else {\r
-                for ($j = $window_size - 1; $j > 0; --$j) {\r
-                    if ( !empty($e_bits[$i + $j]) ) {\r
-                        break;\r
-                    }\r
-                }\r
-\r
-                for ($k = 0; $k <= $j; ++$k) {// eg. the length of substr($e_bits, $i, $j+1)\r
-                    $result = $this->_squareReduce($result, $n_value, $mode);\r
-                }\r
-\r
-                $result = $this->_multiplyReduce($result, $powers[bindec(substr($e_bits, $i, $j + 1))], $n_value, $mode);\r
-\r
-                $i+=$j + 1;\r
-            }\r
-        }\r
-\r
-        $temp = new Math_BigInteger();\r
-        $temp->value = $this->_reduce($result, $n_value, $mode);\r
-\r
-        return $temp;\r
-    }\r
-\r
-    /**\r
-     * Modular reduction\r
-     *\r
-     * For most $modes this will return the remainder.\r
-     *\r
-     * @see _slidingWindow()\r
-     * @access private\r
-     * @param Array $x\r
-     * @param Array $n\r
-     * @param Integer $mode\r
-     * @return Array\r
-     */\r
-    function _reduce($x, $n, $mode)\r
-    {\r
-        switch ($mode) {\r
-            case MATH_BIGINTEGER_MONTGOMERY:\r
-                return $this->_montgomery($x, $n);\r
-            case MATH_BIGINTEGER_BARRETT:\r
-                return $this->_barrett($x, $n);\r
-            case MATH_BIGINTEGER_POWEROF2:\r
-                $lhs = new Math_BigInteger();\r
-                $lhs->value = $x;\r
-                $rhs = new Math_BigInteger();\r
-                $rhs->value = $n;\r
-                return $x->_mod2($n);\r
-            case MATH_BIGINTEGER_CLASSIC:\r
-                $lhs = new Math_BigInteger();\r
-                $lhs->value = $x;\r
-                $rhs = new Math_BigInteger();\r
-                $rhs->value = $n;\r
-                list(, $temp) = $lhs->divide($rhs);\r
-                return $temp->value;\r
-            case MATH_BIGINTEGER_NONE:\r
-                return $x;\r
-            default:\r
-                // an invalid $mode was provided\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Modular reduction preperation\r
-     *\r
-     * @see _slidingWindow()\r
-     * @access private\r
-     * @param Array $x\r
-     * @param Array $n\r
-     * @param Integer $mode\r
-     * @return Array\r
-     */\r
-    function _prepareReduce($x, $n, $mode)\r
-    {\r
-        if ($mode == MATH_BIGINTEGER_MONTGOMERY) {\r
-            return $this->_prepMontgomery($x, $n);\r
-        }\r
-        return $this->_reduce($x, $n, $mode);\r
-    }\r
-\r
-    /**\r
-     * Modular multiply\r
-     *\r
-     * @see _slidingWindow()\r
-     * @access private\r
-     * @param Array $x\r
-     * @param Array $y\r
-     * @param Array $n\r
-     * @param Integer $mode\r
-     * @return Array\r
-     */\r
-    function _multiplyReduce($x, $y, $n, $mode)\r
-    {\r
-        if ($mode == MATH_BIGINTEGER_MONTGOMERY) {\r
-            return $this->_montgomeryMultiply($x, $y, $n);\r
-        }\r
-        $temp = $this->_multiply($x, false, $y, false);\r
-        return $this->_reduce($temp[MATH_BIGINTEGER_VALUE], $n, $mode);\r
-    }\r
-\r
-    /**\r
-     * Modular square\r
-     *\r
-     * @see _slidingWindow()\r
-     * @access private\r
-     * @param Array $x\r
-     * @param Array $n\r
-     * @param Integer $mode\r
-     * @return Array\r
-     */\r
-    function _squareReduce($x, $n, $mode)\r
-    {\r
-        if ($mode == MATH_BIGINTEGER_MONTGOMERY) {\r
-            return $this->_montgomeryMultiply($x, $x, $n);\r
-        }\r
-        return $this->_reduce($this->_square($x), $n, $mode);\r
-    }\r
-\r
-    /**\r
-     * Modulos for Powers of Two\r
-     *\r
-     * Calculates $x%$n, where $n = 2**$e, for some $e.  Since this is basically the same as doing $x & ($n-1),\r
-     * we'll just use this function as a wrapper for doing that.\r
-     *\r
-     * @see _slidingWindow()\r
-     * @access private\r
-     * @param Math_BigInteger\r
-     * @return Math_BigInteger\r
-     */\r
-    function _mod2($n)\r
-    {\r
-        $temp = new Math_BigInteger();\r
-        $temp->value = array(1);\r
-        return $this->bitwise_and($n->subtract($temp));\r
-    }\r
-\r
-    /**\r
-     * Barrett Modular Reduction\r
-     *\r
-     * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} /\r
-     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information.  Modified slightly,\r
-     * so as not to require negative numbers (initially, this script didn't support negative numbers).\r
-     *\r
-     * Employs "folding", as described at\r
-     * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}.  To quote from\r
-     * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x."\r
-     *\r
-     * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that\r
-     * usable on account of (1) its not using reasonable radix points as discussed in\r
-     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable\r
-     * radix points, it only works when there are an even number of digits in the denominator.  The reason for (2) is that\r
-     * (x >> 1) + (x >> 1) != x / 2 + x / 2.  If x is even, they're the same, but if x is odd, they're not.  See the in-line\r
-     * comments for details.\r
-     *\r
-     * @see _slidingWindow()\r
-     * @access private\r
-     * @param Array $n\r
-     * @param Array $m\r
-     * @return Array\r
-     */\r
-    function _barrett($n, $m)\r
-    {\r
-        static $cache = array(\r
-            MATH_BIGINTEGER_VARIABLE => array(),\r
-            MATH_BIGINTEGER_DATA => array()\r
-        );\r
-\r
-        $m_length = count($m);\r
-\r
-        // if ($this->_compare($n, $this->_square($m)) >= 0) {\r
-        if (count($n) > 2 * $m_length) {\r
-            $lhs = new Math_BigInteger();\r
-            $rhs = new Math_BigInteger();\r
-            $lhs->value = $n;\r
-            $rhs->value = $m;\r
-            list(, $temp) = $lhs->divide($rhs);\r
-            return $temp->value;\r
-        }\r
-\r
-        // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced\r
-        if ($m_length < 5) {\r
-            return $this->_regularBarrett($n, $m);\r
-        }\r
-\r
-        // n = 2 * m.length\r
-\r
-        if ( ($key = array_search($m, $cache[MATH_BIGINTEGER_VARIABLE])) === false ) {\r
-            $key = count($cache[MATH_BIGINTEGER_VARIABLE]);\r
-            $cache[MATH_BIGINTEGER_VARIABLE][] = $m;\r
-\r
-            $lhs = new Math_BigInteger();\r
-            $lhs_value = &$lhs->value;\r
-            $lhs_value = $this->_array_repeat(0, $m_length + ($m_length >> 1));\r
-            $lhs_value[] = 1;\r
-            $rhs = new Math_BigInteger();\r
-            $rhs->value = $m;\r
-\r
-            list($u, $m1) = $lhs->divide($rhs);\r
-            $u = $u->value;\r
-            $m1 = $m1->value;\r
-\r
-            $cache[MATH_BIGINTEGER_DATA][] = array(\r
-                'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1)\r
-                'm1'=> $m1 // m.length\r
-            );\r
-        } else {\r
-            extract($cache[MATH_BIGINTEGER_DATA][$key]);\r
-        }\r
-\r
-        $cutoff = $m_length + ($m_length >> 1);\r
-        $lsd = array_slice($n, 0, $cutoff); // m.length + (m.length >> 1)\r
-        $msd = array_slice($n, $cutoff);    // m.length >> 1\r
-        $lsd = $this->_trim($lsd);\r
-        $temp = $this->_multiply($msd, false, $m1, false);\r
-        $n = $this->_add($lsd, false, $temp[MATH_BIGINTEGER_VALUE], false); // m.length + (m.length >> 1) + 1\r
-\r
-        if ($m_length & 1) {\r
-            return $this->_regularBarrett($n[MATH_BIGINTEGER_VALUE], $m);\r
-        }\r
-\r
-        // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2\r
-        $temp = array_slice($n[MATH_BIGINTEGER_VALUE], $m_length - 1);\r
-        // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2\r
-        // if odd:  ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1\r
-        $temp = $this->_multiply($temp, false, $u, false);\r
-        // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1\r
-        // if odd:  (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1)\r
-        $temp = array_slice($temp[MATH_BIGINTEGER_VALUE], ($m_length >> 1) + 1);\r
-        // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1\r
-        // if odd:  (m.length - (m.length >> 1)) + m.length     = 2 * m.length - (m.length >> 1)\r
-        $temp = $this->_multiply($temp, false, $m, false);\r
-\r
-        // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit\r
-        // number from a m.length + (m.length >> 1) + 1 digit number.  ie. there'd be an extra digit and the while loop\r
-        // following this comment would loop a lot (hence our calling _regularBarrett() in that situation).\r
-\r
-        $result = $this->_subtract($n[MATH_BIGINTEGER_VALUE], false, $temp[MATH_BIGINTEGER_VALUE], false);\r
-\r
-        while ($this->_compare($result[MATH_BIGINTEGER_VALUE], $result[MATH_BIGINTEGER_SIGN], $m, false) >= 0) {\r
-            $result = $this->_subtract($result[MATH_BIGINTEGER_VALUE], $result[MATH_BIGINTEGER_SIGN], $m, false);\r
-        }\r
-\r
-        return $result[MATH_BIGINTEGER_VALUE];\r
-    }\r
-\r
-    /**\r
-     * (Regular) Barrett Modular Reduction\r
-     *\r
-     * For numbers with more than four digits Math_BigInteger::_barrett() is faster.  The difference between that and this\r
-     * is that this function does not fold the denominator into a smaller form.\r
-     *\r
-     * @see _slidingWindow()\r
-     * @access private\r
-     * @param Array $x\r
-     * @param Array $n\r
-     * @return Array\r
-     */\r
-    function _regularBarrett($x, $n)\r
-    {\r
-        static $cache = array(\r
-            MATH_BIGINTEGER_VARIABLE => array(),\r
-            MATH_BIGINTEGER_DATA => array()\r
-        );\r
-\r
-        $n_length = count($n);\r
-\r
-        if (count($x) > 2 * $n_length) {\r
-            $lhs = new Math_BigInteger();\r
-            $rhs = new Math_BigInteger();\r
-            $lhs->value = $x;\r
-            $rhs->value = $n;\r
-            list(, $temp) = $lhs->divide($rhs);\r
-            return $temp->value;\r
-        }\r
-\r
-        if ( ($key = array_search($n, $cache[MATH_BIGINTEGER_VARIABLE])) === false ) {\r
-            $key = count($cache[MATH_BIGINTEGER_VARIABLE]);\r
-            $cache[MATH_BIGINTEGER_VARIABLE][] = $n;\r
-            $lhs = new Math_BigInteger();\r
-            $lhs_value = &$lhs->value;\r
-            $lhs_value = $this->_array_repeat(0, 2 * $n_length);\r
-            $lhs_value[] = 1;\r
-            $rhs = new Math_BigInteger();\r
-            $rhs->value = $n;\r
-            list($temp, ) = $lhs->divide($rhs); // m.length\r
-            $cache[MATH_BIGINTEGER_DATA][] = $temp->value;\r
-        }\r
-\r
-        // 2 * m.length - (m.length - 1) = m.length + 1\r
-        $temp = array_slice($x, $n_length - 1);\r
-        // (m.length + 1) + m.length = 2 * m.length + 1\r
-        $temp = $this->_multiply($temp, false, $cache[MATH_BIGINTEGER_DATA][$key], false);\r
-        // (2 * m.length + 1) - (m.length - 1) = m.length + 2\r
-        $temp = array_slice($temp[MATH_BIGINTEGER_VALUE], $n_length + 1);\r
-\r
-        // m.length + 1\r
-        $result = array_slice($x, 0, $n_length + 1);\r
-        // m.length + 1\r
-        $temp = $this->_multiplyLower($temp, false, $n, false, $n_length + 1);\r
-        // $temp == array_slice($temp->_multiply($temp, false, $n, false)->value, 0, $n_length + 1)\r
-\r
-        if ($this->_compare($result, false, $temp[MATH_BIGINTEGER_VALUE], $temp[MATH_BIGINTEGER_SIGN]) < 0) {\r
-            $corrector_value = $this->_array_repeat(0, $n_length + 1);\r
-            $corrector_value[] = 1;\r
-            $result = $this->_add($result, false, $corrector, false);\r
-            $result = $result[MATH_BIGINTEGER_VALUE];\r
-        }\r
-\r
-        // at this point, we're subtracting a number with m.length + 1 digits from another number with m.length + 1 digits\r
-        $result = $this->_subtract($result, false, $temp[MATH_BIGINTEGER_VALUE], $temp[MATH_BIGINTEGER_SIGN]);\r
-        while ($this->_compare($result[MATH_BIGINTEGER_VALUE], $result[MATH_BIGINTEGER_SIGN], $n, false) > 0) {\r
-            $result = $this->_subtract($result[MATH_BIGINTEGER_VALUE], $result[MATH_BIGINTEGER_SIGN], $n, false);\r
-        }\r
-\r
-        return $result[MATH_BIGINTEGER_VALUE];\r
-    }\r
-\r
-    /**\r
-     * Performs long multiplication up to $stop digits\r
-     *\r
-     * If you're going to be doing array_slice($product->value, 0, $stop), some cycles can be saved.\r
-     *\r
-     * @see _regularBarrett()\r
-     * @param Array $x_value\r
-     * @param Boolean $x_negative\r
-     * @param Array $y_value\r
-     * @param Boolean $y_negative\r
-     * @return Array\r
-     * @access private\r
-     */\r
-    function _multiplyLower($x_value, $x_negative, $y_value, $y_negative, $stop)\r
-    {\r
-        $x_length = count($x_value);\r
-        $y_length = count($y_value);\r
-\r
-        if ( !$x_length || !$y_length ) { // a 0 is being multiplied\r
-            return array(\r
-                MATH_BIGINTEGER_VALUE => array(),\r
-                MATH_BIGINTEGER_SIGN => false\r
-            );\r
-        }\r
-\r
-        if ( $x_length < $y_length ) {\r
-            $temp = $x_value;\r
-            $x_value = $y_value;\r
-            $y_value = $temp;\r
-\r
-            $x_length = count($x_value);\r
-            $y_length = count($y_value);\r
-        }\r
-\r
-        $product_value = $this->_array_repeat(0, $x_length + $y_length);\r
-\r
-        // the following for loop could be removed if the for loop following it\r
-        // (the one with nested for loops) initially set $i to 0, but\r
-        // doing so would also make the result in one set of unnecessary adds,\r
-        // since on the outermost loops first pass, $product->value[$k] is going\r
-        // to always be 0\r
-\r
-        $carry = 0;\r
-\r
-        for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0, $k = $i\r
-            $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0\r
-            $carry = (int) ($temp / 0x4000000);\r
-            $product_value[$j] = (int) ($temp - 0x4000000 * $carry);\r
-        }\r
-\r
-        if ($j < $stop) {\r
-            $product_value[$j] = $carry;\r
-        }\r
-\r
-        // the above for loop is what the previous comment was talking about.  the\r
-        // following for loop is the "one with nested for loops"\r
-\r
-        for ($i = 1; $i < $y_length; ++$i) {\r
-            $carry = 0;\r
-\r
-            for ($j = 0, $k = $i; $j < $x_length && $k < $stop; ++$j, ++$k) {\r
-                $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry;\r
-                $carry = (int) ($temp / 0x4000000);\r
-                $product_value[$k] = (int) ($temp - 0x4000000 * $carry);\r
-            }\r
-\r
-            if ($k < $stop) {\r
-                $product_value[$k] = $carry;\r
-            }\r
-        }\r
-\r
-        return array(\r
-            MATH_BIGINTEGER_VALUE => $this->_trim($product_value),\r
-            MATH_BIGINTEGER_SIGN => $x_negative != $y_negative\r
-        );\r
-    }\r
-\r
-    /**\r
-     * Montgomery Modular Reduction\r
-     *\r
-     * ($x->_prepMontgomery($n))->_montgomery($n) yields $x % $n.\r
-     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=170 MPM 6.3} provides insights on how this can be\r
-     * improved upon (basically, by using the comba method).  gcd($n, 2) must be equal to one for this function\r
-     * to work correctly.\r
-     *\r
-     * @see _prepMontgomery()\r
-     * @see _slidingWindow()\r
-     * @access private\r
-     * @param Array $x\r
-     * @param Array $n\r
-     * @return Array\r
-     */\r
-    function _montgomery($x, $n)\r
-    {\r
-        static $cache = array(\r
-            MATH_BIGINTEGER_VARIABLE => array(),\r
-            MATH_BIGINTEGER_DATA => array()\r
-        );\r
-\r
-        if ( ($key = array_search($n, $cache[MATH_BIGINTEGER_VARIABLE])) === false ) {\r
-            $key = count($cache[MATH_BIGINTEGER_VARIABLE]);\r
-            $cache[MATH_BIGINTEGER_VARIABLE][] = $x;\r
-            $cache[MATH_BIGINTEGER_DATA][] = $this->_modInverse67108864($n);\r
-        }\r
-\r
-        $k = count($n);\r
-\r
-        $result = array(MATH_BIGINTEGER_VALUE => $x);\r
-\r
-        for ($i = 0; $i < $k; ++$i) {\r
-            $temp = $result[MATH_BIGINTEGER_VALUE][$i] * $cache[MATH_BIGINTEGER_DATA][$key];\r
-            $temp = (int) ($temp - 0x4000000 * ((int) ($temp / 0x4000000)));\r
-            $temp = $this->_regularMultiply(array($temp), $n);\r
-            $temp = array_merge($this->_array_repeat(0, $i), $temp);\r
-            $result = $this->_add($result[MATH_BIGINTEGER_VALUE], false, $temp, false);\r
-        }\r
-\r
-        $result[MATH_BIGINTEGER_VALUE] = array_slice($result[MATH_BIGINTEGER_VALUE], $k);\r
-\r
-        if ($this->_compare($result, false, $n, false) >= 0) {\r
-            $result = $this->_subtract($result[MATH_BIGINTEGER_VALUE], false, $n, false);\r
-        }\r
-\r
-        return $result[MATH_BIGINTEGER_VALUE];\r
-    }\r
-\r
-    /**\r
-     * Montgomery Multiply\r
-     *\r
-     * Interleaves the montgomery reduction and long multiplication algorithms together as described in \r
-     * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36}\r
-     *\r
-     * @see _prepMontgomery()\r
-     * @see _montgomery()\r
-     * @access private\r
-     * @param Array $x\r
-     * @param Array $y\r
-     * @param Array $m\r
-     * @return Array\r
-     */\r
-    function _montgomeryMultiply($x, $y, $m)\r
-    {\r
-        $temp = $this->_multiply($x, false, $y, false);\r
-        return $this->_montgomery($temp[MATH_BIGINTEGER_VALUE], $m);\r
-\r
-        static $cache = array(\r
-            MATH_BIGINTEGER_VARIABLE => array(),\r
-            MATH_BIGINTEGER_DATA => array()\r
-        );\r
-\r
-        if ( ($key = array_search($m, $cache[MATH_BIGINTEGER_VARIABLE])) === false ) {\r
-            $key = count($cache[MATH_BIGINTEGER_VARIABLE]);\r
-            $cache[MATH_BIGINTEGER_VARIABLE][] = $m;\r
-            $cache[MATH_BIGINTEGER_DATA][] = $this->_modInverse67108864($m);\r
-        }\r
-\r
-        $n = max(count($x), count($y), count($m));\r
-        $x = array_pad($x, $n, 0);\r
-        $y = array_pad($y, $n, 0);\r
-        $m = array_pad($m, $n, 0);\r
-        $a = array(MATH_BIGINTEGER_VALUE => $this->_array_repeat(0, $n + 1));\r
-        for ($i = 0; $i < $n; ++$i) {\r
-            $temp = $a[MATH_BIGINTEGER_VALUE][0] + $x[$i] * $y[0];\r
-            $temp = (int) ($temp - 0x4000000 * ((int) ($temp / 0x4000000)));\r
-            $temp = $temp * $cache[MATH_BIGINTEGER_DATA][$key];\r
-            $temp = (int) ($temp - 0x4000000 * ((int) ($temp / 0x4000000)));\r
-            $temp = $this->_add($this->_regularMultiply(array($x[$i]), $y), false, $this->_regularMultiply(array($temp), $m), false);\r
-            $a = $this->_add($a[MATH_BIGINTEGER_VALUE], false, $temp[MATH_BIGINTEGER_VALUE], false);\r
-            $a[MATH_BIGINTEGER_VALUE] = array_slice($a[MATH_BIGINTEGER_VALUE], 1);\r
-        }\r
-        if ($this->_compare($a[MATH_BIGINTEGER_VALUE], false, $m, false) >= 0) {\r
-            $a = $this->_subtract($a[MATH_BIGINTEGER_VALUE], false, $m, false);\r
-        }\r
-        return $a[MATH_BIGINTEGER_VALUE];\r
-    }\r
-\r
-    /**\r
-     * Prepare a number for use in Montgomery Modular Reductions\r
-     *\r
-     * @see _montgomery()\r
-     * @see _slidingWindow()\r
-     * @access private\r
-     * @param Array $x\r
-     * @param Array $n\r
-     * @return Array\r
-     */\r
-    function _prepMontgomery($x, $n)\r
-    {\r
-        $lhs = new Math_BigInteger();\r
-        $lhs->value = array_merge($this->_array_repeat(0, count($n)), $x);\r
-        $rhs = new Math_BigInteger();\r
-        $rhs->value = $n;\r
-\r
-        list(, $temp) = $lhs->divide($rhs);\r
-        return $temp->value;\r
-    }\r
-\r
-    /**\r
-     * Modular Inverse of a number mod 2**26 (eg. 67108864)\r
-     *\r
-     * Based off of the bnpInvDigit function implemented and justified in the following URL:\r
-     *\r
-     * {@link http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js}\r
-     *\r
-     * The following URL provides more info:\r
-     *\r
-     * {@link http://groups.google.com/group/sci.crypt/msg/7a137205c1be7d85}\r
-     *\r
-     * As for why we do all the bitmasking...  strange things can happen when converting from floats to ints. For\r
-     * instance, on some computers, var_dump((int) -4294967297) yields int(-1) and on others, it yields \r
-     * int(-2147483648).  To avoid problems stemming from this, we use bitmasks to guarantee that ints aren't\r
-     * auto-converted to floats.  The outermost bitmask is present because without it, there's no guarantee that\r
-     * the "residue" returned would be the so-called "common residue".  We use fmod, in the last step, because the\r
-     * maximum possible $x is 26 bits and the maximum $result is 16 bits.  Thus, we have to be able to handle up to\r
-     * 40 bits, which only 64-bit floating points will support.\r
-     *\r
-     * Thanks to Pedro Gimeno Fortea for input!\r
-     *\r
-     * @see _montgomery()\r
-     * @access private\r
-     * @param Array $x\r
-     * @return Integer\r
-     */\r
-    function _modInverse67108864($x) // 2**26 == 67108864\r
-    {\r
-        $x = -$x[0];\r
-        $result = $x & 0x3; // x**-1 mod 2**2\r
-        $result = ($result * (2 - $x * $result)) & 0xF; // x**-1 mod 2**4\r
-        $result = ($result * (2 - ($x & 0xFF) * $result))  & 0xFF; // x**-1 mod 2**8\r
-        $result = ($result * ((2 - ($x & 0xFFFF) * $result) & 0xFFFF)) & 0xFFFF; // x**-1 mod 2**16\r
-        $result = fmod($result * (2 - fmod($x * $result, 0x4000000)), 0x4000000); // x**-1 mod 2**26\r
-        return $result & 0x3FFFFFF;\r
-    }\r
-\r
-    /**\r
-     * Calculates modular inverses.\r
-     *\r
-     * Say you have (30 mod 17 * x mod 17) mod 17 == 1.  x can be found using modular inverses.\r
-     *\r
-     * Here's an example:\r
-     * <code>\r
-     * <?php\r
-     *    include('Math/BigInteger.php');\r
-     *\r
-     *    $a = new Math_BigInteger(30);\r
-     *    $b = new Math_BigInteger(17);\r
-     *\r
-     *    $c = $a->modInverse($b);\r
-     *    echo $c->toString(); // outputs 4\r
-     *\r
-     *    echo "\r\n";\r
-     *\r
-     *    $d = $a->multiply($c);\r
-     *    list(, $d) = $d->divide($b);\r
-     *    echo $d; // outputs 1 (as per the definition of modular inverse)\r
-     * ?>\r
-     * </code>\r
-     *\r
-     * @param Math_BigInteger $n\r
-     * @return mixed false, if no modular inverse exists, Math_BigInteger, otherwise.\r
-     * @access public\r
-     * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=21 HAC 14.64} for more information.\r
-     */\r
-    function modInverse($n)\r
-    {\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                $temp = new Math_BigInteger();\r
-                $temp->value = gmp_invert($this->value, $n->value);\r
-\r
-                return ( $temp->value === false ) ? false : $this->_normalize($temp);\r
-        }\r
-\r
-        static $zero, $one;\r
-        if (!isset($zero)) {\r
-            $zero = new Math_BigInteger();\r
-            $one = new Math_BigInteger(1);\r
-        }\r
-\r
-        // $x mod $n == $x mod -$n.\r
-        $n = $n->abs();\r
-\r
-        if ($this->compare($zero) < 0) {\r
-            $temp = $this->abs();\r
-            $temp = $temp->modInverse($n);\r
-            return $negated === false ? false : $this->_normalize($n->subtract($temp));\r
-        }\r
-\r
-        extract($this->extendedGCD($n));\r
-\r
-        if (!$gcd->equals($one)) {\r
-            return false;\r
-        }\r
-\r
-        $x = $x->compare($zero) < 0 ? $x->add($n) : $x;\r
-\r
-        return $this->compare($zero) < 0 ? $this->_normalize($n->subtract($x)) : $this->_normalize($x);\r
-    }\r
-\r
-    /**\r
-     * Calculates the greatest common divisor and Bézout's identity.\r
-     *\r
-     * Say you have 693 and 609.  The GCD is 21.  Bézout's identity states that there exist integers x and y such that\r
-     * 693*x + 609*y == 21.  In point of fact, there are actually an infinite number of x and y combinations and which\r
-     * combination is returned is dependant upon which mode is in use.  See\r
-     * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bézout's identity - Wikipedia} for more information.\r
-     *\r
-     * Here's an example:\r
-     * <code>\r
-     * <?php\r
-     *    include('Math/BigInteger.php');\r
-     *\r
-     *    $a = new Math_BigInteger(693);\r
-     *    $b = new Math_BigInteger(609);\r
-     *\r
-     *    extract($a->extendedGCD($b));\r
-     *\r
-     *    echo $gcd->toString() . "\r\n"; // outputs 21\r
-     *    echo $a->toString() * $x->toString() + $b->toString() * $y->toString(); // outputs 21\r
-     * ?>\r
-     * </code>\r
-     *\r
-     * @param Math_BigInteger $n\r
-     * @return Math_BigInteger\r
-     * @access public\r
-     * @internal Calculates the GCD using the binary xGCD algorithim described in\r
-     *    {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=19 HAC 14.61}.  As the text above 14.61 notes,\r
-     *    the more traditional algorithim requires "relatively costly multiple-precision divisions".\r
-     */\r
-    function extendedGCD($n)\r
-    {\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                extract(gmp_gcdext($this->value, $n->value));\r
-\r
-                return array(\r
-                    'gcd' => $this->_normalize(new Math_BigInteger($g)),\r
-                    'x'   => $this->_normalize(new Math_BigInteger($s)),\r
-                    'y'   => $this->_normalize(new Math_BigInteger($t))\r
-                );\r
-            case MATH_BIGINTEGER_MODE_BCMATH:\r
-                // it might be faster to use the binary xGCD algorithim here, as well, but (1) that algorithim works\r
-                // best when the base is a power of 2 and (2) i don't think it'd make much difference, anyway.  as is,\r
-                // the basic extended euclidean algorithim is what we're using.\r
-\r
-                $u = $this->value;\r
-                $v = $n->value;\r
-\r
-                $a = '1';\r
-                $b = '0';\r
-                $c = '0';\r
-                $d = '1';\r
-\r
-                while (bccomp($v, '0', 0) != 0) {\r
-                    $q = bcdiv($u, $v, 0);\r
-\r
-                    $temp = $u;\r
-                    $u = $v;\r
-                    $v = bcsub($temp, bcmul($v, $q, 0), 0);\r
-\r
-                    $temp = $a;\r
-                    $a = $c;\r
-                    $c = bcsub($temp, bcmul($a, $q, 0), 0);\r
-\r
-                    $temp = $b;\r
-                    $b = $d;\r
-                    $d = bcsub($temp, bcmul($b, $q, 0), 0);\r
-                }\r
-\r
-                return array(\r
-                    'gcd' => $this->_normalize(new Math_BigInteger($u)),\r
-                    'x'   => $this->_normalize(new Math_BigInteger($a)),\r
-                    'y'   => $this->_normalize(new Math_BigInteger($b))\r
-                );\r
-        }\r
-\r
-        $y = $n->copy();\r
-        $x = $this->copy();\r
-        $g = new Math_BigInteger();\r
-        $g->value = array(1);\r
-\r
-        while ( !(($x->value[0] & 1)|| ($y->value[0] & 1)) ) {\r
-            $x->_rshift(1);\r
-            $y->_rshift(1);\r
-            $g->_lshift(1);\r
-        }\r
-\r
-        $u = $x->copy();\r
-        $v = $y->copy();\r
-\r
-        $a = new Math_BigInteger();\r
-        $b = new Math_BigInteger();\r
-        $c = new Math_BigInteger();\r
-        $d = new Math_BigInteger();\r
-\r
-        $a->value = $d->value = $g->value = array(1);\r
-        $b->value = $c->value = array();\r
-\r
-        while ( !empty($u->value) ) {\r
-            while ( !($u->value[0] & 1) ) {\r
-                $u->_rshift(1);\r
-                if ( (!empty($a->value) && ($a->value[0] & 1)) || (!empty($b->value) && ($b->value[0] & 1)) ) {\r
-                    $a = $a->add($y);\r
-                    $b = $b->subtract($x);\r
-                }\r
-                $a->_rshift(1);\r
-                $b->_rshift(1);\r
-            }\r
-\r
-            while ( !($v->value[0] & 1) ) {\r
-                $v->_rshift(1);\r
-                if ( (!empty($d->value) && ($d->value[0] & 1)) || (!empty($c->value) && ($c->value[0] & 1)) ) {\r
-                    $c = $c->add($y);\r
-                    $d = $d->subtract($x);\r
-                }\r
-                $c->_rshift(1);\r
-                $d->_rshift(1);\r
-            }\r
-\r
-            if ($u->compare($v) >= 0) {\r
-                $u = $u->subtract($v);\r
-                $a = $a->subtract($c);\r
-                $b = $b->subtract($d);\r
-            } else {\r
-                $v = $v->subtract($u);\r
-                $c = $c->subtract($a);\r
-                $d = $d->subtract($b);\r
-            }\r
-        }\r
-\r
-        return array(\r
-            'gcd' => $this->_normalize($g->multiply($v)),\r
-            'x'   => $this->_normalize($c),\r
-            'y'   => $this->_normalize($d)\r
-        );\r
-    }\r
-\r
-    /**\r
-     * Calculates the greatest common divisor\r
-     *\r
-     * Say you have 693 and 609.  The GCD is 21.\r
-     *\r
-     * Here's an example:\r
-     * <code>\r
-     * <?php\r
-     *    include('Math/BigInteger.php');\r
-     *\r
-     *    $a = new Math_BigInteger(693);\r
-     *    $b = new Math_BigInteger(609);\r
-     *\r
-     *    $gcd = a->extendedGCD($b);\r
-     *\r
-     *    echo $gcd->toString() . "\r\n"; // outputs 21\r
-     * ?>\r
-     * </code>\r
-     *\r
-     * @param Math_BigInteger $n\r
-     * @return Math_BigInteger\r
-     * @access public\r
-     */\r
-    function gcd($n)\r
-    {\r
-        extract($this->extendedGCD($n));\r
-        return $gcd;\r
-    }\r
-\r
-    /**\r
-     * Absolute value.\r
-     *\r
-     * @return Math_BigInteger\r
-     * @access public\r
-     */\r
-    function abs()\r
-    {\r
-        $temp = new Math_BigInteger();\r
-\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                $temp->value = gmp_abs($this->value);\r
-                break;\r
-            case MATH_BIGINTEGER_MODE_BCMATH:\r
-                $temp->value = (bccomp($this->value, '0', 0) < 0) ? substr($this->value, 1) : $this->value;\r
-                break;\r
-            default:\r
-                $temp->value = $this->value;\r
-        }\r
-\r
-        return $temp;\r
-    }\r
-\r
-    /**\r
-     * Compares two numbers.\r
-     *\r
-     * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite.  The reason for this is\r
-     * demonstrated thusly:\r
-     *\r
-     * $x  > $y: $x->compare($y)  > 0\r
-     * $x  < $y: $x->compare($y)  < 0\r
-     * $x == $y: $x->compare($y) == 0\r
-     *\r
-     * Note how the same comparison operator is used.  If you want to test for equality, use $x->equals($y).\r
-     *\r
-     * @param Math_BigInteger $x\r
-     * @return Integer < 0 if $this is less than $x; > 0 if $this is greater than $x, and 0 if they are equal.\r
-     * @access public\r
-     * @see equals()\r
-     * @internal Could return $this->subtract($x), but that's not as fast as what we do do.\r
-     */\r
-    function compare($y)\r
-    {\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                return gmp_cmp($this->value, $y->value);\r
-            case MATH_BIGINTEGER_MODE_BCMATH:\r
-                return bccomp($this->value, $y->value, 0);\r
-        }\r
-\r
-        return $this->_compare($this->value, $this->is_negative, $y->value, $y->is_negative);\r
-    }\r
-\r
-    /**\r
-     * Compares two numbers.\r
-     *\r
-     * @param Array $x_value\r
-     * @param Boolean $x_negative\r
-     * @param Array $y_value\r
-     * @param Boolean $y_negative\r
-     * @return Integer\r
-     * @see compare()\r
-     * @access private\r
-     */\r
-    function _compare($x_value, $x_negative, $y_value, $y_negative)\r
-    {\r
-        if ( $x_negative != $y_negative ) {\r
-            return ( !$x_negative && $y_negative ) ? 1 : -1;\r
-        }\r
-\r
-        $result = $x_negative ? -1 : 1;\r
-\r
-        if ( count($x_value) != count($y_value) ) {\r
-            return ( count($x_value) > count($y_value) ) ? $result : -$result;\r
-        }\r
-        $size = max(count($x_value), count($y_value));\r
-\r
-        $x_value = array_pad($x_value, $size, 0);\r
-        $y_value = array_pad($y_value, $size, 0);\r
-\r
-        for ($i = count($x_value) - 1; $i >= 0; --$i) {\r
-            if ($x_value[$i] != $y_value[$i]) {\r
-                return ( $x_value[$i] > $y_value[$i] ) ? $result : -$result;\r
-            }\r
-        }\r
-\r
-        return 0;\r
-    }\r
-\r
-    /**\r
-     * Tests the equality of two numbers.\r
-     *\r
-     * If you need to see if one number is greater than or less than another number, use Math_BigInteger::compare()\r
-     *\r
-     * @param Math_BigInteger $x\r
-     * @return Boolean\r
-     * @access public\r
-     * @see compare()\r
-     */\r
-    function equals($x)\r
-    {\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                return gmp_cmp($this->value, $x->value) == 0;\r
-            default:\r
-                return $this->value === $x->value && $this->is_negative == $x->is_negative;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Set Precision\r
-     *\r
-     * Some bitwise operations give different results depending on the precision being used.  Examples include left\r
-     * shift, not, and rotates.\r
-     *\r
-     * @param Math_BigInteger $x\r
-     * @access public\r
-     * @return Math_BigInteger\r
-     */\r
-    function setPrecision($bits)\r
-    {\r
-        $this->precision = $bits;\r
-        if ( MATH_BIGINTEGER_MODE != MATH_BIGINTEGER_MODE_BCMATH ) {\r
-            $this->bitmask = new Math_BigInteger(chr((1 << ($bits & 0x7)) - 1) . str_repeat(chr(0xFF), $bits >> 3), 256);\r
-        } else {\r
-            $this->bitmask = new Math_BigInteger(bcpow('2', $bits, 0));\r
-        }\r
-\r
-        $temp = $this->_normalize($this);\r
-        $this->value = $temp->value;\r
-    }\r
-\r
-    /**\r
-     * Logical And\r
-     *\r
-     * @param Math_BigInteger $x\r
-     * @access public\r
-     * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>\r
-     * @return Math_BigInteger\r
-     */\r
-    function bitwise_and($x)\r
-    {\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                $temp = new Math_BigInteger();\r
-                $temp->value = gmp_and($this->value, $x->value);\r
-\r
-                return $this->_normalize($temp);\r
-            case MATH_BIGINTEGER_MODE_BCMATH:\r
-                $left = $this->toBytes();\r
-                $right = $x->toBytes();\r
-\r
-                $length = max(strlen($left), strlen($right));\r
-\r
-                $left = str_pad($left, $length, chr(0), STR_PAD_LEFT);\r
-                $right = str_pad($right, $length, chr(0), STR_PAD_LEFT);\r
-\r
-                return $this->_normalize(new Math_BigInteger($left & $right, 256));\r
-        }\r
-\r
-        $result = $this->copy();\r
-\r
-        $length = min(count($x->value), count($this->value));\r
-\r
-        $result->value = array_slice($result->value, 0, $length);\r
-\r
-        for ($i = 0; $i < $length; ++$i) {\r
-            $result->value[$i] = $result->value[$i] & $x->value[$i];\r
-        }\r
-\r
-        return $this->_normalize($result);\r
-    }\r
-\r
-    /**\r
-     * Logical Or\r
-     *\r
-     * @param Math_BigInteger $x\r
-     * @access public\r
-     * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>\r
-     * @return Math_BigInteger\r
-     */\r
-    function bitwise_or($x)\r
-    {\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                $temp = new Math_BigInteger();\r
-                $temp->value = gmp_or($this->value, $x->value);\r
-\r
-                return $this->_normalize($temp);\r
-            case MATH_BIGINTEGER_MODE_BCMATH:\r
-                $left = $this->toBytes();\r
-                $right = $x->toBytes();\r
-\r
-                $length = max(strlen($left), strlen($right));\r
-\r
-                $left = str_pad($left, $length, chr(0), STR_PAD_LEFT);\r
-                $right = str_pad($right, $length, chr(0), STR_PAD_LEFT);\r
-\r
-                return $this->_normalize(new Math_BigInteger($left | $right, 256));\r
-        }\r
-\r
-        $length = max(count($this->value), count($x->value));\r
-        $result = $this->copy();\r
-        $result->value = array_pad($result->value, 0, $length);\r
-        $x->value = array_pad($x->value, 0, $length);\r
-\r
-        for ($i = 0; $i < $length; ++$i) {\r
-            $result->value[$i] = $this->value[$i] | $x->value[$i];\r
-        }\r
-\r
-        return $this->_normalize($result);\r
-    }\r
-\r
-    /**\r
-     * Logical Exclusive-Or\r
-     *\r
-     * @param Math_BigInteger $x\r
-     * @access public\r
-     * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>\r
-     * @return Math_BigInteger\r
-     */\r
-    function bitwise_xor($x)\r
-    {\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                $temp = new Math_BigInteger();\r
-                $temp->value = gmp_xor($this->value, $x->value);\r
-\r
-                return $this->_normalize($temp);\r
-            case MATH_BIGINTEGER_MODE_BCMATH:\r
-                $left = $this->toBytes();\r
-                $right = $x->toBytes();\r
-\r
-                $length = max(strlen($left), strlen($right));\r
-\r
-                $left = str_pad($left, $length, chr(0), STR_PAD_LEFT);\r
-                $right = str_pad($right, $length, chr(0), STR_PAD_LEFT);\r
-\r
-                return $this->_normalize(new Math_BigInteger($left ^ $right, 256));\r
-        }\r
-\r
-        $length = max(count($this->value), count($x->value));\r
-        $result = $this->copy();\r
-        $result->value = array_pad($result->value, 0, $length);\r
-        $x->value = array_pad($x->value, 0, $length);\r
-\r
-        for ($i = 0; $i < $length; ++$i) {\r
-            $result->value[$i] = $this->value[$i] ^ $x->value[$i];\r
-        }\r
-\r
-        return $this->_normalize($result);\r
-    }\r
-\r
-    /**\r
-     * Logical Not\r
-     *\r
-     * @access public\r
-     * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>\r
-     * @return Math_BigInteger\r
-     */\r
-    function bitwise_not()\r
-    {\r
-        // calculuate "not" without regard to $this->precision\r
-        // (will always result in a smaller number.  ie. ~1 isn't 1111 1110 - it's 0)\r
-        $temp = $this->toBytes();\r
-        $pre_msb = decbin(ord($temp[0]));\r
-        $temp = ~$temp;\r
-        $msb = decbin(ord($temp[0]));\r
-        if (strlen($msb) == 8) {\r
-            $msb = substr($msb, strpos($msb, '0'));\r
-        }\r
-        $temp[0] = chr(bindec($msb));\r
-\r
-        // see if we need to add extra leading 1's\r
-        $current_bits = strlen($pre_msb) + 8 * strlen($temp) - 8;\r
-        $new_bits = $this->precision - $current_bits;\r
-        if ($new_bits <= 0) {\r
-            return $this->_normalize(new Math_BigInteger($temp, 256));\r
-        }\r
-\r
-        // generate as many leading 1's as we need to.\r
-        $leading_ones = chr((1 << ($new_bits & 0x7)) - 1) . str_repeat(chr(0xFF), $new_bits >> 3);\r
-        $this->_base256_lshift($leading_ones, $current_bits);\r
-\r
-        $temp = str_pad($temp, ceil($this->bits / 8), chr(0), STR_PAD_LEFT);\r
-\r
-        return $this->_normalize(new Math_BigInteger($leading_ones | $temp, 256));\r
-    }\r
-\r
-    /**\r
-     * Logical Right Shift\r
-     *\r
-     * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift.\r
-     *\r
-     * @param Integer $shift\r
-     * @return Math_BigInteger\r
-     * @access public\r
-     * @internal The only version that yields any speed increases is the internal version.\r
-     */\r
-    function bitwise_rightShift($shift)\r
-    {\r
-        $temp = new Math_BigInteger();\r
-\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                static $two;\r
-\r
-                if (!isset($two)) {\r
-                    $two = gmp_init('2');\r
-                }\r
-\r
-                $temp->value = gmp_div_q($this->value, gmp_pow($two, $shift));\r
-\r
-                break;\r
-            case MATH_BIGINTEGER_MODE_BCMATH:\r
-                $temp->value = bcdiv($this->value, bcpow('2', $shift, 0), 0);\r
-\r
-                break;\r
-            default: // could just replace _lshift with this, but then all _lshift() calls would need to be rewritten\r
-                     // and I don't want to do that...\r
-                $temp->value = $this->value;\r
-                $temp->_rshift($shift);\r
-        }\r
-\r
-        return $this->_normalize($temp);\r
-    }\r
-\r
-    /**\r
-     * Logical Left Shift\r
-     *\r
-     * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift.\r
-     *\r
-     * @param Integer $shift\r
-     * @return Math_BigInteger\r
-     * @access public\r
-     * @internal The only version that yields any speed increases is the internal version.\r
-     */\r
-    function bitwise_leftShift($shift)\r
-    {\r
-        $temp = new Math_BigInteger();\r
-\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                static $two;\r
-\r
-                if (!isset($two)) {\r
-                    $two = gmp_init('2');\r
-                }\r
-\r
-                $temp->value = gmp_mul($this->value, gmp_pow($two, $shift));\r
-\r
-                break;\r
-            case MATH_BIGINTEGER_MODE_BCMATH:\r
-                $temp->value = bcmul($this->value, bcpow('2', $shift, 0), 0);\r
-\r
-                break;\r
-            default: // could just replace _rshift with this, but then all _lshift() calls would need to be rewritten\r
-                     // and I don't want to do that...\r
-                $temp->value = $this->value;\r
-                $temp->_lshift($shift);\r
-        }\r
-\r
-        return $this->_normalize($temp);\r
-    }\r
-\r
-    /**\r
-     * Logical Left Rotate\r
-     *\r
-     * Instead of the top x bits being dropped they're appended to the shifted bit string.\r
-     *\r
-     * @param Integer $shift\r
-     * @return Math_BigInteger\r
-     * @access public\r
-     */\r
-    function bitwise_leftRotate($shift)\r
-    {\r
-        $bits = $this->toBytes();\r
-\r
-        if ($this->precision > 0) {\r
-            $precision = $this->precision;\r
-            if ( MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_BCMATH ) {\r
-                $mask = $this->bitmask->subtract(new Math_BigInteger(1));\r
-                $mask = $mask->toBytes();\r
-            } else {\r
-                $mask = $this->bitmask->toBytes();\r
-            }\r
-        } else {\r
-            $temp = ord($bits[0]);\r
-            for ($i = 0; $temp >> $i; ++$i);\r
-            $precision = 8 * strlen($bits) - 8 + $i;\r
-            $mask = chr((1 << ($precision & 0x7)) - 1) . str_repeat(chr(0xFF), $precision >> 3);\r
-        }\r
-\r
-        if ($shift < 0) {\r
-            $shift+= $precision;\r
-        }\r
-        $shift%= $precision;\r
-\r
-        if (!$shift) {\r
-            return $this->copy();\r
-        }\r
-\r
-        $left = $this->bitwise_leftShift($shift);\r
-        $left = $left->bitwise_and(new Math_BigInteger($mask, 256));\r
-        $right = $this->bitwise_rightShift($precision - $shift);\r
-        $result = MATH_BIGINTEGER_MODE != MATH_BIGINTEGER_MODE_BCMATH ? $left->bitwise_or($right) : $left->add($right);\r
-        return $this->_normalize($result);\r
-    }\r
-\r
-    /**\r
-     * Logical Right Rotate\r
-     *\r
-     * Instead of the bottom x bits being dropped they're prepended to the shifted bit string.\r
-     *\r
-     * @param Integer $shift\r
-     * @return Math_BigInteger\r
-     * @access public\r
-     */\r
-    function bitwise_rightRotate($shift)\r
-    {\r
-        return $this->bitwise_leftRotate(-$shift);\r
-    }\r
-\r
-    /**\r
-     * Set random number generator function\r
-     *\r
-     * $generator should be the name of a random generating function whose first parameter is the minimum\r
-     * value and whose second parameter is the maximum value.  If this function needs to be seeded, it should\r
-     * be seeded prior to calling Math_BigInteger::random() or Math_BigInteger::randomPrime()\r
-     *\r
-     * If the random generating function is not explicitly set, it'll be assumed to be mt_rand().\r
-     *\r
-     * @see random()\r
-     * @see randomPrime()\r
-     * @param optional String $generator\r
-     * @access public\r
-     */\r
-    function setRandomGenerator($generator)\r
-    {\r
-        $this->generator = $generator;\r
-    }\r
-\r
-    /**\r
-     * Generate a random number\r
-     *\r
-     * @param optional Integer $min\r
-     * @param optional Integer $max\r
-     * @return Math_BigInteger\r
-     * @access public\r
-     */\r
-    function random($min = false, $max = false)\r
-    {\r
-        if ($min === false) {\r
-            $min = new Math_BigInteger(0);\r
-        }\r
-\r
-        if ($max === false) {\r
-            $max = new Math_BigInteger(0x7FFFFFFF);\r
-        }\r
-\r
-        $compare = $max->compare($min);\r
-\r
-        if (!$compare) {\r
-            return $this->_normalize($min);\r
-        } else if ($compare < 0) {\r
-            // if $min is bigger then $max, swap $min and $max\r
-            $temp = $max;\r
-            $max = $min;\r
-            $min = $temp;\r
-        }\r
-\r
-        $generator = $this->generator;\r
-\r
-        $max = $max->subtract($min);\r
-        $max = ltrim($max->toBytes(), chr(0));\r
-        $size = strlen($max) - 1;\r
-        $random = '';\r
-\r
-        $bytes = $size & 1;\r
-        for ($i = 0; $i < $bytes; ++$i) {\r
-            $random.= chr($generator(0, 255));\r
-        }\r
-\r
-        $blocks = $size >> 1;\r
-        for ($i = 0; $i < $blocks; ++$i) {\r
-            // mt_rand(-2147483648, 0x7FFFFFFF) always produces -2147483648 on some systems\r
-            $random.= pack('n', $generator(0, 0xFFFF));\r
-        }\r
-\r
-        $temp = new Math_BigInteger($random, 256);\r
-        if ($temp->compare(new Math_BigInteger(substr($max, 1), 256)) > 0) {\r
-            $random = chr($generator(0, ord($max[0]) - 1)) . $random;\r
-        } else {\r
-            $random = chr($generator(0, ord($max[0])    )) . $random;\r
-        }\r
-\r
-        $random = new Math_BigInteger($random, 256);\r
-\r
-        return $this->_normalize($random->add($min));\r
-    }\r
-\r
-    /**\r
-     * Generate a random prime number.\r
-     *\r
-     * If there's not a prime within the given range, false will be returned.  If more than $timeout seconds have elapsed,\r
-     * give up and return false.\r
-     *\r
-     * @param optional Integer $min\r
-     * @param optional Integer $max\r
-     * @param optional Integer $timeout\r
-     * @return Math_BigInteger\r
-     * @access public\r
-     * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=15 HAC 4.44}.\r
-     */\r
-    function randomPrime($min = false, $max = false, $timeout = false)\r
-    {\r
-        $compare = $max->compare($min);\r
-\r
-        if (!$compare) {\r
-            return $min;\r
-        } else if ($compare < 0) {\r
-            // if $min is bigger then $max, swap $min and $max\r
-            $temp = $max;\r
-            $max = $min;\r
-            $min = $temp;\r
-        }\r
-\r
-        // gmp_nextprime() requires PHP 5 >= 5.2.0 per <http://php.net/gmp-nextprime>.\r
-        if ( MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_GMP && function_exists('gmp_nextprime') ) {\r
-            // we don't rely on Math_BigInteger::random()'s min / max when gmp_nextprime() is being used since this function\r
-            // does its own checks on $max / $min when gmp_nextprime() is used.  When gmp_nextprime() is not used, however,\r
-            // the same $max / $min checks are not performed.\r
-            if ($min === false) {\r
-                $min = new Math_BigInteger(0);\r
-            }\r
-\r
-            if ($max === false) {\r
-                $max = new Math_BigInteger(0x7FFFFFFF);\r
-            }\r
-\r
-            $x = $this->random($min, $max);\r
-\r
-            $x->value = gmp_nextprime($x->value);\r
-\r
-            if ($x->compare($max) <= 0) {\r
-                return $x;\r
-            }\r
-\r
-            $x->value = gmp_nextprime($min->value);\r
-\r
-            if ($x->compare($max) <= 0) {\r
-                return $x;\r
-            }\r
-\r
-            return false;\r
-        }\r
-\r
-        static $one, $two;\r
-        if (!isset($one)) {\r
-            $one = new Math_BigInteger(1);\r
-            $two = new Math_BigInteger(2);\r
-        }\r
-\r
-        $start = time();\r
-\r
-        $x = $this->random($min, $max);\r
-        if ($x->equals($two)) {\r
-            return $x;\r
-        }\r
-\r
-        $x->_make_odd();\r
-        if ($x->compare($max) > 0) {\r
-            // if $x > $max then $max is even and if $min == $max then no prime number exists between the specified range\r
-            if ($min->equals($max)) {\r
-                return false;\r
-            }\r
-            $x = $min->copy();\r
-            $x->_make_odd();\r
-        }\r
-\r
-        $initial_x = $x->copy();\r
-\r
-        while (true) {\r
-            if ($timeout !== false && time() - $start > $timeout) {\r
-                return false;\r
-            }\r
-\r
-            if ($x->isPrime()) {\r
-                return $x;\r
-            }\r
-\r
-            $x = $x->add($two);\r
-\r
-            if ($x->compare($max) > 0) {\r
-                $x = $min->copy();\r
-                if ($x->equals($two)) {\r
-                    return $x;\r
-                }\r
-                $x->_make_odd();\r
-            }\r
-\r
-            if ($x->equals($initial_x)) {\r
-                return false;\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Make the current number odd\r
-     *\r
-     * If the current number is odd it'll be unchanged.  If it's even, one will be added to it.\r
-     *\r
-     * @see randomPrime()\r
-     * @access private\r
-     */\r
-    function _make_odd()\r
-    {\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                gmp_setbit($this->value, 0);\r
-                break;\r
-            case MATH_BIGINTEGER_MODE_BCMATH:\r
-                if ($this->value[strlen($this->value) - 1] % 2 == 0) {\r
-                    $this->value = bcadd($this->value, '1');\r
-                }\r
-                break;\r
-            default:\r
-                $this->value[0] |= 1;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Checks a numer to see if it's prime\r
-     *\r
-     * Assuming the $t parameter is not set, this function has an error rate of 2**-80.  The main motivation for the\r
-     * $t parameter is distributability.  Math_BigInteger::randomPrime() can be distributed accross multiple pageloads\r
-     * on a website instead of just one.\r
-     *\r
-     * @param optional Integer $t\r
-     * @return Boolean\r
-     * @access public\r
-     * @internal Uses the\r
-     *     {@link http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test Miller-Rabin primality test}.  See \r
-     *     {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=8 HAC 4.24}.\r
-     */\r
-    function isPrime($t = false)\r
-    {\r
-        $length = strlen($this->toBytes());\r
-\r
-        if (!$t) {\r
-            // see HAC 4.49 "Note (controlling the error probability)"\r
-                 if ($length >= 163) { $t =  2; } // floor(1300 / 8)\r
-            else if ($length >= 106) { $t =  3; } // floor( 850 / 8)\r
-            else if ($length >= 81 ) { $t =  4; } // floor( 650 / 8)\r
-            else if ($length >= 68 ) { $t =  5; } // floor( 550 / 8)\r
-            else if ($length >= 56 ) { $t =  6; } // floor( 450 / 8)\r
-            else if ($length >= 50 ) { $t =  7; } // floor( 400 / 8)\r
-            else if ($length >= 43 ) { $t =  8; } // floor( 350 / 8)\r
-            else if ($length >= 37 ) { $t =  9; } // floor( 300 / 8)\r
-            else if ($length >= 31 ) { $t = 12; } // floor( 250 / 8)\r
-            else if ($length >= 25 ) { $t = 15; } // floor( 200 / 8)\r
-            else if ($length >= 18 ) { $t = 18; } // floor( 150 / 8)\r
-            else                     { $t = 27; }\r
-        }\r
-\r
-        // ie. gmp_testbit($this, 0)\r
-        // ie. isEven() or !isOdd()\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                return gmp_prob_prime($this->value, $t) != 0;\r
-            case MATH_BIGINTEGER_MODE_BCMATH:\r
-                if ($this->value === '2') {\r
-                    return true;\r
-                }\r
-                if ($this->value[strlen($this->value) - 1] % 2 == 0) {\r
-                    return false;\r
-                }\r
-                break;\r
-            default:\r
-                if ($this->value == array(2)) {\r
-                    return true;\r
-                }\r
-                if (~$this->value[0] & 1) {\r
-                    return false;\r
-                }\r
-        }\r
-\r
-        static $primes, $zero, $one, $two;\r
-\r
-        if (!isset($primes)) {\r
-            $primes = array(\r
-                3,    5,    7,    11,   13,   17,   19,   23,   29,   31,   37,   41,   43,   47,   53,   59,   \r
-                61,   67,   71,   73,   79,   83,   89,   97,   101,  103,  107,  109,  113,  127,  131,  137,  \r
-                139,  149,  151,  157,  163,  167,  173,  179,  181,  191,  193,  197,  199,  211,  223,  227,  \r
-                229,  233,  239,  241,  251,  257,  263,  269,  271,  277,  281,  283,  293,  307,  311,  313,  \r
-                317,  331,  337,  347,  349,  353,  359,  367,  373,  379,  383,  389,  397,  401,  409,  419,  \r
-                421,  431,  433,  439,  443,  449,  457,  461,  463,  467,  479,  487,  491,  499,  503,  509,  \r
-                521,  523,  541,  547,  557,  563,  569,  571,  577,  587,  593,  599,  601,  607,  613,  617,  \r
-                619,  631,  641,  643,  647,  653,  659,  661,  673,  677,  683,  691,  701,  709,  719,  727,  \r
-                733,  739,  743,  751,  757,  761,  769,  773,  787,  797,  809,  811,  821,  823,  827,  829,  \r
-                839,  853,  857,  859,  863,  877,  881,  883,  887,  907,  911,  919,  929,  937,  941,  947,  \r
-                953,  967,  971,  977,  983,  991,  997\r
-            );\r
-\r
-            if ( MATH_BIGINTEGER_MODE != MATH_BIGINTEGER_MODE_INTERNAL ) {\r
-                for ($i = 0; $i < count($primes); ++$i) {\r
-                    $primes[$i] = new Math_BigInteger($primes[$i]);\r
-                }\r
-            }\r
-\r
-            $zero = new Math_BigInteger();\r
-            $one = new Math_BigInteger(1);\r
-            $two = new Math_BigInteger(2);\r
-        }\r
-\r
-        if ($this->equals($one)) {\r
-            return false;\r
-        }\r
-\r
-        // see HAC 4.4.1 "Random search for probable primes"\r
-        if ( MATH_BIGINTEGER_MODE != MATH_BIGINTEGER_MODE_INTERNAL ) {\r
-            foreach ($primes as $prime) {\r
-                list(, $r) = $this->divide($prime);\r
-                if ($r->equals($zero)) {\r
-                    return $this->equals($prime);\r
-                }\r
-            }\r
-        } else {\r
-            $value = $this->value;\r
-            foreach ($primes as $prime) {\r
-                list(, $r) = $this->_divide_digit($value, $prime);\r
-                if (!$r) {\r
-                    return count($value) == 1 && $value[0] == $prime;\r
-                }\r
-            }\r
-        }\r
-\r
-        $n   = $this->copy();\r
-        $n_1 = $n->subtract($one);\r
-        $n_2 = $n->subtract($two);\r
-\r
-        $r = $n_1->copy();\r
-        $r_value = $r->value;\r
-        // ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s));\r
-        if ( MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_BCMATH ) {\r
-            $s = 0;\r
-            // if $n was 1, $r would be 0 and this would be an infinite loop, hence our $this->equals($one) check earlier\r
-            while ($r->value[strlen($r->value) - 1] % 2 == 0) {\r
-                $r->value = bcdiv($r->value, '2', 0);\r
-                ++$s;\r
-            }\r
-        } else {\r
-            for ($i = 0, $r_length = count($r_value); $i < $r_length; ++$i) {\r
-                $temp = ~$r_value[$i] & 0xFFFFFF;\r
-                for ($j = 1; ($temp >> $j) & 1; ++$j);\r
-                if ($j != 25) {\r
-                    break;\r
-                }\r
-            }\r
-            $s = 26 * $i + $j - 1;\r
-            $r->_rshift($s);\r
-        }\r
-\r
-        for ($i = 0; $i < $t; ++$i) {\r
-            $a = $this->random($two, $n_2);\r
-            $y = $a->modPow($r, $n);\r
-\r
-            if (!$y->equals($one) && !$y->equals($n_1)) {\r
-                for ($j = 1; $j < $s && !$y->equals($n_1); ++$j) {\r
-                    $y = $y->modPow($two, $n);\r
-                    if ($y->equals($one)) {\r
-                        return false;\r
-                    }\r
-                }\r
-\r
-                if (!$y->equals($n_1)) {\r
-                    return false;\r
-                }\r
-            }\r
-        }\r
-        return true;\r
-    }\r
-\r
-    /**\r
-     * Logical Left Shift\r
-     *\r
-     * Shifts BigInteger's by $shift bits.\r
-     *\r
-     * @param Integer $shift\r
-     * @access private\r
-     */\r
-    function _lshift($shift)\r
-    {\r
-        if ( $shift == 0 ) {\r
-            return;\r
-        }\r
-\r
-        $num_digits = (int) ($shift / 26);\r
-        $shift %= 26;\r
-        $shift = 1 << $shift;\r
-\r
-        $carry = 0;\r
-\r
-        for ($i = 0; $i < count($this->value); ++$i) {\r
-            $temp = $this->value[$i] * $shift + $carry;\r
-            $carry = (int) ($temp / 0x4000000);\r
-            $this->value[$i] = (int) ($temp - $carry * 0x4000000);\r
-        }\r
-\r
-        if ( $carry ) {\r
-            $this->value[] = $carry;\r
-        }\r
-\r
-        while ($num_digits--) {\r
-            array_unshift($this->value, 0);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Logical Right Shift\r
-     *\r
-     * Shifts BigInteger's by $shift bits.\r
-     *\r
-     * @param Integer $shift\r
-     * @access private\r
-     */\r
-    function _rshift($shift)\r
-    {\r
-        if ($shift == 0) {\r
-            return;\r
-        }\r
-\r
-        $num_digits = (int) ($shift / 26);\r
-        $shift %= 26;\r
-        $carry_shift = 26 - $shift;\r
-        $carry_mask = (1 << $shift) - 1;\r
-\r
-        if ( $num_digits ) {\r
-            $this->value = array_slice($this->value, $num_digits);\r
-        }\r
-\r
-        $carry = 0;\r
-\r
-        for ($i = count($this->value) - 1; $i >= 0; --$i) {\r
-            $temp = $this->value[$i] >> $shift | $carry;\r
-            $carry = ($this->value[$i] & $carry_mask) << $carry_shift;\r
-            $this->value[$i] = $temp;\r
-        }\r
-\r
-        $this->value = $this->_trim($this->value);\r
-    }\r
-\r
-    /**\r
-     * Normalize\r
-     *\r
-     * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision\r
-     *\r
-     * @param Math_BigInteger\r
-     * @return Math_BigInteger\r
-     * @see _trim()\r
-     * @access private\r
-     */\r
-    function _normalize($result)\r
-    {\r
-        $result->precision = $this->precision;\r
-        $result->bitmask = $this->bitmask;\r
-\r
-        switch ( MATH_BIGINTEGER_MODE ) {\r
-            case MATH_BIGINTEGER_MODE_GMP:\r
-                if (!empty($result->bitmask->value)) {\r
-                    $result->value = gmp_and($result->value, $result->bitmask->value);\r
-                }\r
-\r
-                return $result;\r
-            case MATH_BIGINTEGER_MODE_BCMATH:\r
-                if (!empty($result->bitmask->value)) {\r
-                    $result->value = bcmod($result->value, $result->bitmask->value);\r
-                }\r
-\r
-                return $result;\r
-        }\r
-\r
-        $value = &$result->value;\r
-\r
-        if ( !count($value) ) {\r
-            return $result;\r
-        }\r
-\r
-        $value = $this->_trim($value);\r
-\r
-        if (!empty($result->bitmask->value)) {\r
-            $length = min(count($value), count($this->bitmask->value));\r
-            $value = array_slice($value, 0, $length);\r
-\r
-            for ($i = 0; $i < $length; ++$i) {\r
-                $value[$i] = $value[$i] & $this->bitmask->value[$i];\r
-            }\r
-        }\r
-\r
-        return $result;\r
-    }\r
-\r
-    /**\r
-     * Trim\r
-     *\r
-     * Removes leading zeros\r
-     *\r
-     * @return Math_BigInteger\r
-     * @access private\r
-     */\r
-    function _trim($value)\r
-    {\r
-        for ($i = count($value) - 1; $i >= 0; --$i) {\r
-            if ( $value[$i] ) {\r
-                break;\r
-            }\r
-            unset($value[$i]);\r
-        }\r
-\r
-        return $value;\r
-    }\r
-\r
-    /**\r
-     * Array Repeat\r
-     *\r
-     * @param $input Array\r
-     * @param $multiplier mixed\r
-     * @return Array\r
-     * @access private\r
-     */\r
-    function _array_repeat($input, $multiplier)\r
-    {\r
-        return ($multiplier) ? array_fill(0, $multiplier, $input) : array();\r
-    }\r
-\r
-    /**\r
-     * Logical Left Shift\r
-     *\r
-     * Shifts binary strings $shift bits, essentially multiplying by 2**$shift.\r
-     *\r
-     * @param $x String\r
-     * @param $shift Integer\r
-     * @return String\r
-     * @access private\r
-     */\r
-    function _base256_lshift(&$x, $shift)\r
-    {\r
-        if ($shift == 0) {\r
-            return;\r
-        }\r
-\r
-        $num_bytes = $shift >> 3; // eg. floor($shift/8)\r
-        $shift &= 7; // eg. $shift % 8\r
-\r
-        $carry = 0;\r
-        for ($i = strlen($x) - 1; $i >= 0; --$i) {\r
-            $temp = ord($x[$i]) << $shift | $carry;\r
-            $x[$i] = chr($temp);\r
-            $carry = $temp >> 8;\r
-        }\r
-        $carry = ($carry != 0) ? chr($carry) : '';\r
-        $x = $carry . $x . str_repeat(chr(0), $num_bytes);\r
-    }\r
-\r
-    /**\r
-     * Logical Right Shift\r
-     *\r
-     * Shifts binary strings $shift bits, essentially dividing by 2**$shift and returning the remainder.\r
-     *\r
-     * @param $x String\r
-     * @param $shift Integer\r
-     * @return String\r
-     * @access private\r
-     */\r
-    function _base256_rshift(&$x, $shift)\r
-    {\r
-        if ($shift == 0) {\r
-            $x = ltrim($x, chr(0));\r
-            return '';\r
-        }\r
-\r
-        $num_bytes = $shift >> 3; // eg. floor($shift/8)\r
-        $shift &= 7; // eg. $shift % 8\r
-\r
-        $remainder = '';\r
-        if ($num_bytes) {\r
-            $start = $num_bytes > strlen($x) ? -strlen($x) : -$num_bytes;\r
-            $remainder = substr($x, $start);\r
-            $x = substr($x, 0, -$num_bytes);\r
-        }\r
-\r
-        $carry = 0;\r
-        $carry_shift = 8 - $shift;\r
-        for ($i = 0; $i < strlen($x); ++$i) {\r
-            $temp = (ord($x[$i]) >> $shift) | $carry;\r
-            $carry = (ord($x[$i]) << $carry_shift) & 0xFF;\r
-            $x[$i] = chr($temp);\r
-        }\r
-        $x = ltrim($x, chr(0));\r
-\r
-        $remainder = chr($carry >> $carry_shift) . $remainder;\r
-\r
-        return ltrim($remainder, chr(0));\r
-    }\r
-\r
-    // one quirk about how the following functions are implemented is that PHP defines N to be an unsigned long\r
-    // at 32-bits, while java's longs are 64-bits.\r
-\r
-    /**\r
-     * Converts 32-bit integers to bytes.\r
-     *\r
-     * @param Integer $x\r
-     * @return String\r
-     * @access private\r
-     */\r
-    function _int2bytes($x)\r
-    {\r
-        return ltrim(pack('N', $x), chr(0));\r
-    }\r
-\r
-    /**\r
-     * Converts bytes to 32-bit integers\r
-     *\r
-     * @param String $x\r
-     * @return Integer\r
-     * @access private\r
-     */\r
-    function _bytes2int($x)\r
-    {\r
-        $temp = unpack('Nint', str_pad($x, 4, chr(0), STR_PAD_LEFT));\r
-        return $temp['int'];\r
-    }\r
-}
\ No newline at end of file
diff --git a/library/phpsec/Net/SFTP.php b/library/phpsec/Net/SFTP.php
deleted file mode 100644 (file)
index 06812ad..0000000
+++ /dev/null
@@ -1,1461 +0,0 @@
-<?php\r
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */\r
-\r
-/**\r
- * Pure-PHP implementation of SFTP.\r
- *\r
- * PHP versions 4 and 5\r
- *\r
- * Currently only supports SFTPv3, which, according to wikipedia.org, "is the most widely used version,\r
- * implemented by the popular OpenSSH SFTP server".  If you want SFTPv4/5/6 support, provide me with access\r
- * to an SFTPv4/5/6 server.\r
- *\r
- * The API for this library is modeled after the API from PHP's {@link http://php.net/book.ftp FTP extension}.\r
- *\r
- * Here's a short example of how to use this library:\r
- * <code>\r
- * <?php\r
- *    include('Net/SFTP.php');\r
- *\r
- *    $sftp = new Net_SFTP('www.domain.tld');\r
- *    if (!$sftp->login('username', 'password')) {\r
- *        exit('Login Failed');\r
- *    }\r
- *\r
- *    echo $sftp->pwd() . "\r\n";\r
- *    $sftp->put('filename.ext', 'hello, world!');\r
- *    print_r($sftp->nlist());\r
- * ?>\r
- * </code>\r
- *\r
- * LICENSE: This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,\r
- * MA  02111-1307  USA\r
- *\r
- * @category   Net\r
- * @package    Net_SFTP\r
- * @author     Jim Wigginton <terrafrost@php.net>\r
- * @copyright  MMIX Jim Wigginton\r
- * @license    http://www.gnu.org/licenses/lgpl.txt\r
- * @version    $Id: SFTP.php,v 1.21 2010/04/09 02:31:34 terrafrost Exp $\r
- * @link       http://phpseclib.sourceforge.net\r
- */\r
-\r
-/**\r
- * Include Net_SSH2\r
- */\r
-require_once('Net/SSH2.php');\r
-\r
-/**#@+\r
- * @access public\r
- * @see Net_SFTP::getLog()\r
- */\r
-/**\r
- * Returns the message numbers\r
- */\r
-define('NET_SFTP_LOG_SIMPLE',  NET_SSH2_LOG_SIMPLE);\r
-/**\r
- * Returns the message content\r
- */\r
-define('NET_SFTP_LOG_COMPLEX', NET_SSH2_LOG_COMPLEX);\r
-/**#@-*/\r
-\r
-/**\r
- * SFTP channel constant\r
- *\r
- * Net_SSH2::exec() uses 0 and Net_SSH2::interactiveRead() / Net_SSH2::interactiveWrite() use 1.\r
- *\r
- * @see Net_SSH2::_send_channel_packet()\r
- * @see Net_SSH2::_get_channel_packet()\r
- * @access private\r
- */\r
-define('NET_SFTP_CHANNEL', 2);\r
-\r
-/**#@+\r
- * @access public\r
- * @see Net_SFTP::put()\r
- */\r
-/**\r
- * Reads data from a local file.\r
- */\r
-define('NET_SFTP_LOCAL_FILE', 1);\r
-/**\r
- * Reads data from a string.\r
- */\r
-define('NET_SFTP_STRING',  2);\r
-/**#@-*/\r
-\r
-/**\r
- * Pure-PHP implementations of SFTP.\r
- *\r
- * @author  Jim Wigginton <terrafrost@php.net>\r
- * @version 0.1.0\r
- * @access  public\r
- * @package Net_SFTP\r
- */\r
-class Net_SFTP extends Net_SSH2 {\r
-    /**\r
-     * Packet Types\r
-     *\r
-     * @see Net_SFTP::Net_SFTP()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $packet_types = array();\r
-\r
-    /**\r
-     * Status Codes\r
-     *\r
-     * @see Net_SFTP::Net_SFTP()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $status_codes = array();\r
-\r
-    /**\r
-     * The Request ID\r
-     *\r
-     * The request ID exists in the off chance that a packet is sent out-of-order.  Of course, this library doesn't support\r
-     * concurrent actions, so it's somewhat academic, here.\r
-     *\r
-     * @var Integer\r
-     * @see Net_SFTP::_send_sftp_packet()\r
-     * @access private\r
-     */\r
-    var $request_id = false;\r
-\r
-    /**\r
-     * The Packet Type\r
-     *\r
-     * The request ID exists in the off chance that a packet is sent out-of-order.  Of course, this library doesn't support\r
-     * concurrent actions, so it's somewhat academic, here.\r
-     *\r
-     * @var Integer\r
-     * @see Net_SFTP::_get_sftp_packet()\r
-     * @access private\r
-     */\r
-    var $packet_type = -1;\r
-\r
-    /**\r
-     * Packet Buffer\r
-     *\r
-     * @var String\r
-     * @see Net_SFTP::_get_sftp_packet()\r
-     * @access private\r
-     */\r
-    var $packet_buffer = '';\r
-\r
-    /**\r
-     * Extensions supported by the server\r
-     *\r
-     * @var Array\r
-     * @see Net_SFTP::_initChannel()\r
-     * @access private\r
-     */\r
-    var $extensions = array();\r
-\r
-    /**\r
-     * Server SFTP version\r
-     *\r
-     * @var Integer\r
-     * @see Net_SFTP::_initChannel()\r
-     * @access private\r
-     */\r
-    var $version;\r
-\r
-    /**\r
-     * Current working directory\r
-     *\r
-     * @var String\r
-     * @see Net_SFTP::_realpath()\r
-     * @see Net_SFTP::chdir()\r
-     * @access private\r
-     */\r
-    var $pwd = false;\r
-\r
-    /**\r
-     * Packet Type Log\r
-     *\r
-     * @see Net_SFTP::getLog()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $packet_type_log = array();\r
-\r
-    /**\r
-     * Packet Log\r
-     *\r
-     * @see Net_SFTP::getLog()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $packet_log = array();\r
-\r
-    /**\r
-     * Error information\r
-     *\r
-     * @see Net_SFTP::getSFTPErrors()\r
-     * @see Net_SFTP::getLastSFTPError()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $errors = array();\r
-\r
-    /**\r
-     * Default Constructor.\r
-     *\r
-     * Connects to an SFTP server\r
-     *\r
-     * @param String $host\r
-     * @param optional Integer $port\r
-     * @param optional Integer $timeout\r
-     * @return Net_SFTP\r
-     * @access public\r
-     */\r
-    function Net_SFTP($host, $port = 22, $timeout = 10)\r
-    {\r
-        parent::Net_SSH2($host, $port, $timeout);\r
-        $this->packet_types = array(\r
-            1  => 'NET_SFTP_INIT',\r
-            2  => 'NET_SFTP_VERSION',\r
-            /* the format of SSH_FXP_OPEN changed between SFTPv4 and SFTPv5+:\r
-                   SFTPv5+: http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.1\r
-               pre-SFTPv5 : http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3 */\r
-            3  => 'NET_SFTP_OPEN',\r
-            4  => 'NET_SFTP_CLOSE',\r
-            5  => 'NET_SFTP_READ',\r
-            6  => 'NET_SFTP_WRITE',\r
-            8  => 'NET_SFTP_FSTAT',\r
-            9  => 'NET_SFTP_SETSTAT',\r
-            11 => 'NET_SFTP_OPENDIR',\r
-            12 => 'NET_SFTP_READDIR',\r
-            13 => 'NET_SFTP_REMOVE',\r
-            14 => 'NET_SFTP_MKDIR',\r
-            15 => 'NET_SFTP_RMDIR',\r
-            16 => 'NET_SFTP_REALPATH',\r
-            17 => 'NET_SFTP_STAT',\r
-            /* the format of SSH_FXP_RENAME changed between SFTPv4 and SFTPv5+:\r
-                   SFTPv5+: http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3\r
-               pre-SFTPv5 : http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.5 */\r
-            18 => 'NET_SFTP_RENAME',\r
-\r
-            101=> 'NET_SFTP_STATUS',\r
-            102=> 'NET_SFTP_HANDLE',\r
-            /* the format of SSH_FXP_NAME changed between SFTPv3 and SFTPv4+:\r
-                   SFTPv4+: http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.4\r
-               pre-SFTPv4 : http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02#section-7 */\r
-            103=> 'NET_SFTP_DATA',\r
-            104=> 'NET_SFTP_NAME',\r
-            105=> 'NET_SFTP_ATTRS',\r
-\r
-            200=> 'NET_SFTP_EXTENDED'\r
-        );\r
-        $this->status_codes = array(\r
-            0 => 'NET_SFTP_STATUS_OK',\r
-            1 => 'NET_SFTP_STATUS_EOF',\r
-            2 => 'NET_SFTP_STATUS_NO_SUCH_FILE',\r
-            3 => 'NET_SFTP_STATUS_PERMISSION_DENIED',\r
-            4 => 'NET_SFTP_STATUS_FAILURE',\r
-            5 => 'NET_SFTP_STATUS_BAD_MESSAGE',\r
-            6 => 'NET_SFTP_STATUS_NO_CONNECTION',\r
-            7 => 'NET_SFTP_STATUS_CONNECTION_LOST',\r
-            8 => 'NET_SFTP_STATUS_OP_UNSUPPORTED'\r
-        );\r
-        // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1\r
-        // the order, in this case, matters quite a lot - see Net_SFTP::_parseAttributes() to understand why\r
-        $this->attributes = array(\r
-            0x00000001 => 'NET_SFTP_ATTR_SIZE',\r
-            0x00000002 => 'NET_SFTP_ATTR_UIDGID', // defined in SFTPv3, removed in SFTPv4+\r
-            0x00000004 => 'NET_SFTP_ATTR_PERMISSIONS',\r
-            0x00000008 => 'NET_SFTP_ATTR_ACCESSTIME',\r
-                    -1 => 'NET_SFTP_ATTR_EXTENDED' // unpack('N', "\xFF\xFF\xFF\xFF") == array(1 => int(-1))\r
-        );\r
-        // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3\r
-        // the flag definitions change somewhat in SFTPv5+.  if SFTPv5+ support is added to this library, maybe name\r
-        // the array for that $this->open5_flags and similarily alter the constant names.\r
-        $this->open_flags = array(\r
-            0x00000001 => 'NET_SFTP_OPEN_READ',\r
-            0x00000002 => 'NET_SFTP_OPEN_WRITE',\r
-            0x00000008 => 'NET_SFTP_OPEN_CREATE',\r
-            0x00000010 => 'NET_SFTP_OPEN_TRUNCATE'\r
-        );\r
-        $this->_define_array(\r
-            $this->packet_types,\r
-            $this->status_codes,\r
-            $this->attributes,\r
-            $this->open_flags\r
-        );\r
-    }\r
-\r
-    /**\r
-     * Login\r
-     *\r
-     * @param String $username\r
-     * @param optional String $password\r
-     * @return Boolean\r
-     * @access public\r
-     */\r
-    function login($username, $password = '')\r
-    {\r
-        if (!parent::login($username, $password)) {\r
-            return false;\r
-        }\r
-\r
-        $this->window_size_client_to_server[NET_SFTP_CHANNEL] = $this->window_size;\r
-\r
-        $packet = pack('CNa*N3',\r
-            NET_SSH2_MSG_CHANNEL_OPEN, strlen('session'), 'session', NET_SFTP_CHANNEL, $this->window_size, 0x4000);\r
-\r
-        if (!$this->_send_binary_packet($packet)) {\r
-            return false;\r
-        }\r
-\r
-        $this->channel_status[NET_SFTP_CHANNEL] = NET_SSH2_MSG_CHANNEL_OPEN;\r
-\r
-        $response = $this->_get_channel_packet(NET_SFTP_CHANNEL);\r
-        if ($response === false) {\r
-            return false;\r
-        }\r
-\r
-        $packet = pack('CNNa*CNa*',\r
-            NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[NET_SFTP_CHANNEL], strlen('subsystem'), 'subsystem', 1, strlen('sftp'), 'sftp');\r
-        if (!$this->_send_binary_packet($packet)) {\r
-            return false;\r
-        }\r
-\r
-        $this->channel_status[NET_SFTP_CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;\r
-\r
-        $response = $this->_get_channel_packet(NET_SFTP_CHANNEL);\r
-        if ($response === false) {\r
-            return false;\r
-        }\r
-\r
-        $this->channel_status[NET_SFTP_CHANNEL] = NET_SSH2_MSG_CHANNEL_DATA;\r
-\r
-        if (!$this->_send_sftp_packet(NET_SFTP_INIT, "\0\0\0\3")) {\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_sftp_packet();\r
-        if ($this->packet_type != NET_SFTP_VERSION) {\r
-            user_error('Expected SSH_FXP_VERSION', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        extract(unpack('Nversion', $this->_string_shift($response, 4)));\r
-        $this->version = $version;\r
-        while (!empty($response)) {\r
-            extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-            $key = $this->_string_shift($response, $length);\r
-            extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-            $value = $this->_string_shift($response, $length);\r
-            $this->extensions[$key] = $value;\r
-        }\r
-\r
-        /*\r
-         SFTPv4+ defines a 'newline' extension.  SFTPv3 seems to have unofficial support for it via 'newline@vandyke.com',\r
-         however, I'm not sure what 'newline@vandyke.com' is supposed to do (the fact that it's unofficial means that it's\r
-         not in the official SFTPv3 specs) and 'newline@vandyke.com' / 'newline' are likely not drop-in substitutes for\r
-         one another due to the fact that 'newline' comes with a SSH_FXF_TEXT bitmask whereas it seems unlikely that\r
-         'newline@vandyke.com' would.\r
-        */\r
-        /*\r
-        if (isset($this->extensions['newline@vandyke.com'])) {\r
-            $this->extensions['newline'] = $this->extensions['newline@vandyke.com'];\r
-            unset($this->extensions['newline@vandyke.com']);\r
-        }\r
-        */\r
-\r
-        $this->request_id = 1;\r
-\r
-        /*\r
-         A Note on SFTPv4/5/6 support:\r
-         <http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-5.1> states the following:\r
-\r
-         "If the client wishes to interoperate with servers that support noncontiguous version\r
-          numbers it SHOULD send '3'"\r
-\r
-         Given that the server only sends its version number after the client has already done so, the above\r
-         seems to be suggesting that v3 should be the default version.  This makes sense given that v3 is the\r
-         most popular.\r
-\r
-         <http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-5.5> states the following;\r
-\r
-         "If the server did not send the "versions" extension, or the version-from-list was not included, the\r
-          server MAY send a status response describing the failure, but MUST then close the channel without\r
-          processing any further requests."\r
-\r
-         So what do you do if you have a client whose initial SSH_FXP_INIT packet says it implements v3 and\r
-         a server whose initial SSH_FXP_VERSION reply says it implements v4 and only v4?  If it only implements\r
-         v4, the "versions" extension is likely not going to have been sent so version re-negotiation as discussed\r
-         in draft-ietf-secsh-filexfer-13 would be quite impossible.  As such, what Net_SFTP would do is close the\r
-         channel and reopen it with a new and updated SSH_FXP_INIT packet.\r
-        */\r
-        if ($this->version != 3) {\r
-            return false;\r
-        }\r
-\r
-        $this->pwd = $this->_realpath('.');\r
-\r
-        return true;\r
-    }\r
-\r
-    /**\r
-     * Returns the current directory name\r
-     *\r
-     * @return Mixed\r
-     * @access public\r
-     */\r
-    function pwd()\r
-    {\r
-        return $this->pwd;\r
-    }\r
-\r
-    /**\r
-     * Canonicalize the Server-Side Path Name\r
-     *\r
-     * SFTP doesn't provide a mechanism by which the current working directory can be changed, so we'll emulate it.  Returns\r
-     * the absolute (canonicalized) path.  If $mode is set to NET_SFTP_CONFIRM_DIR (as opposed to NET_SFTP_CONFIRM_NONE,\r
-     * which is what it is set to by default), false is returned if $dir is not a valid directory.\r
-     *\r
-     * @see Net_SFTP::chdir()\r
-     * @param String $dir\r
-     * @param optional Integer $mode\r
-     * @return Mixed\r
-     * @access private\r
-     */\r
-    function _realpath($dir)\r
-    {\r
-        /*\r
-        "This protocol represents file names as strings.  File names are\r
-         assumed to use the slash ('/') character as a directory separator.\r
-\r
-         File names starting with a slash are "absolute", and are relative to\r
-         the root of the file system.  Names starting with any other character\r
-         are relative to the user's default directory (home directory).  Note\r
-         that identifying the user is assumed to take place outside of this\r
-         protocol."\r
-\r
-         -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-6\r
-        */\r
-        $file = '';\r
-        if ($this->pwd !== false) {\r
-            // if the SFTP server returned the canonicalized path even for non-existant files this wouldn't be necessary\r
-            // on OpenSSH it isn't necessary but on other SFTP servers it is.  that and since the specs say nothing on\r
-            // the subject, we'll go ahead and work around it with the following.\r
-            if ($dir[strlen($dir) - 1] != '/') {\r
-                $file = basename($dir);\r
-                $dir = dirname($dir);\r
-            }\r
-\r
-            if ($dir == '.' || $dir == $this->pwd) {\r
-                return $this->pwd . $file;\r
-            }\r
-\r
-            if ($dir[0] != '/') {\r
-                $dir = $this->pwd . '/' . $dir;\r
-            }\r
-            // on the surface it seems like maybe resolving a path beginning with / is unnecessary, but such paths\r
-            // can contain .'s and ..'s just like any other.  we could parse those out as appropriate or we can let\r
-            // the server do it.  we'll do the latter.\r
-        }\r
-\r
-        /*\r
-         that SSH_FXP_REALPATH returns SSH_FXP_NAME does not necessarily mean that anything actually exists at the\r
-         specified path.  generally speaking, no attributes are returned with this particular SSH_FXP_NAME packet\r
-         regardless of whether or not a file actually exists.  and in SFTPv3, the longname field and the filename\r
-         field match for this particular SSH_FXP_NAME packet.  for other SSH_FXP_NAME packets, this will likely\r
-         not be the case, but for this one, it is.\r
-        */\r
-        // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.9\r
-        if (!$this->_send_sftp_packet(NET_SFTP_REALPATH, pack('Na*', strlen($dir), $dir))) {\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_sftp_packet();\r
-        switch ($this->packet_type) {\r
-            case NET_SFTP_NAME:\r
-                // although SSH_FXP_NAME is implemented differently in SFTPv3 than it is in SFTPv4+, the following\r
-                // should work on all SFTP versions since the only part of the SSH_FXP_NAME packet the following looks\r
-                // at is the first part and that part is defined the same in SFTP versions 3 through 6.\r
-                $this->_string_shift($response, 4); // skip over the count - it should be 1, anyway\r
-                extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-                $realpath = $this->_string_shift($response, $length);\r
-                break;\r
-            case NET_SFTP_STATUS:\r
-                extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));\r
-                $this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);\r
-                return false;\r
-            default:\r
-                user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS', E_USER_NOTICE);\r
-                return false;\r
-        }\r
-\r
-        // if $this->pwd isn't set than the only thing $realpath could be is for '.', which is pretty much guaranteed to\r
-        // be a bonafide directory\r
-        return $realpath . '/' . $file;\r
-    }\r
-\r
-    /**\r
-     * Changes the current directory\r
-     *\r
-     * @param String $dir\r
-     * @return Boolean\r
-     * @access public\r
-     */\r
-    function chdir($dir)\r
-    {\r
-        if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {\r
-            return false;\r
-        }\r
-\r
-        if ($dir[strlen($dir) - 1] != '/') {\r
-            $dir.= '/';\r
-        }\r
-        $dir = $this->_realpath($dir);\r
-\r
-        // confirm that $dir is, in fact, a valid directory\r
-        if (!$this->_send_sftp_packet(NET_SFTP_OPENDIR, pack('Na*', strlen($dir), $dir))) {\r
-            return false;\r
-        }\r
-\r
-        // see Net_SFTP::nlist() for a more thorough explanation of the following\r
-        $response = $this->_get_sftp_packet();\r
-        switch ($this->packet_type) {\r
-            case NET_SFTP_HANDLE:\r
-                $handle = substr($response, 4);\r
-                break;\r
-            case NET_SFTP_STATUS:\r
-                extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));\r
-                $this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);\r
-                return false;\r
-            default:\r
-                user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE);\r
-                return false;\r
-        }\r
-\r
-        if (!$this->_send_sftp_packet(NET_SFTP_CLOSE, pack('Na*', strlen($handle), $handle))) {\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_sftp_packet();\r
-        if ($this->packet_type != NET_SFTP_STATUS) {\r
-            user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        extract(unpack('Nstatus', $this->_string_shift($response, 4)));\r
-        if ($status != NET_SFTP_STATUS_OK) {\r
-            extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-            $this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);\r
-            return false;\r
-        }\r
-\r
-        $this->pwd = $dir;\r
-        return true;\r
-    }\r
-\r
-    /**\r
-     * Returns a list of files in the given directory\r
-     *\r
-     * @param optional String $dir\r
-     * @return Mixed\r
-     * @access public\r
-     */\r
-    function nlist($dir = '.')\r
-    {\r
-        return $this->_list($dir, false);\r
-    }\r
-\r
-    /**\r
-     * Returns a list of files in the given directory\r
-     *\r
-     * @param optional String $dir\r
-     * @return Mixed\r
-     * @access public\r
-     */\r
-    function rawlist($dir = '.')\r
-    {\r
-        return $this->_list($dir, true);\r
-    }\r
-\r
-    function _list($dir, $raw = true)\r
-    {\r
-        if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {\r
-            return false;\r
-        }\r
-\r
-        $dir = $this->_realpath($dir);\r
-        if ($dir === false) {\r
-            return false;\r
-        }\r
-\r
-        // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.2\r
-        if (!$this->_send_sftp_packet(NET_SFTP_OPENDIR, pack('Na*', strlen($dir), $dir))) {\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_sftp_packet();\r
-        switch ($this->packet_type) {\r
-            case NET_SFTP_HANDLE:\r
-                // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.2\r
-                // since 'handle' is the last field in the SSH_FXP_HANDLE packet, we'll just remove the first four bytes that\r
-                // represent the length of the string and leave it at that\r
-                $handle = substr($response, 4);\r
-                break;\r
-            case NET_SFTP_STATUS:\r
-                // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED\r
-                extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));\r
-                $this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);\r
-                return false;\r
-            default:\r
-                user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE);\r
-                return false;\r
-        }\r
-\r
-        $contents = array();\r
-        while (true) {\r
-            // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.2\r
-            // why multiple SSH_FXP_READDIR packets would be sent when the response to a single one can span arbitrarily many\r
-            // SSH_MSG_CHANNEL_DATA messages is not known to me.\r
-            if (!$this->_send_sftp_packet(NET_SFTP_READDIR, pack('Na*', strlen($handle), $handle))) {\r
-                return false;\r
-            }\r
-\r
-            $response = $this->_get_sftp_packet();\r
-            switch ($this->packet_type) {\r
-                case NET_SFTP_NAME:\r
-                    extract(unpack('Ncount', $this->_string_shift($response, 4)));\r
-                    for ($i = 0; $i < $count; $i++) {\r
-                        extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-                        $shortname = $this->_string_shift($response, $length);\r
-                        extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-                        $this->_string_shift($response, $length); // SFTPv4+ drop this field - the "longname" field\r
-                        $attributes = $this->_parseAttributes($response); // we also don't care about the attributes\r
-                        if (!$raw) {\r
-                            $contents[] = $shortname;\r
-                        } else {\r
-                            $contents[$shortname] = $attributes;\r
-                        }\r
-                        // SFTPv6 has an optional boolean end-of-list field, but we'll ignore that, since the\r
-                        // final SSH_FXP_STATUS packet should tell us that, already.\r
-                    }\r
-                    break;\r
-                case NET_SFTP_STATUS:\r
-                    extract(unpack('Nstatus', $this->_string_shift($response, 4)));\r
-                    if ($status != NET_SFTP_STATUS_EOF) {\r
-                        extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-                        $this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);\r
-                        return false;\r
-                    }\r
-                    break 2;\r
-                default:\r
-                    user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS', E_USER_NOTICE);\r
-                    return false;\r
-            }\r
-        }\r
-\r
-        if (!$this->_send_sftp_packet(NET_SFTP_CLOSE, pack('Na*', strlen($handle), $handle))) {\r
-            return false;\r
-        }\r
-\r
-        // "The client MUST release all resources associated with the handle regardless of the status."\r
-        //  -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3\r
-        $response = $this->_get_sftp_packet();\r
-        if ($this->packet_type != NET_SFTP_STATUS) {\r
-            user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        extract(unpack('Nstatus', $this->_string_shift($response, 4)));\r
-        if ($status != NET_SFTP_STATUS_OK) {\r
-            extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-            $this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);\r
-            return false;\r
-        }\r
-\r
-        return $contents;\r
-    }\r
-\r
-    /**\r
-     * Returns the file size, in bytes, or false, on failure\r
-     *\r
-     * Files larger than 4GB will show up as being exactly 4GB.\r
-     *\r
-     * @param optional String $dir\r
-     * @return Mixed\r
-     * @access public\r
-     */\r
-    function size($filename)\r
-    {\r
-        if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {\r
-            return false;\r
-        }\r
-\r
-        $filename = $this->_realpath($filename);\r
-        if ($filename === false) {\r
-            return false;\r
-        }\r
-\r
-        // SFTPv4+ adds an additional 32-bit integer field - flags - to the following:\r
-        $packet = pack('Na*', strlen($filename), $filename);\r
-        if (!$this->_send_sftp_packet(NET_SFTP_STAT, $packet)) {\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_sftp_packet();\r
-        switch ($this->packet_type) {\r
-            case NET_SFTP_ATTRS:\r
-                $attrs = $this->_parseAttributes($response);\r
-                return $attrs['size'];\r
-            case NET_SFTP_STATUS:\r
-                extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));\r
-                $this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);\r
-                return false;\r
-        }\r
-\r
-        user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS', E_USER_NOTICE);\r
-        return false;\r
-    }\r
-\r
-    /**\r
-     * Set permissions on a file.\r
-     *\r
-     * Returns the new file permissions on success or FALSE on error.\r
-     *\r
-     * @param Integer $mode\r
-     * @param String $filename\r
-     * @return Mixed\r
-     * @access public\r
-     */\r
-    function chmod($mode, $filename)\r
-    {\r
-        if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {\r
-            return false;\r
-        }\r
-\r
-        $filename = $this->_realpath($filename);\r
-        if ($filename === false) {\r
-            return false;\r
-        }\r
-\r
-        // SFTPv4+ has an additional byte field - type - that would need to be sent, as well. setting it to\r
-        // SSH_FILEXFER_TYPE_UNKNOWN might work. if not, we'd have to do an SSH_FXP_STAT before doing an SSH_FXP_SETSTAT.\r
-        $attr = pack('N2', NET_SFTP_ATTR_PERMISSIONS, $mode & 07777);\r
-        if (!$this->_send_sftp_packet(NET_SFTP_SETSTAT, pack('Na*a*', strlen($filename), $filename, $attr))) {\r
-            return false;\r
-        }\r
-\r
-        /*\r
-         "Because some systems must use separate system calls to set various attributes, it is possible that a failure \r
-          response will be returned, but yet some of the attributes may be have been successfully modified.  If possible,\r
-          servers SHOULD avoid this situation; however, clients MUST be aware that this is possible."\r
-\r
-          -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.6\r
-        */\r
-        $response = $this->_get_sftp_packet();\r
-        if ($this->packet_type != NET_SFTP_STATUS) {\r
-            user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        extract(unpack('Nstatus', $this->_string_shift($response, 4)));\r
-        if ($status != NET_SFTP_STATUS_EOF) {\r
-            extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-            $this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);\r
-        }\r
-\r
-        // rather than return what the permissions *should* be, we'll return what they actually are.  this will also\r
-        // tell us if the file actually exists.\r
-        // incidentally, SFTPv4+ adds an additional 32-bit integer field - flags - to the following:\r
-        $packet = pack('Na*', strlen($filename), $filename);\r
-        if (!$this->_send_sftp_packet(NET_SFTP_STAT, $packet)) {\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_sftp_packet();\r
-        switch ($this->packet_type) {\r
-            case NET_SFTP_ATTRS:\r
-                $attrs = $this->_parseAttributes($response);\r
-                return $attrs['permissions'];\r
-            case NET_SFTP_STATUS:\r
-                extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));\r
-                $this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);\r
-                return false;\r
-        }\r
-\r
-        user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS', E_USER_NOTICE);\r
-        return false;\r
-    }\r
-\r
-    /**\r
-     * Creates a directory.\r
-     *\r
-     * @param String $dir\r
-     * @return Boolean\r
-     * @access public\r
-     */\r
-    function mkdir($dir)\r
-    {\r
-        if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {\r
-            return false;\r
-        }\r
-\r
-        $dir = $this->_realpath(rtrim($dir, '/'));\r
-        if ($dir === false) {\r
-            return false;\r
-        }\r
-\r
-        // by not providing any permissions, hopefully the server will use the logged in users umask - their \r
-        // default permissions.\r
-        if (!$this->_send_sftp_packet(NET_SFTP_MKDIR, pack('Na*N', strlen($dir), $dir, 0))) {\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_sftp_packet();\r
-        if ($this->packet_type != NET_SFTP_STATUS) {\r
-            user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        extract(unpack('Nstatus', $this->_string_shift($response, 4)));\r
-        if ($status != NET_SFTP_STATUS_OK) {\r
-            extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-            $this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);\r
-            return false;\r
-        }\r
-\r
-        return true;\r
-    }\r
-\r
-    /**\r
-     * Removes a directory.\r
-     *\r
-     * @param String $dir\r
-     * @return Boolean\r
-     * @access public\r
-     */\r
-    function rmdir($dir)\r
-    {\r
-        if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {\r
-            return false;\r
-        }\r
-\r
-        $dir = $this->_realpath($dir);\r
-        if ($dir === false) {\r
-            return false;\r
-        }\r
-\r
-        if (!$this->_send_sftp_packet(NET_SFTP_RMDIR, pack('Na*', strlen($dir), $dir))) {\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_sftp_packet();\r
-        if ($this->packet_type != NET_SFTP_STATUS) {\r
-            user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        extract(unpack('Nstatus', $this->_string_shift($response, 4)));\r
-        if ($status != NET_SFTP_STATUS_OK) {\r
-            // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED?\r
-            extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-            $this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);\r
-            return false;\r
-        }\r
-\r
-        return true;\r
-    }\r
-\r
-    /**\r
-     * Uploads a file to the SFTP server.\r
-     *\r
-     * By default, Net_SFTP::put() does not read from the local filesystem.  $data is dumped directly into $remote_file.\r
-     * So, for example, if you set $data to 'filename.ext' and then do Net_SFTP::get(), you will get a file, twelve bytes\r
-     * long, containing 'filename.ext' as its contents.\r
-     *\r
-     * Setting $mode to NET_SFTP_LOCAL_FILE will change the above behavior.  With NET_SFTP_LOCAL_FILE, $remote_file will \r
-     * contain as many bytes as filename.ext does on your local filesystem.  If your filename.ext is 1MB then that is how\r
-     * large $remote_file will be, as well.\r
-     *\r
-     * Currently, only binary mode is supported.  As such, if the line endings need to be adjusted, you will need to take\r
-     * care of that, yourself.\r
-     *\r
-     * @param String $remote_file\r
-     * @param String $data\r
-     * @param optional Integer $flags\r
-     * @return Boolean\r
-     * @access public\r
-     * @internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - Net_SFTP::setMode().\r
-     */\r
-    function put($remote_file, $data, $mode = NET_SFTP_STRING)\r
-    {\r
-        if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {\r
-            return false;\r
-        }\r
-\r
-        $remote_file = $this->_realpath($remote_file);\r
-        if ($remote_file === false) {\r
-            return false;\r
-        }\r
-\r
-        $packet = pack('Na*N2', strlen($remote_file), $remote_file, NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE | NET_SFTP_OPEN_TRUNCATE, 0);\r
-        if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) {\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_sftp_packet();\r
-        switch ($this->packet_type) {\r
-            case NET_SFTP_HANDLE:\r
-                $handle = substr($response, 4);\r
-                break;\r
-            case NET_SFTP_STATUS:\r
-                extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));\r
-                $this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);\r
-                return false;\r
-            default:\r
-                user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE);\r
-                return false;\r
-        }\r
-\r
-        $initialize = true;\r
-\r
-        // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3\r
-        if ($mode == NET_SFTP_LOCAL_FILE) {\r
-            if (!is_file($data)) {\r
-                user_error("$data is not a valid file", E_USER_NOTICE);\r
-                return false;\r
-            }\r
-            $fp = fopen($data, 'rb');\r
-            if (!$fp) {\r
-                return false;\r
-            }\r
-            $sent = 0;\r
-            $size = filesize($data);\r
-        } else {\r
-            $sent = 0;\r
-            $size = strlen($data);\r
-        }\r
-\r
-        $size = $size < 0 ? ($size & 0x7FFFFFFF) + 0x80000000 : $size;\r
-\r
-        $sftp_packet_size = 34000; // PuTTY uses 4096\r
-        $i = 0;\r
-        while ($sent < $size) {\r
-            $temp = $mode == NET_SFTP_LOCAL_FILE ? fread($fp, $sftp_packet_size) : $this->_string_shift($data, $sftp_packet_size);\r
-            $packet = pack('Na*N3a*', strlen($handle), $handle, 0, $sent, strlen($temp), $temp);\r
-            if (!$this->_send_sftp_packet(NET_SFTP_WRITE, $packet)) {\r
-                fclose($fp);\r
-                return false;\r
-            }\r
-            $sent+= strlen($temp);\r
-\r
-            $i++;\r
-\r
-            if ($i == 50) {\r
-                if (!$this->_read_put_responses($i)) {\r
-                    $i = 0;\r
-                    break;\r
-                }\r
-                $i = 0;\r
-            }\r
-        }\r
-\r
-        $this->_read_put_responses($i);\r
-\r
-        if ($mode == NET_SFTP_LOCAL_FILE) {\r
-            fclose($fp);\r
-        }\r
-\r
-        if (!$this->_send_sftp_packet(NET_SFTP_CLOSE, pack('Na*', strlen($handle), $handle))) {\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_sftp_packet();\r
-        if ($this->packet_type != NET_SFTP_STATUS) {\r
-            user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        extract(unpack('Nstatus', $this->_string_shift($response, 4)));\r
-        if ($status != NET_SFTP_STATUS_OK) {\r
-            extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-            $this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);\r
-            return false;\r
-        }\r
-\r
-        return true;\r
-    }\r
-\r
-    /**\r
-     * Reads multiple successive SSH_FXP_WRITE responses\r
-     *\r
-     * Sending an SSH_FXP_WRITE packet and immediately reading its response isn't as efficient as blindly sending out $i\r
-     * SSH_FXP_WRITEs, in succession, and then reading $i responses.\r
-     *\r
-     * @param Integer $i\r
-     * @return Boolean\r
-     * @access private\r
-     */\r
-    function _read_put_responses($i)\r
-    {\r
-        while ($i--) {\r
-            $response = $this->_get_sftp_packet();\r
-            if ($this->packet_type != NET_SFTP_STATUS) {\r
-                user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);\r
-                return false;\r
-            }\r
-\r
-            extract(unpack('Nstatus', $this->_string_shift($response, 4)));\r
-            if ($status != NET_SFTP_STATUS_OK) {\r
-                extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-                $this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);\r
-                break;\r
-            }\r
-        }\r
-\r
-        return $i < 0;\r
-    }\r
-\r
-    /**\r
-     * Downloads a file from the SFTP server.\r
-     *\r
-     * Returns a string containing the contents of $remote_file if $local_file is left undefined or a boolean false if\r
-     * the operation was unsuccessful.  If $local_file is defined, returns true or false depending on the success of the\r
-     * operation\r
-     *\r
-     * @param String $remote_file\r
-     * @param optional String $local_file\r
-     * @return Mixed\r
-     * @access public\r
-     */\r
-    function get($remote_file, $local_file = false)\r
-    {\r
-        if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {\r
-            return false;\r
-        }\r
-\r
-        $remote_file = $this->_realpath($remote_file);\r
-        if ($remote_file === false) {\r
-            return false;\r
-        }\r
-\r
-        $packet = pack('Na*N2', strlen($remote_file), $remote_file, NET_SFTP_OPEN_READ, 0);\r
-        if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) {\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_sftp_packet();\r
-        switch ($this->packet_type) {\r
-            case NET_SFTP_HANDLE:\r
-                $handle = substr($response, 4);\r
-                break;\r
-            case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED\r
-                extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));\r
-                $this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);\r
-                return false;\r
-            default:\r
-                user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS', E_USER_NOTICE);\r
-                return false;\r
-        }\r
-\r
-        $packet = pack('Na*', strlen($handle), $handle);\r
-        if (!$this->_send_sftp_packet(NET_SFTP_FSTAT, $packet)) {\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_sftp_packet();\r
-        switch ($this->packet_type) {\r
-            case NET_SFTP_ATTRS:\r
-                $attrs = $this->_parseAttributes($response);\r
-                break;\r
-            case NET_SFTP_STATUS:\r
-                extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));\r
-                $this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);\r
-                return false;\r
-            default:\r
-                user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS', E_USER_NOTICE);\r
-                return false;\r
-        }\r
-\r
-        if ($local_file !== false) {\r
-            $fp = fopen($local_file, 'wb');\r
-            if (!$fp) {\r
-                return false;\r
-            }\r
-        } else {\r
-            $content = '';\r
-        }\r
-\r
-        $read = 0;\r
-        while ($read < $attrs['size']) {\r
-            $packet = pack('Na*N3', strlen($handle), $handle, 0, $read, 1 << 20);\r
-            if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet)) {\r
-                return false;\r
-            }\r
-\r
-            $response = $this->_get_sftp_packet();\r
-            switch ($this->packet_type) {\r
-                case NET_SFTP_DATA:\r
-                    $temp = substr($response, 4);\r
-                    $read+= strlen($temp);\r
-                    if ($local_file === false) {\r
-                        $content.= $temp;\r
-                    } else {\r
-                        fputs($fp, $temp);\r
-                    }\r
-                    break;\r
-                case NET_SFTP_STATUS:\r
-                    extract(unpack('Nstatus/Nlength', $this->_string_shift($response, 8)));\r
-                    $this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);\r
-                    break 2;\r
-                default:\r
-                    user_error('Expected SSH_FXP_DATA or SSH_FXP_STATUS', E_USER_NOTICE);\r
-                    return false;\r
-            }\r
-        }\r
-\r
-        if (!$this->_send_sftp_packet(NET_SFTP_CLOSE, pack('Na*', strlen($handle), $handle))) {\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_sftp_packet();\r
-        if ($this->packet_type != NET_SFTP_STATUS) {\r
-            user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        extract(unpack('Nstatus', $this->_string_shift($response, 4)));\r
-        if ($status != NET_SFTP_STATUS_OK) {\r
-            extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-            $this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);\r
-            return false;\r
-        }\r
-\r
-        if (isset($content)) {\r
-            return $content;\r
-        }\r
-\r
-        fclose($fp);\r
-        return true;\r
-    }\r
-\r
-    /**\r
-     * Deletes a file on the SFTP server.\r
-     *\r
-     * @param String $path\r
-     * @return Boolean\r
-     * @access public\r
-     */\r
-    function delete($path)\r
-    {\r
-        if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {\r
-            return false;\r
-        }\r
-\r
-        $remote_file = $this->_realpath($path);\r
-        if ($path === false) {\r
-            return false;\r
-        }\r
-\r
-        // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3\r
-        if (!$this->_send_sftp_packet(NET_SFTP_REMOVE, pack('Na*', strlen($path), $path))) {\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_sftp_packet();\r
-        if ($this->packet_type != NET_SFTP_STATUS) {\r
-            user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED\r
-        extract(unpack('Nstatus', $this->_string_shift($response, 4)));\r
-        if ($status != NET_SFTP_STATUS_OK) {\r
-            extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-            $this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);\r
-            return false;\r
-        }\r
-\r
-        return true;\r
-    }\r
-\r
-    /**\r
-     * Renames a file or a directory on the SFTP server\r
-     *\r
-     * @param String $oldname\r
-     * @param String $newname\r
-     * @return Boolean\r
-     * @access public\r
-     */\r
-    function rename($oldname, $newname)\r
-    {\r
-        if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {\r
-            return false;\r
-        }\r
-\r
-        $oldname = $this->_realpath($oldname);\r
-        $newname = $this->_realpath($newname);\r
-        if ($oldname === false || $newname === false) {\r
-            return false;\r
-        }\r
-\r
-        // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3\r
-        $packet = pack('Na*Na*', strlen($oldname), $oldname, strlen($newname), $newname);\r
-        if (!$this->_send_sftp_packet(NET_SFTP_RENAME, $packet)) {\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_sftp_packet();\r
-        if ($this->packet_type != NET_SFTP_STATUS) {\r
-            user_error('Expected SSH_FXP_STATUS', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED\r
-        extract(unpack('Nstatus', $this->_string_shift($response, 4)));\r
-        if ($status != NET_SFTP_STATUS_OK) {\r
-            extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-            $this->sftp_errors[] = $this->status_codes[$status] . ': ' . $this->_string_shift($response, $length);\r
-            return false;\r
-        }\r
-\r
-        return true;\r
-    }\r
-\r
-    /**\r
-     * Parse Attributes\r
-     *\r
-     * See '7.  File Attributes' of draft-ietf-secsh-filexfer-13 for more info.\r
-     *\r
-     * @param String $response\r
-     * @return Array\r
-     * @access private\r
-     */\r
-    function _parseAttributes(&$response)\r
-    {\r
-        $attr = array();\r
-        extract(unpack('Nflags', $this->_string_shift($response, 4)));\r
-        // SFTPv4+ have a type field (a byte) that follows the above flag field\r
-        foreach ($this->attributes as $key => $value) {\r
-            switch ($flags & $key) {\r
-                case NET_SFTP_ATTR_SIZE: // 0x00000001\r
-                    // size is represented by a 64-bit integer, so we perhaps ought to be doing the following:\r
-                    // $attr['size'] = new Math_BigInteger($this->_string_shift($response, 8), 256);\r
-                    // of course, you shouldn't be using Net_SFTP to transfer files that are in excess of 4GB\r
-                    // (0xFFFFFFFF bytes), anyway.  as such, we'll just represent all file sizes that are bigger than\r
-                    // 4GB as being 4GB.\r
-                    extract(unpack('Nupper/Nsize', $this->_string_shift($response, 8)));\r
-                    if ($upper) {\r
-                        $attr['size'] = 0xFFFFFFFF;\r
-                    } else {\r
-                        $attr['size'] = $size < 0 ? ($size & 0x7FFFFFFF) + 0x80000000 : $size;\r
-                    }\r
-                    break;\r
-                case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 only)\r
-                    $attr+= unpack('Nuid/Ngid', $this->_string_shift($response, 8));\r
-                    break;\r
-                case NET_SFTP_ATTR_PERMISSIONS: // 0x00000004\r
-                    $attr+= unpack('Npermissions', $this->_string_shift($response, 4));\r
-                    break;\r
-                case NET_SFTP_ATTR_ACCESSTIME: // 0x00000008\r
-                    $attr+= unpack('Natime/Nmtime', $this->_string_shift($response, 8));\r
-                    break;\r
-                case NET_SFTP_ATTR_EXTENDED: // 0x80000000\r
-                    extract(unpack('Ncount', $this->_string_shift($response, 4)));\r
-                    for ($i = 0; $i < $count; $i++) {\r
-                        extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-                        $key = $this->_string_shift($response, $length);\r
-                        extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-                        $attr[$key] = $this->_string_shift($response, $length);                        \r
-                    }\r
-            }\r
-        }\r
-        return $attr;\r
-    }\r
-\r
-    /**\r
-     * Sends SFTP Packets\r
-     *\r
-     * See '6. General Packet Format' of draft-ietf-secsh-filexfer-13 for more info.\r
-     *\r
-     * @param Integer $type\r
-     * @param String $data\r
-     * @see Net_SFTP::_get_sftp_packet()\r
-     * @see Net_SSH2::_send_channel_packet()\r
-     * @return Boolean\r
-     * @access private\r
-     */\r
-    function _send_sftp_packet($type, $data)\r
-    {\r
-        $packet = $this->request_id !== false ?\r
-            pack('NCNa*', strlen($data) + 5, $type, $this->request_id, $data) :\r
-            pack('NCa*',  strlen($data) + 1, $type, $data);\r
-\r
-        $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838\r
-        $result = $this->_send_channel_packet(NET_SFTP_CHANNEL, $packet);\r
-        $stop = strtok(microtime(), ' ') + strtok('');\r
-\r
-        if (defined('NET_SFTP_LOGGING')) {\r
-            $this->packet_type_log[] = '-> ' . $this->packet_types[$type] . \r
-                                       ' (' . round($stop - $start, 4) . 's)';\r
-            if (NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX) {\r
-                $this->packet_log[] = $data;\r
-            }\r
-        }\r
-\r
-        return $result;\r
-    }\r
-\r
-    /**\r
-     * Receives SFTP Packets\r
-     *\r
-     * See '6. General Packet Format' of draft-ietf-secsh-filexfer-13 for more info.\r
-     *\r
-     * Incidentally, the number of SSH_MSG_CHANNEL_DATA messages has no bearing on the number of SFTP packets present.\r
-     * There can be one SSH_MSG_CHANNEL_DATA messages containing two SFTP packets or there can be two SSH_MSG_CHANNEL_DATA\r
-     * messages containing one SFTP packet.\r
-     *\r
-     * @see Net_SFTP::_send_sftp_packet()\r
-     * @return String\r
-     * @access private\r
-     */\r
-    function _get_sftp_packet()\r
-    {\r
-        $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838\r
-\r
-        // SFTP packet length\r
-        while (strlen($this->packet_buffer) < 4) {\r
-            $temp = $this->_get_channel_packet(NET_SFTP_CHANNEL);\r
-            if (is_bool($temp)) {\r
-                $this->packet_type = false;\r
-                $this->packet_buffer = '';\r
-                return false;\r
-            }\r
-            $this->packet_buffer.= $temp;\r
-        }\r
-        extract(unpack('Nlength', $this->_string_shift($this->packet_buffer, 4)));\r
-        $tempLength = $length;\r
-        $tempLength-= strlen($this->packet_buffer);\r
-\r
-        // SFTP packet type and data payload\r
-        while ($tempLength > 0) {\r
-            $temp = $this->_get_channel_packet(NET_SFTP_CHANNEL);\r
-            if (is_bool($temp)) {\r
-                $this->packet_type = false;\r
-                $this->packet_buffer = '';\r
-                return false;\r
-            }\r
-            $this->packet_buffer.= $temp;\r
-            $tempLength-= strlen($temp);\r
-        }\r
-\r
-        $stop = strtok(microtime(), ' ') + strtok('');\r
-\r
-        $this->packet_type = ord($this->_string_shift($this->packet_buffer));\r
-\r
-        if ($this->request_id !== false) {\r
-            $this->_string_shift($this->packet_buffer, 4); // remove the request id\r
-            $length-= 5; // account for the request id and the packet type\r
-        } else {\r
-            $length-= 1; // account for the packet type\r
-        }\r
-\r
-        $packet = $this->_string_shift($this->packet_buffer, $length);\r
-\r
-        if (defined('NET_SFTP_LOGGING')) {\r
-            $this->packet_type_log[] = '<- ' . $this->packet_types[$this->packet_type] . \r
-                                       ' (' . round($stop - $start, 4) . 's)';\r
-            if (NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX) {\r
-                $this->packet_log[] = $packet;\r
-            }\r
-        }\r
-\r
-        return $packet;\r
-    }\r
-\r
-    /**\r
-     * Returns a log of the packets that have been sent and received.\r
-     *\r
-     * Returns a string if NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX, an array if NET_SFTP_LOGGING == NET_SFTP_LOG_SIMPLE and false if !defined('NET_SFTP_LOGGING')\r
-     *\r
-     * @access public\r
-     * @return String or Array\r
-     */\r
-    function getSFTPLog()\r
-    {\r
-        if (!defined('NET_SFTP_LOGGING')) {\r
-            return false;\r
-        }\r
-\r
-        switch (NET_SFTP_LOGGING) {\r
-            case NET_SFTP_LOG_COMPLEX:\r
-                return $this->_format_log($this->packet_log, $this->packet_type_log);\r
-                break;\r
-            //case NET_SFTP_LOG_SIMPLE:\r
-            default:\r
-                return $this->packet_type_log;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Returns all errors\r
-     *\r
-     * @return String\r
-     * @access public\r
-     */\r
-    function getSFTPErrors()\r
-    {\r
-        return $this->sftp_errors;\r
-    }\r
-\r
-    /**\r
-     * Returns the last error\r
-     *\r
-     * @return String\r
-     * @access public\r
-     */\r
-    function getLastSFTPError()\r
-    {\r
-        return $this->sftp_errors[count($this->sftp_errors) - 1];\r
-    }\r
-\r
-    /**\r
-     * Get supported SFTP versions\r
-     *\r
-     * @return Array\r
-     * @access public\r
-     */\r
-    function getSupportedVersions()\r
-    {\r
-        $temp = array('version' => $this->version);\r
-        if (isset($this->extensions['versions'])) {\r
-            $temp['extensions'] = $this->extensions['versions'];\r
-        }\r
-        return $temp;\r
-    }\r
-\r
-    /**\r
-     * Disconnect\r
-     *\r
-     * @param Integer $reason\r
-     * @return Boolean\r
-     * @access private\r
-     */\r
-    function _disconnect($reason)\r
-    {\r
-        $this->pwd = false;\r
-        parent::_disconnect($reason);\r
-    }\r
-}
\ No newline at end of file
diff --git a/library/phpsec/Net/SSH1.php b/library/phpsec/Net/SSH1.php
deleted file mode 100644 (file)
index 7220ee4..0000000
+++ /dev/null
@@ -1,1160 +0,0 @@
-<?php\r
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */\r
-\r
-/**\r
- * Pure-PHP implementation of SSHv1.\r
- *\r
- * PHP versions 4 and 5\r
- *\r
- * Here's a short example of how to use this library:\r
- * <code>\r
- * <?php\r
- *    include('Net/SSH1.php');\r
- *\r
- *    $ssh = new Net_SSH1('www.domain.tld');\r
- *    if (!$ssh->login('username', 'password')) {\r
- *        exit('Login Failed');\r
- *    }\r
- *\r
- *    while (true) {\r
- *        echo $ssh->interactiveRead();\r
- *\r
- *        $read = array(STDIN);\r
- *        $write = $except = NULL;\r
- *        if (stream_select($read, $write, $except, 0)) {\r
- *            $ssh->interactiveWrite(fread(STDIN, 1));\r
- *        }\r
- *    }\r
- * ?>\r
- * </code>\r
- *\r
- * Here's another short example:\r
- * <code>\r
- * <?php\r
- *    include('Net/SSH1.php');\r
- *\r
- *    $ssh = new Net_SSH1('www.domain.tld');\r
- *    if (!$ssh->login('username', 'password')) {\r
- *        exit('Login Failed');\r
- *    }\r
- *\r
- *    echo $ssh->exec('ls -la');\r
- * ?>\r
- * </code>\r
- *\r
- * More information on the SSHv1 specification can be found by reading \r
- * {@link http://www.snailbook.com/docs/protocol-1.5.txt protocol-1.5.txt}.\r
- *\r
- * LICENSE: This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,\r
- * MA  02111-1307  USA\r
- *\r
- * @category   Net\r
- * @package    Net_SSH1\r
- * @author     Jim Wigginton <terrafrost@php.net>\r
- * @copyright  MMVII Jim Wigginton\r
- * @license    http://www.gnu.org/licenses/lgpl.txt\r
- * @version    $Id: SSH1.php,v 1.15 2010/03/22 22:01:38 terrafrost Exp $\r
- * @link       http://phpseclib.sourceforge.net\r
- */\r
-\r
-/**\r
- * Include Math_BigInteger\r
- *\r
- * Used to do RSA encryption.\r
- */\r
-require_once('Math/BigInteger.php');\r
-\r
-/**\r
- * Include Crypt_Null\r
- */\r
-//require_once('Crypt/Null.php');\r
-\r
-/**\r
- * Include Crypt_DES\r
- */\r
-require_once('Crypt/DES.php');\r
-\r
-/**\r
- * Include Crypt_TripleDES\r
- */\r
-require_once('Crypt/TripleDES.php');\r
-\r
-/**\r
- * Include Crypt_RC4\r
- */\r
-require_once('Crypt/RC4.php');\r
-\r
-/**\r
- * Include Crypt_Random\r
- */\r
-require_once('Crypt/Random.php');\r
-\r
-/**#@+\r
- * Protocol Flags\r
- *\r
- * @access private\r
- */\r
-define('NET_SSH1_MSG_DISCONNECT',          1);\r
-define('NET_SSH1_SMSG_PUBLIC_KEY',         2);\r
-define('NET_SSH1_CMSG_SESSION_KEY',        3);\r
-define('NET_SSH1_CMSG_USER',               4);\r
-define('NET_SSH1_CMSG_AUTH_PASSWORD',      9);\r
-define('NET_SSH1_CMSG_REQUEST_PTY',       10);\r
-define('NET_SSH1_CMSG_EXEC_SHELL',        12);\r
-define('NET_SSH1_CMSG_EXEC_CMD',          13);\r
-define('NET_SSH1_SMSG_SUCCESS',           14);\r
-define('NET_SSH1_SMSG_FAILURE',           15);\r
-define('NET_SSH1_CMSG_STDIN_DATA',        16);\r
-define('NET_SSH1_SMSG_STDOUT_DATA',       17);\r
-define('NET_SSH1_SMSG_STDERR_DATA',       18);\r
-define('NET_SSH1_SMSG_EXITSTATUS',        20);\r
-define('NET_SSH1_CMSG_EXIT_CONFIRMATION', 33);\r
-/**#@-*/\r
-\r
-/**#@+\r
- * Encryption Methods\r
- *\r
- * @see Net_SSH1::getSupportedCiphers()\r
- * @access public\r
- */\r
-/**\r
- * No encryption\r
- *\r
- * Not supported.\r
- */\r
-define('NET_SSH1_CIPHER_NONE',       0);\r
-/**\r
- * IDEA in CFB mode\r
- *\r
- * Not supported.\r
- */\r
-define('NET_SSH1_CIPHER_IDEA',       1);\r
-/**\r
- * DES in CBC mode\r
- */\r
-define('NET_SSH1_CIPHER_DES',        2);\r
-/**\r
- * Triple-DES in CBC mode\r
- *\r
- * All implementations are required to support this\r
- */\r
-define('NET_SSH1_CIPHER_3DES',       3);\r
-/**\r
- * TRI's Simple Stream encryption CBC\r
- *\r
- * Not supported nor is it defined in the official SSH1 specs.  OpenSSH, however, does define it (see cipher.h),\r
- * although it doesn't use it (see cipher.c)\r
- */\r
-define('NET_SSH1_CIPHER_BROKEN_TSS', 4);\r
-/**\r
- * RC4\r
- *\r
- * Not supported.\r
- *\r
- * @internal According to the SSH1 specs:\r
- *\r
- *        "The first 16 bytes of the session key are used as the key for\r
- *         the server to client direction.  The remaining 16 bytes are used\r
- *         as the key for the client to server direction.  This gives\r
- *         independent 128-bit keys for each direction."\r
- *\r
- *     This library currently only supports encryption when the same key is being used for both directions.  This is\r
- *     because there's only one $crypto object.  Two could be added ($encrypt and $decrypt, perhaps).\r
- */\r
-define('NET_SSH1_CIPHER_RC4',        5);\r
-/**\r
- * Blowfish\r
- *\r
- * Not supported nor is it defined in the official SSH1 specs.  OpenSSH, however, defines it (see cipher.h) and\r
- * uses it (see cipher.c)\r
- */\r
-define('NET_SSH1_CIPHER_BLOWFISH',   6);\r
-/**#@-*/\r
-\r
-/**#@+\r
- * Authentication Methods\r
- *\r
- * @see Net_SSH1::getSupportedAuthentications()\r
- * @access public\r
- */\r
-/**\r
- * .rhosts or /etc/hosts.equiv\r
- */\r
-define('NET_SSH1_AUTH_RHOSTS',     1);\r
-/**\r
- * pure RSA authentication\r
- */\r
-define('NET_SSH1_AUTH_RSA',        2);\r
-/**\r
- * password authentication\r
- *\r
- * This is the only method that is supported by this library.\r
- */\r
-define('NET_SSH1_AUTH_PASSWORD',   3);\r
-/**\r
- * .rhosts with RSA host authentication\r
- */\r
-define('NET_SSH1_AUTH_RHOSTS_RSA', 4);\r
-/**#@-*/\r
-\r
-/**#@+\r
- * Terminal Modes\r
- *\r
- * @link http://3sp.com/content/developer/maverick-net/docs/Maverick.SSH.PseudoTerminalModesMembers.html\r
- * @access private\r
- */\r
-define('NET_SSH1_TTY_OP_END',  0);\r
-/**#@-*/\r
-\r
-/**\r
- * The Response Type\r
- *\r
- * @see Net_SSH1::_get_binary_packet()\r
- * @access private\r
- */\r
-define('NET_SSH1_RESPONSE_TYPE', 1);\r
-\r
-/**\r
- * The Response Data\r
- *\r
- * @see Net_SSH1::_get_binary_packet()\r
- * @access private\r
- */\r
-define('NET_SSH1_RESPONSE_DATA', 2);\r
-\r
-/**#@+\r
- * Execution Bitmap Masks\r
- *\r
- * @see Net_SSH1::bitmap\r
- * @access private\r
- */\r
-define('NET_SSH1_MASK_CONSTRUCTOR', 0x00000001);\r
-define('NET_SSH1_MASK_LOGIN',       0x00000002);\r
-define('NET_SSH1_MASK_SHELL',       0x00000004);\r
-/**#@-*/\r
-\r
-/**\r
- * Pure-PHP implementation of SSHv1.\r
- *\r
- * @author  Jim Wigginton <terrafrost@php.net>\r
- * @version 0.1.0\r
- * @access  public\r
- * @package Net_SSH1\r
- */\r
-class Net_SSH1 {\r
-    /**\r
-     * The SSH identifier\r
-     *\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $identifier = 'SSH-1.5-phpseclib';\r
-\r
-    /**\r
-     * The Socket Object\r
-     *\r
-     * @var Object\r
-     * @access private\r
-     */\r
-    var $fsock;\r
-\r
-    /**\r
-     * The cryptography object\r
-     *\r
-     * @var Object\r
-     * @access private\r
-     */\r
-    var $crypto = false;\r
-\r
-    /**\r
-     * Execution Bitmap\r
-     *\r
-     * The bits that are set reprsent functions that have been called already.  This is used to determine\r
-     * if a requisite function has been successfully executed.  If not, an error should be thrown.\r
-     *\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $bitmap = 0;\r
-\r
-    /**\r
-     * The Server Key Public Exponent\r
-     *\r
-     * Logged for debug purposes\r
-     *\r
-     * @see Net_SSH1::getServerKeyPublicExponent()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $server_key_public_exponent;\r
-\r
-    /**\r
-     * The Server Key Public Modulus\r
-     *\r
-     * Logged for debug purposes\r
-     *\r
-     * @see Net_SSH1::getServerKeyPublicModulus()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $server_key_public_modulus;\r
-\r
-    /**\r
-     * The Host Key Public Exponent\r
-     *\r
-     * Logged for debug purposes\r
-     *\r
-     * @see Net_SSH1::getHostKeyPublicExponent()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $host_key_public_exponent;\r
-\r
-    /**\r
-     * The Host Key Public Modulus\r
-     *\r
-     * Logged for debug purposes\r
-     *\r
-     * @see Net_SSH1::getHostKeyPublicModulus()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $host_key_public_modulus;\r
-\r
-    /**\r
-     * Supported Ciphers\r
-     *\r
-     * Logged for debug purposes\r
-     *\r
-     * @see Net_SSH1::getSupportedCiphers()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $supported_ciphers = array(\r
-        NET_SSH1_CIPHER_NONE       => 'No encryption',\r
-        NET_SSH1_CIPHER_IDEA       => 'IDEA in CFB mode',\r
-        NET_SSH1_CIPHER_DES        => 'DES in CBC mode',\r
-        NET_SSH1_CIPHER_3DES       => 'Triple-DES in CBC mode',\r
-        NET_SSH1_CIPHER_BROKEN_TSS => 'TRI\'s Simple Stream encryption CBC',\r
-        NET_SSH1_CIPHER_RC4        => 'RC4',\r
-        NET_SSH1_CIPHER_BLOWFISH   => 'Blowfish'\r
-    );\r
-\r
-    /**\r
-     * Supported Authentications\r
-     *\r
-     * Logged for debug purposes\r
-     *\r
-     * @see Net_SSH1::getSupportedAuthentications()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $supported_authentications = array(\r
-        NET_SSH1_AUTH_RHOSTS     => '.rhosts or /etc/hosts.equiv',\r
-        NET_SSH1_AUTH_RSA        => 'pure RSA authentication',\r
-        NET_SSH1_AUTH_PASSWORD   => 'password authentication',\r
-        NET_SSH1_AUTH_RHOSTS_RSA => '.rhosts with RSA host authentication'\r
-    );\r
-\r
-    /**\r
-     * Server Identification\r
-     *\r
-     * @see Net_SSH1::getServerIdentification()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $server_identification = '';\r
-\r
-    /**\r
-     * Default Constructor.\r
-     *\r
-     * Connects to an SSHv1 server\r
-     *\r
-     * @param String $host\r
-     * @param optional Integer $port\r
-     * @param optional Integer $timeout\r
-     * @param optional Integer $cipher\r
-     * @return Net_SSH1\r
-     * @access public\r
-     */\r
-    function Net_SSH1($host, $port = 22, $timeout = 10, $cipher = NET_SSH1_CIPHER_3DES)\r
-    {\r
-        $this->fsock = @fsockopen($host, $port, $errno, $errstr, $timeout);\r
-        if (!$this->fsock) {\r
-            user_error(rtrim("Cannot connect to $host. Error $errno. $errstr"), E_USER_NOTICE);\r
-            return;\r
-        }\r
-\r
-        $this->server_identification = $init_line = fgets($this->fsock, 255);\r
-        if (!preg_match('#SSH-([0-9\.]+)-(.+)#', $init_line, $parts)) {\r
-            user_error('Can only connect to SSH servers', E_USER_NOTICE);\r
-            return;\r
-        }\r
-        if ($parts[1][0] != 1) {\r
-            user_error("Cannot connect to SSH $parts[1] servers", E_USER_NOTICE);\r
-            return;\r
-        }\r
-\r
-        fputs($this->fsock, $this->identifier."\r\n");\r
-\r
-        $response = $this->_get_binary_packet();\r
-        if ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_PUBLIC_KEY) {\r
-            user_error('Expected SSH_SMSG_PUBLIC_KEY', E_USER_NOTICE);\r
-            return;\r
-        }\r
-\r
-        $anti_spoofing_cookie = $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 8);\r
-\r
-        $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 4);\r
-\r
-        $temp = unpack('nlen', $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 2));\r
-        $server_key_public_exponent = new Math_BigInteger($this->_string_shift($response[NET_SSH1_RESPONSE_DATA], ceil($temp['len'] / 8)), 256);\r
-        $this->server_key_public_exponent = $server_key_public_exponent;\r
-\r
-        $temp = unpack('nlen', $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 2));\r
-        $server_key_public_modulus = new Math_BigInteger($this->_string_shift($response[NET_SSH1_RESPONSE_DATA], ceil($temp['len'] / 8)), 256);\r
-        $this->server_key_public_modulus = $server_key_public_modulus;\r
-\r
-        $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 4);\r
-\r
-        $temp = unpack('nlen', $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 2));\r
-        $host_key_public_exponent = new Math_BigInteger($this->_string_shift($response[NET_SSH1_RESPONSE_DATA], ceil($temp['len'] / 8)), 256);\r
-        $this->host_key_public_exponent = $host_key_public_exponent;\r
-\r
-        $temp = unpack('nlen', $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 2));\r
-        $host_key_public_modulus = new Math_BigInteger($this->_string_shift($response[NET_SSH1_RESPONSE_DATA], ceil($temp['len'] / 8)), 256);\r
-        $this->host_key_public_modulus = $host_key_public_modulus;\r
-\r
-        $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 4);\r
-\r
-        // get a list of the supported ciphers\r
-        extract(unpack('Nsupported_ciphers_mask', $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 4)));\r
-        foreach ($this->supported_ciphers as $mask=>$name) {\r
-            if (($supported_ciphers_mask & (1 << $mask)) == 0) {\r
-                unset($this->supported_ciphers[$mask]);\r
-            }\r
-        }\r
-\r
-        // get a list of the supported authentications\r
-        extract(unpack('Nsupported_authentications_mask', $this->_string_shift($response[NET_SSH1_RESPONSE_DATA], 4)));\r
-        foreach ($this->supported_authentications as $mask=>$name) {\r
-            if (($supported_authentications_mask & (1 << $mask)) == 0) {\r
-                unset($this->supported_authentications[$mask]);\r
-            }\r
-        }\r
-\r
-        $session_id = pack('H*', md5($host_key_public_modulus->toBytes() . $server_key_public_modulus->toBytes() . $anti_spoofing_cookie));\r
-\r
-        $session_key = '';\r
-        for ($i = 0; $i < 32; $i++) {\r
-            $session_key.= chr(crypt_random(0, 255));\r
-        }\r
-        $double_encrypted_session_key = $session_key ^ str_pad($session_id, 32, chr(0));\r
-\r
-        if ($server_key_public_modulus->compare($host_key_public_modulus) < 0) {\r
-            $double_encrypted_session_key = $this->_rsa_crypt(\r
-                $double_encrypted_session_key,\r
-                array(\r
-                    $server_key_public_exponent,\r
-                    $server_key_public_modulus\r
-                )\r
-            );\r
-            $double_encrypted_session_key = $this->_rsa_crypt(\r
-                $double_encrypted_session_key,\r
-                array(\r
-                    $host_key_public_exponent,\r
-                    $host_key_public_modulus\r
-                )\r
-            );\r
-        } else {\r
-            $double_encrypted_session_key = $this->_rsa_crypt(\r
-                $double_encrypted_session_key,\r
-                array(\r
-                    $host_key_public_exponent,\r
-                    $host_key_public_modulus\r
-                )\r
-            );\r
-            $double_encrypted_session_key = $this->_rsa_crypt(\r
-                $double_encrypted_session_key,\r
-                array(\r
-                    $server_key_public_exponent,\r
-                    $server_key_public_modulus\r
-                )\r
-            );\r
-        }\r
-\r
-        $cipher = isset($this->supported_ciphers[$cipher]) ? $cipher : NET_SSH1_CIPHER_3DES;\r
-        $data = pack('C2a*na*N', NET_SSH1_CMSG_SESSION_KEY, $cipher, $anti_spoofing_cookie, 8 * strlen($double_encrypted_session_key), $double_encrypted_session_key, 0);\r
-\r
-        if (!$this->_send_binary_packet($data)) {\r
-            user_error('Error sending SSH_CMSG_SESSION_KEY', E_USER_NOTICE);\r
-            return;\r
-        }\r
-\r
-        switch ($cipher) {\r
-            //case NET_SSH1_CIPHER_NONE:\r
-            //    $this->crypto = new Crypt_Null();\r
-            //    break;\r
-            case NET_SSH1_CIPHER_DES:\r
-                $this->crypto = new Crypt_DES();\r
-                $this->crypto->disablePadding();\r
-                $this->crypto->enableContinuousBuffer();\r
-                $this->crypto->setKey(substr($session_key, 0,  8));\r
-                break;\r
-            case NET_SSH1_CIPHER_3DES:\r
-                $this->crypto = new Crypt_TripleDES(CRYPT_DES_MODE_3CBC);\r
-                $this->crypto->disablePadding();\r
-                $this->crypto->enableContinuousBuffer();\r
-                $this->crypto->setKey(substr($session_key, 0, 24));\r
-                break;\r
-            //case NET_SSH1_CIPHER_RC4:\r
-            //    $this->crypto = new Crypt_RC4();\r
-            //    $this->crypto->enableContinuousBuffer();\r
-            //    $this->crypto->setKey(substr($session_key, 0,  16));\r
-            //    break;\r
-        }\r
-\r
-        $response = $this->_get_binary_packet();\r
-\r
-        if ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {\r
-            user_error('Expected SSH_SMSG_SUCCESS', E_USER_NOTICE);\r
-            return;\r
-        }\r
-\r
-        $this->bitmap = NET_SSH1_MASK_CONSTRUCTOR;\r
-    }\r
-\r
-    /**\r
-     * Login\r
-     *\r
-     * @param String $username\r
-     * @param optional String $password\r
-     * @return Boolean\r
-     * @access public\r
-     */\r
-    function login($username, $password = '')\r
-    {\r
-        if (!($this->bitmap & NET_SSH1_MASK_CONSTRUCTOR)) {\r
-            return false;\r
-        }\r
-\r
-        $data = pack('CNa*', NET_SSH1_CMSG_USER, strlen($username), $username);\r
-\r
-        if (!$this->_send_binary_packet($data)) {\r
-            user_error('Error sending SSH_CMSG_USER', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_binary_packet();\r
-\r
-        if ($response[NET_SSH1_RESPONSE_TYPE] == NET_SSH1_SMSG_SUCCESS) {\r
-            $this->bitmap |= NET_SSH1_MASK_LOGIN;\r
-            return true;\r
-        } else if ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_FAILURE) {\r
-            user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        $data = pack('CNa*', NET_SSH1_CMSG_AUTH_PASSWORD, strlen($password), $password);\r
-\r
-        if (!$this->_send_binary_packet($data)) {\r
-            user_error('Error sending SSH_CMSG_AUTH_PASSWORD', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_binary_packet();\r
-\r
-        if ($response[NET_SSH1_RESPONSE_TYPE] == NET_SSH1_SMSG_SUCCESS) {\r
-            $this->bitmap |= NET_SSH1_MASK_LOGIN;\r
-            return true;\r
-        } else if ($response[NET_SSH1_RESPONSE_TYPE] == NET_SSH1_SMSG_FAILURE) {\r
-            return false;\r
-        } else {\r
-            user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Executes a command on a non-interactive shell, returns the output, and quits.\r
-     *\r
-     * An SSH1 server will close the connection after a command has been executed on a non-interactive shell.  SSH2\r
-     * servers don't, however, this isn't an SSH2 client.  The way this works, on the server, is by initiating a\r
-     * shell with the -s option, as discussed in the following links:\r
-     *\r
-     * {@link http://www.faqs.org/docs/bashman/bashref_65.html http://www.faqs.org/docs/bashman/bashref_65.html}\r
-     * {@link http://www.faqs.org/docs/bashman/bashref_62.html http://www.faqs.org/docs/bashman/bashref_62.html}\r
-     *\r
-     * To execute further commands, a new Net_SSH1 object will need to be created.\r
-     *\r
-     * Returns false on failure and the output, otherwise.\r
-     *\r
-     * @see Net_SSH1::interactiveRead()\r
-     * @see Net_SSH1::interactiveWrite()\r
-     * @param String $cmd\r
-     * @return mixed\r
-     * @access public\r
-     */\r
-    function exec($cmd)\r
-    {\r
-        if (!($this->bitmap & NET_SSH1_MASK_LOGIN)) {\r
-            user_error('Operation disallowed prior to login()', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        // connect using the sample parameters in protocol-1.5.txt.\r
-        // according to wikipedia.org's entry on text terminals, "the fundamental type of application running on a text\r
-        // terminal is a command line interpreter or shell".  thus, opening a terminal session to run the shell.\r
-        $data = pack('CNa*N4C', NET_SSH1_CMSG_REQUEST_PTY, strlen('vt100'), 'vt100', 24, 80, 0, 0, NET_SSH1_TTY_OP_END);\r
-\r
-        if (!$this->_send_binary_packet($data)) {\r
-            user_error('Error sending SSH_CMSG_REQUEST_PTY', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_binary_packet();\r
-\r
-        if ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {\r
-            user_error('Expected SSH_SMSG_SUCCESS', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        $data = pack('CNa*', NET_SSH1_CMSG_EXEC_CMD, strlen($cmd), $cmd);\r
-\r
-        if (!$this->_send_binary_packet($data)) {\r
-            user_error('Error sending SSH_CMSG_EXEC_CMD', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        $output = '';\r
-        $response = $this->_get_binary_packet();\r
-\r
-        do {\r
-            $output.= substr($response[NET_SSH1_RESPONSE_DATA], 4);\r
-            $response = $this->_get_binary_packet();\r
-        } while ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_EXITSTATUS);\r
-\r
-        $data = pack('C', NET_SSH1_CMSG_EXIT_CONFIRMATION);\r
-\r
-        // i don't think it's really all that important if this packet gets sent or not.\r
-        $this->_send_binary_packet($data);\r
-\r
-        fclose($this->fsock);\r
-\r
-        // reset the execution bitmap - a new Net_SSH1 object needs to be created.\r
-        $this->bitmap = 0;\r
-\r
-        return $output;\r
-    }\r
-\r
-    /**\r
-     * Creates an interactive shell\r
-     *\r
-     * @see Net_SSH1::interactiveRead()\r
-     * @see Net_SSH1::interactiveWrite()\r
-     * @return Boolean\r
-     * @access private\r
-     */\r
-    function _initShell()\r
-    {\r
-        $data = pack('CNa*N4C', NET_SSH1_CMSG_REQUEST_PTY, strlen('vt100'), 'vt100', 24, 80, 0, 0, NET_SSH1_TTY_OP_END);\r
-\r
-        if (!$this->_send_binary_packet($data)) {\r
-            user_error('Error sending SSH_CMSG_REQUEST_PTY', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_binary_packet();\r
-\r
-        if ($response[NET_SSH1_RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {\r
-            user_error('Expected SSH_SMSG_SUCCESS', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        $data = pack('C', NET_SSH1_CMSG_EXEC_SHELL);\r
-\r
-        if (!$this->_send_binary_packet($data)) {\r
-            user_error('Error sending SSH_CMSG_EXEC_SHELL', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        $this->bitmap |= NET_SSH1_MASK_SHELL;\r
-\r
-        //stream_set_blocking($this->fsock, 0);\r
-\r
-        return true;\r
-    }\r
-\r
-    /**\r
-     * Inputs a command into an interactive shell.\r
-     *\r
-     * @see Net_SSH1::interactiveRead()\r
-     * @param String $cmd\r
-     * @return Boolean\r
-     * @access public\r
-     */\r
-    function interactiveWrite($cmd)\r
-    {\r
-        if (!($this->bitmap & NET_SSH1_MASK_LOGIN)) {\r
-            user_error('Operation disallowed prior to login()', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        if (!($this->bitmap & NET_SSH1_MASK_SHELL) && !$this->_initShell()) {\r
-            user_error('Unable to initiate an interactive shell session', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        $data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($cmd), $cmd);\r
-\r
-        if (!$this->_send_binary_packet($data)) {\r
-            user_error('Error sending SSH_CMSG_STDIN', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        return true;\r
-    }\r
-\r
-    /**\r
-     * Reads the output of an interactive shell.\r
-     *\r
-     * Requires PHP 4.3.0 or later due to the use of the stream_select() function.  If you see crap, \r
-     * you're seeing ANSI escape codes.  According to\r
-     * {@link http://support.microsoft.com/kb/101875 How to Enable ANSI.SYS in a Command Window}, "Windows NT\r
-     * does not support ANSI escape sequences in Win32 Console applications", so if you're a Windows user,\r
-     * there's not going to be much recourse.\r
-     *\r
-     * @see Net_SSH1::interactiveRead()\r
-     * @return String\r
-     * @access public\r
-     */\r
-    function interactiveRead()\r
-    {\r
-        if (!($this->bitmap & NET_SSH1_MASK_LOGIN)) {\r
-            user_error('Operation disallowed prior to login()', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        if (!($this->bitmap & NET_SSH1_MASK_SHELL) && !$this->_initShell()) {\r
-            user_error('Unable to initiate an interactive shell session', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        $read = array($this->fsock);\r
-        $write = $except = null;\r
-        if (stream_select($read, $write, $except, 0)) {\r
-            $response = $this->_get_binary_packet();\r
-            return substr($response[NET_SSH1_RESPONSE_DATA], 4);\r
-        } else {\r
-            return '';\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Disconnect\r
-     *\r
-     * @access public\r
-     */\r
-    function disconnect()\r
-    {\r
-        $this->_disconnect();\r
-    }\r
-\r
-    /**\r
-     * Destructor.\r
-     *\r
-     * Will be called, automatically, if you're supporting just PHP5.  If you're supporting PHP4, you'll need to call\r
-     * disconnect().\r
-     *\r
-     * @access public\r
-     */\r
-    function __destruct()\r
-    {\r
-        $this->_disconnect();\r
-    }\r
-\r
-    /**\r
-     * Disconnect\r
-     *\r
-     * @param String $msg\r
-     * @access private\r
-     */\r
-    function _disconnect($msg = 'Client Quit')\r
-    {\r
-        if ($this->bitmap) {\r
-            $data = pack('CNa*', NET_SSH1_MSG_DISCONNECT, strlen($msg), $msg);\r
-            $this->_send_binary_packet($data);\r
-            fclose($this->fsock);\r
-            $this->bitmap = 0;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Gets Binary Packets\r
-     *\r
-     * See 'The Binary Packet Protocol' of protocol-1.5.txt for more info.\r
-     *\r
-     * Also, this function could be improved upon by adding detection for the following exploit:\r
-     * http://www.securiteam.com/securitynews/5LP042K3FY.html\r
-     *\r
-     * @see Net_SSH1::_send_binary_packet()\r
-     * @return Array\r
-     * @access private\r
-     */\r
-    function _get_binary_packet()\r
-    {\r
-        if (feof($this->fsock)) {\r
-            //user_error('connection closed prematurely', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        $temp = unpack('Nlength', fread($this->fsock, 4));\r
-\r
-        $padding_length = 8 - ($temp['length'] & 7);\r
-        $length = $temp['length'] + $padding_length;\r
-\r
-        $raw = fread($this->fsock, $length);\r
-\r
-        if ($this->crypto !== false) {\r
-            $raw = $this->crypto->decrypt($raw);\r
-        }\r
-\r
-        $padding = substr($raw, 0, $padding_length);\r
-        $type = $raw[$padding_length];\r
-        $data = substr($raw, $padding_length + 1, -4);\r
-\r
-        $temp = unpack('Ncrc', substr($raw, -4));\r
-\r
-        //if ( $temp['crc'] != $this->_crc($padding . $type . $data) ) {\r
-        //    user_error('Bad CRC in packet from server', E_USER_NOTICE);\r
-        //    return false;\r
-        //}\r
-\r
-        return array(\r
-            NET_SSH1_RESPONSE_TYPE => ord($type),\r
-            NET_SSH1_RESPONSE_DATA => $data\r
-        );\r
-    }\r
-\r
-    /**\r
-     * Sends Binary Packets\r
-     *\r
-     * Returns true on success, false on failure.\r
-     *\r
-     * @see Net_SSH1::_get_binary_packet()\r
-     * @param String $data\r
-     * @return Boolean\r
-     * @access private\r
-     */\r
-    function _send_binary_packet($data) {\r
-        if (feof($this->fsock)) {\r
-            //user_error('connection closed prematurely', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        $length = strlen($data) + 4;\r
-\r
-        $padding_length = 8 - ($length & 7);\r
-        $padding = '';\r
-        for ($i = 0; $i < $padding_length; $i++) {\r
-            $padding.= chr(crypt_random(0, 255));\r
-        }\r
-\r
-        $data = $padding . $data;\r
-        $data.= pack('N', $this->_crc($data));\r
-\r
-        if ($this->crypto !== false) {\r
-            $data = $this->crypto->encrypt($data);\r
-        }\r
-\r
-        $packet = pack('Na*', $length, $data);\r
-\r
-        return strlen($packet) == fputs($this->fsock, $packet);\r
-    }\r
-\r
-    /**\r
-     * Cyclic Redundancy Check (CRC)\r
-     *\r
-     * PHP's crc32 function is implemented slightly differently than the one that SSH v1 uses, so\r
-     * we've reimplemented it. A more detailed discussion of the differences can be found after\r
-     * $crc_lookup_table's initialization.\r
-     *\r
-     * @see Net_SSH1::_get_binary_packet()\r
-     * @see Net_SSH1::_send_binary_packet()\r
-     * @param String $data\r
-     * @return Integer\r
-     * @access private\r
-     */\r
-    function _crc($data)\r
-    {\r
-        static $crc_lookup_table = array(\r
-            0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,\r
-            0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,\r
-            0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,\r
-            0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,\r
-            0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,\r
-            0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,\r
-            0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,\r
-            0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,\r
-            0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,\r
-            0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,\r
-            0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,\r
-            0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,\r
-            0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,\r
-            0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,\r
-            0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,\r
-            0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,\r
-            0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,\r
-            0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,\r
-            0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,\r
-            0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,\r
-            0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,\r
-            0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,\r
-            0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,\r
-            0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,\r
-            0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,\r
-            0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,\r
-            0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,\r
-            0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,\r
-            0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,\r
-            0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,\r
-            0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,\r
-            0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,\r
-            0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,\r
-            0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,\r
-            0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,\r
-            0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,\r
-            0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,\r
-            0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,\r
-            0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,\r
-            0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,\r
-            0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,\r
-            0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,\r
-            0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,\r
-            0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,\r
-            0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,\r
-            0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,\r
-            0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,\r
-            0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,\r
-            0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,\r
-            0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,\r
-            0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,\r
-            0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,\r
-            0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,\r
-            0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,\r
-            0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,\r
-            0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,\r
-            0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,\r
-            0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,\r
-            0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,\r
-            0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,\r
-            0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,\r
-            0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,\r
-            0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,\r
-            0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D\r
-        );\r
-\r
-        // For this function to yield the same output as PHP's crc32 function, $crc would have to be\r
-        // set to 0xFFFFFFFF, initially - not 0x00000000 as it currently is.\r
-        $crc = 0x00000000;\r
-        $length = strlen($data);\r
-\r
-        for ($i=0;$i<$length;$i++) {\r
-            // We AND $crc >> 8 with 0x00FFFFFF because we want the eight newly added bits to all\r
-            // be zero.  PHP, unfortunately, doesn't always do this.  0x80000000 >> 8, as an example,\r
-            // yields 0xFF800000 - not 0x00800000.  The following link elaborates:\r
-            // http://www.php.net/manual/en/language.operators.bitwise.php#57281\r
-            $crc = (($crc >> 8) & 0x00FFFFFF) ^ $crc_lookup_table[($crc & 0xFF) ^ ord($data[$i])];\r
-        }\r
-\r
-        // In addition to having to set $crc to 0xFFFFFFFF, initially, the return value must be XOR'd with\r
-        // 0xFFFFFFFF for this function to return the same thing that PHP's crc32 function would.\r
-        return $crc;\r
-    }\r
-\r
-    /**\r
-     * String Shift\r
-     *\r
-     * Inspired by array_shift\r
-     *\r
-     * @param String $string\r
-     * @param optional Integer $index\r
-     * @return String\r
-     * @access private\r
-     */\r
-    function _string_shift(&$string, $index = 1)\r
-    {\r
-        $substr = substr($string, 0, $index);\r
-        $string = substr($string, $index);\r
-        return $substr;\r
-    }\r
-\r
-    /**\r
-     * RSA Encrypt\r
-     *\r
-     * Returns mod(pow($m, $e), $n), where $n should be the product of two (large) primes $p and $q and where $e\r
-     * should be a number with the property that gcd($e, ($p - 1) * ($q - 1)) == 1.  Could just make anything that\r
-     * calls this call modexp, instead, but I think this makes things clearer, maybe...\r
-     *\r
-     * @see Net_SSH1::Net_SSH1()\r
-     * @param Math_BigInteger $m\r
-     * @param Array $key\r
-     * @return Math_BigInteger\r
-     * @access private\r
-     */\r
-    function _rsa_crypt($m, $key)\r
-    {\r
-        /*\r
-        if (!class_exists('Crypt_RSA')) {\r
-            require_once('Crypt/RSA.php');\r
-        }\r
-\r
-        $rsa = new Crypt_RSA();\r
-        $rsa->loadKey($key, CRYPT_RSA_PUBLIC_FORMAT_RAW);\r
-        $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);\r
-        return $rsa->encrypt($m);\r
-        */\r
-\r
-        // To quote from protocol-1.5.txt:\r
-        // The most significant byte (which is only partial as the value must be\r
-        // less than the public modulus, which is never a power of two) is zero.\r
-        //\r
-        // The next byte contains the value 2 (which stands for public-key\r
-        // encrypted data in the PKCS standard [PKCS#1]).  Then, there are non-\r
-        // zero random bytes to fill any unused space, a zero byte, and the data\r
-        // to be encrypted in the least significant bytes, the last byte of the\r
-        // data in the least significant byte.\r
-\r
-        // Presumably the part of PKCS#1 they're refering to is "Section 7.2.1 Encryption Operation",\r
-        // under "7.2 RSAES-PKCS1-v1.5" and "7 Encryption schemes" of the following URL:\r
-        // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf\r
-        $temp = chr(0) . chr(2);\r
-        $modulus = $key[1]->toBytes();\r
-        $length = strlen($modulus) - strlen($m) - 3;\r
-        for ($i = 0; $i < $length; $i++) {\r
-            $temp.= chr(crypt_random(1, 255));\r
-        }\r
-        $temp.= chr(0) . $m;\r
-\r
-        $m = new Math_BigInteger($temp, 256);\r
-        $m = $m->modPow($key[0], $key[1]);\r
-\r
-        return $m->toBytes();\r
-    }\r
-\r
-    /**\r
-     * Return the server key public exponent\r
-     *\r
-     * Returns, by default, the base-10 representation.  If $raw_output is set to true, returns, instead,\r
-     * the raw bytes.  This behavior is similar to PHP's md5() function.\r
-     *\r
-     * @param optional Boolean $raw_output\r
-     * @return String\r
-     * @access public\r
-     */\r
-    function getServerKeyPublicExponent($raw_output = false)\r
-    {\r
-        return $raw_output ? $this->server_key_public_exponent->toBytes() : $this->server_key_public_exponent->toString();\r
-    }\r
-\r
-    /**\r
-     * Return the server key public modulus\r
-     *\r
-     * Returns, by default, the base-10 representation.  If $raw_output is set to true, returns, instead,\r
-     * the raw bytes.  This behavior is similar to PHP's md5() function.\r
-     *\r
-     * @param optional Boolean $raw_output\r
-     * @return String\r
-     * @access public\r
-     */\r
-    function getServerKeyPublicModulus($raw_output = false)\r
-    {\r
-        return $raw_output ? $this->server_key_public_modulus->toBytes() : $this->server_key_public_modulus->toString();\r
-    }\r
-\r
-    /**\r
-     * Return the host key public exponent\r
-     *\r
-     * Returns, by default, the base-10 representation.  If $raw_output is set to true, returns, instead,\r
-     * the raw bytes.  This behavior is similar to PHP's md5() function.\r
-     *\r
-     * @param optional Boolean $raw_output\r
-     * @return String\r
-     * @access public\r
-     */\r
-    function getHostKeyPublicExponent($raw_output = false)\r
-    {\r
-        return $raw_output ? $this->host_key_public_exponent->toBytes() : $this->host_key_public_exponent->toString();\r
-    }\r
-\r
-    /**\r
-     * Return the host key public modulus\r
-     *\r
-     * Returns, by default, the base-10 representation.  If $raw_output is set to true, returns, instead,\r
-     * the raw bytes.  This behavior is similar to PHP's md5() function.\r
-     *\r
-     * @param optional Boolean $raw_output\r
-     * @return String\r
-     * @access public\r
-     */\r
-    function getHostKeyPublicModulus($raw_output = false)\r
-    {\r
-        return $raw_output ? $this->host_key_public_modulus->toBytes() : $this->host_key_public_modulus->toString();\r
-    }\r
-\r
-    /**\r
-     * Return a list of ciphers supported by SSH1 server.\r
-     *\r
-     * Just because a cipher is supported by an SSH1 server doesn't mean it's supported by this library. If $raw_output\r
-     * is set to true, returns, instead, an array of constants.  ie. instead of array('Triple-DES in CBC mode'), you'll\r
-     * get array(NET_SSH1_CIPHER_3DES).\r
-     *\r
-     * @param optional Boolean $raw_output\r
-     * @return Array\r
-     * @access public\r
-     */\r
-    function getSupportedCiphers($raw_output = false)\r
-    {\r
-        return $raw_output ? array_keys($this->supported_ciphers) : array_values($this->supported_ciphers);\r
-    }\r
-\r
-    /**\r
-     * Return a list of authentications supported by SSH1 server.\r
-     *\r
-     * Just because a cipher is supported by an SSH1 server doesn't mean it's supported by this library. If $raw_output\r
-     * is set to true, returns, instead, an array of constants.  ie. instead of array('password authentication'), you'll\r
-     * get array(NET_SSH1_AUTH_PASSWORD).\r
-     *\r
-     * @param optional Boolean $raw_output\r
-     * @return Array\r
-     * @access public\r
-     */\r
-    function getSupportedAuthentications($raw_output = false)\r
-    {\r
-        return $raw_output ? array_keys($this->supported_authentications) : array_values($this->supported_authentications);\r
-    }\r
-\r
-    /**\r
-     * Return the server identification.\r
-     *\r
-     * @return String\r
-     * @access public\r
-     */\r
-    function getServerIdentification()\r
-    {\r
-        return rtrim($this->server_identification);\r
-    }\r
-}\r
-?>
\ No newline at end of file
diff --git a/library/phpsec/Net/SSH2.php b/library/phpsec/Net/SSH2.php
deleted file mode 100644 (file)
index aa9f6db..0000000
+++ /dev/null
@@ -1,2302 +0,0 @@
-<?php\r
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */\r
-\r
-/**\r
- * Pure-PHP implementation of SSHv2.\r
- *\r
- * PHP versions 4 and 5\r
- *\r
- * Here are some examples of how to use this library:\r
- * <code>\r
- * <?php\r
- *    include('Net/SSH2.php');\r
- *\r
- *    $ssh = new Net_SSH2('www.domain.tld');\r
- *    if (!$ssh->login('username', 'password')) {\r
- *        exit('Login Failed');\r
- *    }\r
- *\r
- *    echo $ssh->exec('pwd');\r
- *    echo $ssh->exec('ls -la');\r
- * ?>\r
- * </code>\r
- *\r
- * <code>\r
- * <?php\r
- *    include('Crypt/RSA.php');\r
- *    include('Net/SSH2.php');\r
- *\r
- *    $key = new Crypt_RSA();\r
- *    //$key->setPassword('whatever');\r
- *    $key->loadKey(file_get_contents('privatekey'));\r
- *\r
- *    $ssh = new Net_SSH2('www.domain.tld');\r
- *    if (!$ssh->login('username', $key)) {\r
- *        exit('Login Failed');\r
- *    }\r
- *\r
- *    echo $ssh->exec('pwd');\r
- *    echo $ssh->exec('ls -la');\r
- * ?>\r
- * </code>\r
- *\r
- * LICENSE: This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,\r
- * MA  02111-1307  USA\r
- *\r
- * @category   Net\r
- * @package    Net_SSH2\r
- * @author     Jim Wigginton <terrafrost@php.net>\r
- * @copyright  MMVII Jim Wigginton\r
- * @license    http://www.gnu.org/licenses/lgpl.txt\r
- * @version    $Id: SSH2.php,v 1.46 2010/04/27 21:29:36 terrafrost Exp $\r
- * @link       http://phpseclib.sourceforge.net\r
- */\r
-\r
-/**\r
- * Include Math_BigInteger\r
- *\r
- * Used to do Diffie-Hellman key exchange and DSA/RSA signature verification.\r
- */\r
-require_once('Math/BigInteger.php');\r
-\r
-/**\r
- * Include Crypt_Random\r
- */\r
-require_once('Crypt/Random.php');\r
-\r
-/**\r
- * Include Crypt_Hash\r
- */\r
-require_once('Crypt/Hash.php');\r
-\r
-/**\r
- * Include Crypt_TripleDES\r
- */\r
-require_once('Crypt/TripleDES.php');\r
-\r
-/**\r
- * Include Crypt_RC4\r
- */\r
-require_once('Crypt/RC4.php');\r
-\r
-/**\r
- * Include Crypt_AES\r
- */\r
-require_once('Crypt/AES.php');\r
-\r
-/**#@+\r
- * Execution Bitmap Masks\r
- *\r
- * @see Net_SSH2::bitmap\r
- * @access private\r
- */\r
-define('NET_SSH2_MASK_CONSTRUCTOR', 0x00000001);\r
-define('NET_SSH2_MASK_LOGIN',       0x00000002);\r
-/**#@-*/\r
-\r
-/**#@+\r
- * Channel constants\r
- *\r
- * RFC4254 refers not to client and server channels but rather to sender and recipient channels.  we don't refer\r
- * to them in that way because RFC4254 toggles the meaning. the client sends a SSH_MSG_CHANNEL_OPEN message with\r
- * a sender channel and the server sends a SSH_MSG_CHANNEL_OPEN_CONFIRMATION in response, with a sender and a\r
- * recepient channel.  at first glance, you might conclude that SSH_MSG_CHANNEL_OPEN_CONFIRMATION's sender channel\r
- * would be the same thing as SSH_MSG_CHANNEL_OPEN's sender channel, but it's not, per this snipet:\r
- *     The 'recipient channel' is the channel number given in the original\r
- *     open request, and 'sender channel' is the channel number allocated by\r
- *     the other side.\r
- *\r
- * @see Net_SSH2::_send_channel_packet()\r
- * @see Net_SSH2::_get_channel_packet()\r
- * @access private\r
- */\r
-define('NET_SSH2_CHANNEL_EXEC', 0); // PuTTy uses 0x100\r
-/**#@-*/\r
-\r
-/**#@+\r
- * @access public\r
- * @see Net_SSH2::getLog()\r
- */\r
-/**\r
- * Returns the message numbers\r
- */\r
-define('NET_SSH2_LOG_SIMPLE',  1);\r
-/**\r
- * Returns the message content\r
- */\r
-define('NET_SSH2_LOG_COMPLEX', 2);\r
-/**#@-*/\r
-\r
-/**\r
- * Pure-PHP implementation of SSHv2.\r
- *\r
- * @author  Jim Wigginton <terrafrost@php.net>\r
- * @version 0.1.0\r
- * @access  public\r
- * @package Net_SSH2\r
- */\r
-class Net_SSH2 {\r
-    /**\r
-     * The SSH identifier\r
-     *\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $identifier = 'SSH-2.0-phpseclib_0.2';\r
-\r
-    /**\r
-     * The Socket Object\r
-     *\r
-     * @var Object\r
-     * @access private\r
-     */\r
-    var $fsock;\r
-\r
-    /**\r
-     * Execution Bitmap\r
-     *\r
-     * The bits that are set reprsent functions that have been called already.  This is used to determine\r
-     * if a requisite function has been successfully executed.  If not, an error should be thrown.\r
-     *\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $bitmap = 0;\r
-\r
-    /**\r
-     * Error information\r
-     *\r
-     * @see Net_SSH2::getErrors()\r
-     * @see Net_SSH2::getLastError()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $errors = array();\r
-\r
-    /**\r
-     * Server Identifier\r
-     *\r
-     * @see Net_SSH2::getServerIdentification()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $server_identifier = '';\r
-\r
-    /**\r
-     * Key Exchange Algorithms\r
-     *\r
-     * @see Net_SSH2::getKexAlgorithims()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $kex_algorithms;\r
-\r
-    /**\r
-     * Server Host Key Algorithms\r
-     *\r
-     * @see Net_SSH2::getServerHostKeyAlgorithms()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $server_host_key_algorithms;\r
-\r
-    /**\r
-     * Encryption Algorithms: Client to Server\r
-     *\r
-     * @see Net_SSH2::getEncryptionAlgorithmsClient2Server()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $encryption_algorithms_client_to_server;\r
-\r
-    /**\r
-     * Encryption Algorithms: Server to Client\r
-     *\r
-     * @see Net_SSH2::getEncryptionAlgorithmsServer2Client()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $encryption_algorithms_server_to_client;\r
-\r
-    /**\r
-     * MAC Algorithms: Client to Server\r
-     *\r
-     * @see Net_SSH2::getMACAlgorithmsClient2Server()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $mac_algorithms_client_to_server;\r
-\r
-    /**\r
-     * MAC Algorithms: Server to Client\r
-     *\r
-     * @see Net_SSH2::getMACAlgorithmsServer2Client()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $mac_algorithms_server_to_client;\r
-\r
-    /**\r
-     * Compression Algorithms: Client to Server\r
-     *\r
-     * @see Net_SSH2::getCompressionAlgorithmsClient2Server()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $compression_algorithms_client_to_server;\r
-\r
-    /**\r
-     * Compression Algorithms: Server to Client\r
-     *\r
-     * @see Net_SSH2::getCompressionAlgorithmsServer2Client()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $compression_algorithms_server_to_client;\r
-\r
-    /**\r
-     * Languages: Server to Client\r
-     *\r
-     * @see Net_SSH2::getLanguagesServer2Client()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $languages_server_to_client;\r
-\r
-    /**\r
-     * Languages: Client to Server\r
-     *\r
-     * @see Net_SSH2::getLanguagesClient2Server()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $languages_client_to_server;\r
-\r
-    /**\r
-     * Block Size for Server to Client Encryption\r
-     *\r
-     * "Note that the length of the concatenation of 'packet_length',\r
-     *  'padding_length', 'payload', and 'random padding' MUST be a multiple\r
-     *  of the cipher block size or 8, whichever is larger.  This constraint\r
-     *  MUST be enforced, even when using stream ciphers."\r
-     *\r
-     *  -- http://tools.ietf.org/html/rfc4253#section-6\r
-     *\r
-     * @see Net_SSH2::Net_SSH2()\r
-     * @see Net_SSH2::_send_binary_packet()\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $encrypt_block_size = 8;\r
-\r
-    /**\r
-     * Block Size for Client to Server Encryption\r
-     *\r
-     * @see Net_SSH2::Net_SSH2()\r
-     * @see Net_SSH2::_get_binary_packet()\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $decrypt_block_size = 8;\r
-\r
-    /**\r
-     * Server to Client Encryption Object\r
-     *\r
-     * @see Net_SSH2::_get_binary_packet()\r
-     * @var Object\r
-     * @access private\r
-     */\r
-    var $decrypt = false;\r
-\r
-    /**\r
-     * Client to Server Encryption Object\r
-     *\r
-     * @see Net_SSH2::_send_binary_packet()\r
-     * @var Object\r
-     * @access private\r
-     */\r
-    var $encrypt = false;\r
-\r
-    /**\r
-     * Client to Server HMAC Object\r
-     *\r
-     * @see Net_SSH2::_send_binary_packet()\r
-     * @var Object\r
-     * @access private\r
-     */\r
-    var $hmac_create = false;\r
-\r
-    /**\r
-     * Server to Client HMAC Object\r
-     *\r
-     * @see Net_SSH2::_get_binary_packet()\r
-     * @var Object\r
-     * @access private\r
-     */\r
-    var $hmac_check = false;\r
-\r
-    /**\r
-     * Size of server to client HMAC\r
-     *\r
-     * We need to know how big the HMAC will be for the server to client direction so that we know how many bytes to read.\r
-     * For the client to server side, the HMAC object will make the HMAC as long as it needs to be.  All we need to do is\r
-     * append it.\r
-     *\r
-     * @see Net_SSH2::_get_binary_packet()\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $hmac_size = false;\r
-\r
-    /**\r
-     * Server Public Host Key\r
-     *\r
-     * @see Net_SSH2::getServerPublicHostKey()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $server_public_host_key;\r
-\r
-    /**\r
-     * Session identifer\r
-     *\r
-     * "The exchange hash H from the first key exchange is additionally\r
-     *  used as the session identifier, which is a unique identifier for\r
-     *  this connection."\r
-     *\r
-     *  -- http://tools.ietf.org/html/rfc4253#section-7.2\r
-     *\r
-     * @see Net_SSH2::_key_exchange()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $session_id = false;\r
-\r
-    /**\r
-     * Message Numbers\r
-     *\r
-     * @see Net_SSH2::Net_SSH2()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $message_numbers = array();\r
-\r
-    /**\r
-     * Disconnection Message 'reason codes' defined in RFC4253\r
-     *\r
-     * @see Net_SSH2::Net_SSH2()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $disconnect_reasons = array();\r
-\r
-    /**\r
-     * SSH_MSG_CHANNEL_OPEN_FAILURE 'reason codes', defined in RFC4254\r
-     *\r
-     * @see Net_SSH2::Net_SSH2()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $channel_open_failure_reasons = array();\r
-\r
-    /**\r
-     * Terminal Modes\r
-     *\r
-     * @link http://tools.ietf.org/html/rfc4254#section-8\r
-     * @see Net_SSH2::Net_SSH2()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $terminal_modes = array();\r
-\r
-    /**\r
-     * SSH_MSG_CHANNEL_EXTENDED_DATA's data_type_codes\r
-     *\r
-     * @link http://tools.ietf.org/html/rfc4254#section-5.2\r
-     * @see Net_SSH2::Net_SSH2()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $channel_extended_data_type_codes = array();\r
-\r
-    /**\r
-     * Send Sequence Number\r
-     *\r
-     * See 'Section 6.4.  Data Integrity' of rfc4253 for more info.\r
-     *\r
-     * @see Net_SSH2::_send_binary_packet()\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $send_seq_no = 0;\r
-\r
-    /**\r
-     * Get Sequence Number\r
-     *\r
-     * See 'Section 6.4.  Data Integrity' of rfc4253 for more info.\r
-     *\r
-     * @see Net_SSH2::_get_binary_packet()\r
-     * @var Integer\r
-     * @access private\r
-     */\r
-    var $get_seq_no = 0;\r
-\r
-    /**\r
-     * Server Channels\r
-     *\r
-     * Maps client channels to server channels\r
-     *\r
-     * @see Net_SSH2::_get_channel_packet()\r
-     * @see Net_SSH2::exec()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $server_channels = array();\r
-\r
-    /**\r
-     * Channel Buffers\r
-     *\r
-     * If a client requests a packet from one channel but receives two packets from another those packets should\r
-     * be placed in a buffer\r
-     *\r
-     * @see Net_SSH2::_get_channel_packet()\r
-     * @see Net_SSH2::exec()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $channel_buffers = array();\r
-\r
-    /**\r
-     * Channel Status\r
-     *\r
-     * Contains the type of the last sent message\r
-     *\r
-     * @see Net_SSH2::_get_channel_packet()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $channel_status = array();\r
-\r
-    /**\r
-     * Packet Size\r
-     *\r
-     * Maximum packet size indexed by channel\r
-     *\r
-     * @see Net_SSH2::_send_channel_packet()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $packet_size_client_to_server = array();\r
-\r
-    /**\r
-     * Message Number Log\r
-     *\r
-     * @see Net_SSH2::getLog()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $message_number_log = array();\r
-\r
-    /**\r
-     * Message Log\r
-     *\r
-     * @see Net_SSH2::getLog()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $message_log = array();\r
-\r
-    /**\r
-     * The Window Size\r
-     *\r
-     * Bytes the other party can send before it must wait for the window to be adjusted (0x7FFFFFFF = 4GB)\r
-     *\r
-     * @var Integer\r
-     * @see Net_SSH2::_send_channel_packet()\r
-     * @see Net_SSH2::exec()\r
-     * @access private\r
-     */\r
-    var $window_size = 0x7FFFFFFF;\r
-\r
-    /**\r
-     * Window size\r
-     *\r
-     * Window size indexed by channel\r
-     *\r
-     * @see Net_SSH2::_send_channel_packet()\r
-     * @var Array\r
-     * @access private\r
-     */\r
-    var $window_size_client_to_server = array();\r
-\r
-    /**\r
-     * Server signature\r
-     *\r
-     * Verified against $this->session_id\r
-     *\r
-     * @see Net_SSH2::getServerPublicHostKey()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $signature = '';\r
-\r
-    /**\r
-     * Server signature format\r
-     *\r
-     * ssh-rsa or ssh-dss.\r
-     *\r
-     * @see Net_SSH2::getServerPublicHostKey()\r
-     * @var String\r
-     * @access private\r
-     */\r
-    var $signature_format = '';\r
-\r
-    /**\r
-     * Default Constructor.\r
-     *\r
-     * Connects to an SSHv2 server\r
-     *\r
-     * @param String $host\r
-     * @param optional Integer $port\r
-     * @param optional Integer $timeout\r
-     * @return Net_SSH2\r
-     * @access public\r
-     */\r
-    function Net_SSH2($host, $port = 22, $timeout = 10)\r
-    {\r
-        $this->message_numbers = array(\r
-            1 => 'NET_SSH2_MSG_DISCONNECT',\r
-            2 => 'NET_SSH2_MSG_IGNORE',\r
-            3 => 'NET_SSH2_MSG_UNIMPLEMENTED',\r
-            4 => 'NET_SSH2_MSG_DEBUG',\r
-            5 => 'NET_SSH2_MSG_SERVICE_REQUEST',\r
-            6 => 'NET_SSH2_MSG_SERVICE_ACCEPT',\r
-            20 => 'NET_SSH2_MSG_KEXINIT',\r
-            21 => 'NET_SSH2_MSG_NEWKEYS',\r
-            30 => 'NET_SSH2_MSG_KEXDH_INIT',\r
-            31 => 'NET_SSH2_MSG_KEXDH_REPLY',\r
-            50 => 'NET_SSH2_MSG_USERAUTH_REQUEST',\r
-            51 => 'NET_SSH2_MSG_USERAUTH_FAILURE',\r
-            52 => 'NET_SSH2_MSG_USERAUTH_SUCCESS',\r
-            53 => 'NET_SSH2_MSG_USERAUTH_BANNER',\r
-\r
-            80 => 'NET_SSH2_MSG_GLOBAL_REQUEST',\r
-            81 => 'NET_SSH2_MSG_REQUEST_SUCCESS',\r
-            82 => 'NET_SSH2_MSG_REQUEST_FAILURE',\r
-            90 => 'NET_SSH2_MSG_CHANNEL_OPEN',\r
-            91 => 'NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION',\r
-            92 => 'NET_SSH2_MSG_CHANNEL_OPEN_FAILURE',\r
-            93 => 'NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST',\r
-            94 => 'NET_SSH2_MSG_CHANNEL_DATA',\r
-            95 => 'NET_SSH2_MSG_CHANNEL_EXTENDED_DATA',\r
-            96 => 'NET_SSH2_MSG_CHANNEL_EOF',\r
-            97 => 'NET_SSH2_MSG_CHANNEL_CLOSE',\r
-            98 => 'NET_SSH2_MSG_CHANNEL_REQUEST',\r
-            99 => 'NET_SSH2_MSG_CHANNEL_SUCCESS',\r
-            100 => 'NET_SSH2_MSG_CHANNEL_FAILURE'\r
-        );\r
-        $this->disconnect_reasons = array(\r
-            1 => 'NET_SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT',\r
-            2 => 'NET_SSH2_DISCONNECT_PROTOCOL_ERROR',\r
-            3 => 'NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED',\r
-            4 => 'NET_SSH2_DISCONNECT_RESERVED',\r
-            5 => 'NET_SSH2_DISCONNECT_MAC_ERROR',\r
-            6 => 'NET_SSH2_DISCONNECT_COMPRESSION_ERROR',\r
-            7 => 'NET_SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE',\r
-            8 => 'NET_SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED',\r
-            9 => 'NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE',\r
-            10 => 'NET_SSH2_DISCONNECT_CONNECTION_LOST',\r
-            11 => 'NET_SSH2_DISCONNECT_BY_APPLICATION',\r
-            12 => 'NET_SSH2_DISCONNECT_TOO_MANY_CONNECTIONS',\r
-            13 => 'NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER',\r
-            14 => 'NET_SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE',\r
-            15 => 'NET_SSH2_DISCONNECT_ILLEGAL_USER_NAME'\r
-        );\r
-        $this->channel_open_failure_reasons = array(\r
-            1 => 'NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED'\r
-        );\r
-        $this->terminal_modes = array(\r
-            0 => 'NET_SSH2_TTY_OP_END'\r
-        );\r
-        $this->channel_extended_data_type_codes = array(\r
-            1 => 'NET_SSH2_EXTENDED_DATA_STDERR'\r
-        );\r
-\r
-        $this->_define_array(\r
-            $this->message_numbers,\r
-            $this->disconnect_reasons,\r
-            $this->channel_open_failure_reasons,\r
-            $this->terminal_modes,\r
-            $this->channel_extended_data_type_codes,\r
-            array(60 => 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'),\r
-            array(60 => 'NET_SSH2_MSG_USERAUTH_PK_OK')\r
-        );\r
-\r
-        $this->fsock = @fsockopen($host, $port, $errno, $errstr, $timeout);\r
-        if (!$this->fsock) {\r
-            user_error(rtrim("Cannot connect to $host. Error $errno. $errstr"), E_USER_NOTICE);\r
-            return;\r
-        }\r
-\r
-        /* According to the SSH2 specs,\r
-\r
-          "The server MAY send other lines of data before sending the version\r
-           string.  Each line SHOULD be terminated by a Carriage Return and Line\r
-           Feed.  Such lines MUST NOT begin with "SSH-", and SHOULD be encoded\r
-           in ISO-10646 UTF-8 [RFC3629] (language is not specified).  Clients\r
-           MUST be able to process such lines." */\r
-        $temp = '';\r
-        $extra = '';\r
-        while (!feof($this->fsock) && !preg_match('#^SSH-(\d\.\d+)#', $temp, $matches)) {\r
-            if (substr($temp, -2) == "\r\n") {\r
-                $extra.= $temp;\r
-                $temp = '';\r
-            }\r
-            $temp.= fgets($this->fsock, 255);\r
-        }\r
-\r
-        $ext = array();\r
-        if (extension_loaded('mcrypt')) {\r
-            $ext[] = 'mcrypt';\r
-        }\r
-        if (extension_loaded('gmp')) {\r
-            $ext[] = 'gmp';\r
-        } else if (extension_loaded('bcmath')) {\r
-            $ext[] = 'bcmath';\r
-        }\r
-\r
-        if (!empty($ext)) {\r
-            $this->identifier.= ' (' . implode(', ', $ext) . ')';\r
-        }\r
-\r
-        if (defined('NET_SSH2_LOGGING')) {\r
-            $this->message_number_log[] = '<-';\r
-            $this->message_number_log[] = '->';\r
-\r
-            if (NET_SSH2_LOGGING == NET_SSH2_LOG_COMPLEX) {\r
-                $this->message_log[] = $temp;\r
-                $this->message_log[] = $this->identifier . "\r\n";\r
-            }\r
-        }\r
-\r
-        $this->server_identifier = trim($temp, "\r\n");\r
-        if (!empty($extra)) {\r
-            $this->errors[] = utf8_decode($extra);\r
-        }\r
-\r
-        if ($matches[1] != '1.99' && $matches[1] != '2.0') {\r
-            user_error("Cannot connect to SSH $matches[1] servers", E_USER_NOTICE);\r
-            return;\r
-        }\r
-\r
-        fputs($this->fsock, $this->identifier . "\r\n");\r
-\r
-        $response = $this->_get_binary_packet();\r
-        if ($response === false) {\r
-            user_error('Connection closed by server', E_USER_NOTICE);\r
-            return;\r
-        }\r
-\r
-        if (ord($response[0]) != NET_SSH2_MSG_KEXINIT) {\r
-            user_error('Expected SSH_MSG_KEXINIT', E_USER_NOTICE);\r
-            return;\r
-        }\r
-\r
-        if (!$this->_key_exchange($response)) {\r
-            return;\r
-        }\r
-\r
-        $this->bitmap = NET_SSH2_MASK_CONSTRUCTOR;\r
-    }\r
-\r
-    /**\r
-     * Key Exchange\r
-     *\r
-     * @param String $kexinit_payload_server\r
-     * @access private\r
-     */\r
-    function _key_exchange($kexinit_payload_server)\r
-    {\r
-        static $kex_algorithms = array(\r
-            'diffie-hellman-group1-sha1', // REQUIRED\r
-            'diffie-hellman-group14-sha1' // REQUIRED\r
-        );\r
-\r
-        static $server_host_key_algorithms = array(\r
-            'ssh-rsa', // RECOMMENDED  sign   Raw RSA Key\r
-            'ssh-dss'  // REQUIRED     sign   Raw DSS Key\r
-        );\r
-\r
-        static $encryption_algorithms = array(\r
-            // from <http://tools.ietf.org/html/rfc4345#section-4>:\r
-            'arcfour256',\r
-            'arcfour128',\r
-\r
-            'arcfour',    // OPTIONAL          the ARCFOUR stream cipher with a 128-bit key\r
-\r
-            'aes128-cbc', // RECOMMENDED       AES with a 128-bit key\r
-            'aes192-cbc', // OPTIONAL          AES with a 192-bit key\r
-            'aes256-cbc', // OPTIONAL          AES in CBC mode, with a 256-bit key\r
-\r
-            // from <http://tools.ietf.org/html/rfc4344#section-4>:\r
-            'aes128-ctr', // RECOMMENDED       AES (Rijndael) in SDCTR mode, with 128-bit key\r
-            'aes192-ctr', // RECOMMENDED       AES with 192-bit key\r
-            'aes256-ctr', // RECOMMENDED       AES with 256-bit key\r
-            '3des-ctr',   // RECOMMENDED       Three-key 3DES in SDCTR mode\r
-\r
-            '3des-cbc',   // REQUIRED          three-key 3DES in CBC mode\r
-            'none'        // OPTIONAL          no encryption; NOT RECOMMENDED\r
-        );\r
-\r
-        static $mac_algorithms = array(\r
-            'hmac-sha1-96', // RECOMMENDED     first 96 bits of HMAC-SHA1 (digest length = 12, key length = 20)\r
-            'hmac-sha1',    // REQUIRED        HMAC-SHA1 (digest length = key length = 20)\r
-            'hmac-md5-96',  // OPTIONAL        first 96 bits of HMAC-MD5 (digest length = 12, key length = 16)\r
-            'hmac-md5',     // OPTIONAL        HMAC-MD5 (digest length = key length = 16)\r
-            'none'          // OPTIONAL        no MAC; NOT RECOMMENDED\r
-        );\r
-\r
-        static $compression_algorithms = array(\r
-            'none'   // REQUIRED        no compression\r
-            //'zlib' // OPTIONAL        ZLIB (LZ77) compression\r
-        );\r
-\r
-        static $str_kex_algorithms, $str_server_host_key_algorithms,\r
-               $encryption_algorithms_server_to_client, $mac_algorithms_server_to_client, $compression_algorithms_server_to_client,\r
-               $encryption_algorithms_client_to_server, $mac_algorithms_client_to_server, $compression_algorithms_client_to_server;\r
-\r
-        if (empty($str_kex_algorithms)) {\r
-            $str_kex_algorithms = implode(',', $kex_algorithms);\r
-            $str_server_host_key_algorithms = implode(',', $server_host_key_algorithms);\r
-            $encryption_algorithms_server_to_client = $encryption_algorithms_client_to_server = implode(',', $encryption_algorithms);\r
-            $mac_algorithms_server_to_client = $mac_algorithms_client_to_server = implode(',', $mac_algorithms);\r
-            $compression_algorithms_server_to_client = $compression_algorithms_client_to_server = implode(',', $compression_algorithms);\r
-        }\r
-\r
-        $client_cookie = '';\r
-        for ($i = 0; $i < 16; $i++) {\r
-            $client_cookie.= chr(crypt_random(0, 255));\r
-        }\r
-\r
-        $response = $kexinit_payload_server;\r
-        $this->_string_shift($response, 1); // skip past the message number (it should be SSH_MSG_KEXINIT)\r
-        $server_cookie = $this->_string_shift($response, 16);\r
-\r
-        $temp = unpack('Nlength', $this->_string_shift($response, 4));\r
-        $this->kex_algorithms = explode(',', $this->_string_shift($response, $temp['length']));\r
-\r
-        $temp = unpack('Nlength', $this->_string_shift($response, 4));\r
-        $this->server_host_key_algorithms = explode(',', $this->_string_shift($response, $temp['length']));\r
-\r
-        $temp = unpack('Nlength', $this->_string_shift($response, 4));\r
-        $this->encryption_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));\r
-\r
-        $temp = unpack('Nlength', $this->_string_shift($response, 4));\r
-        $this->encryption_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));\r
-\r
-        $temp = unpack('Nlength', $this->_string_shift($response, 4));\r
-        $this->mac_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));\r
-\r
-        $temp = unpack('Nlength', $this->_string_shift($response, 4));\r
-        $this->mac_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));\r
-\r
-        $temp = unpack('Nlength', $this->_string_shift($response, 4));\r
-        $this->compression_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));\r
-\r
-        $temp = unpack('Nlength', $this->_string_shift($response, 4));\r
-        $this->compression_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));\r
-\r
-        $temp = unpack('Nlength', $this->_string_shift($response, 4));\r
-        $this->languages_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));\r
-\r
-        $temp = unpack('Nlength', $this->_string_shift($response, 4));\r
-        $this->languages_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));\r
-\r
-        extract(unpack('Cfirst_kex_packet_follows', $this->_string_shift($response, 1)));\r
-        $first_kex_packet_follows = $first_kex_packet_follows != 0;\r
-\r
-        // the sending of SSH2_MSG_KEXINIT could go in one of two places.  this is the second place.\r
-        $kexinit_payload_client = pack('Ca*Na*Na*Na*Na*Na*Na*Na*Na*Na*Na*CN',\r
-            NET_SSH2_MSG_KEXINIT, $client_cookie, strlen($str_kex_algorithms), $str_kex_algorithms,\r
-            strlen($str_server_host_key_algorithms), $str_server_host_key_algorithms, strlen($encryption_algorithms_client_to_server),\r
-            $encryption_algorithms_client_to_server, strlen($encryption_algorithms_server_to_client), $encryption_algorithms_server_to_client,\r
-            strlen($mac_algorithms_client_to_server), $mac_algorithms_client_to_server, strlen($mac_algorithms_server_to_client),\r
-            $mac_algorithms_server_to_client, strlen($compression_algorithms_client_to_server), $compression_algorithms_client_to_server,\r
-            strlen($compression_algorithms_server_to_client), $compression_algorithms_server_to_client, 0, '', 0, '',\r
-            0, 0\r
-        );\r
-\r
-        if (!$this->_send_binary_packet($kexinit_payload_client)) {\r
-            return false;\r
-        }\r
-        // here ends the second place.\r
-\r
-        // we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange\r
-        for ($i = 0; $i < count($encryption_algorithms) && !in_array($encryption_algorithms[$i], $this->encryption_algorithms_server_to_client); $i++);\r
-        if ($i == count($encryption_algorithms)) {\r
-            user_error('No compatible server to client encryption algorithms found', E_USER_NOTICE);\r
-            return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);\r
-        }\r
-\r
-        // we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the\r
-        // diffie-hellman key exchange as fast as possible\r
-        $decrypt = $encryption_algorithms[$i];\r
-        switch ($decrypt) {\r
-            case '3des-cbc':\r
-            case '3des-ctr':\r
-                $decryptKeyLength = 24; // eg. 192 / 8\r
-                break;\r
-            case 'aes256-cbc':\r
-            case 'aes256-ctr':\r
-                $decryptKeyLength = 32; // eg. 256 / 8\r
-                break;\r
-            case 'aes192-cbc':\r
-            case 'aes192-ctr':\r
-                $decryptKeyLength = 24; // eg. 192 / 8\r
-                break;\r
-            case 'aes128-cbc':\r
-            case 'aes128-ctr':\r
-                $decryptKeyLength = 16; // eg. 128 / 8\r
-                break;\r
-            case 'arcfour':\r
-            case 'arcfour128':\r
-                $decryptKeyLength = 16; // eg. 128 / 8\r
-                break;\r
-            case 'arcfour256':\r
-                $decryptKeyLength = 32; // eg. 128 / 8\r
-                break;\r
-            case 'none';\r
-                $decryptKeyLength = 0;\r
-        }\r
-\r
-        for ($i = 0; $i < count($encryption_algorithms) && !in_array($encryption_algorithms[$i], $this->encryption_algorithms_client_to_server); $i++);\r
-        if ($i == count($encryption_algorithms)) {\r
-            user_error('No compatible client to server encryption algorithms found', E_USER_NOTICE);\r
-            return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);\r
-        }\r
-\r
-        $encrypt = $encryption_algorithms[$i];\r
-        switch ($encrypt) {\r
-            case '3des-cbc':\r
-            case '3des-ctr':\r
-                $encryptKeyLength = 24;\r
-                break;\r
-            case 'aes256-cbc':\r
-            case 'aes256-ctr':\r
-                $encryptKeyLength = 32;\r
-                break;\r
-            case 'aes192-cbc':\r
-            case 'aes192-ctr':\r
-                $encryptKeyLength = 24;\r
-                break;\r
-            case 'aes128-cbc':\r
-            case 'aes128-ctr':\r
-                $encryptKeyLength = 16;\r
-                break;\r
-            case 'arcfour':\r
-            case 'arcfour128':\r
-                $encryptKeyLength = 16;\r
-                break;\r
-            case 'arcfour256':\r
-                $encryptKeyLength = 32;\r
-                break;\r
-            case 'none';\r
-                $encryptKeyLength = 0;\r
-        }\r
-\r
-        $keyLength = $decryptKeyLength > $encryptKeyLength ? $decryptKeyLength : $encryptKeyLength;\r
-\r
-        // through diffie-hellman key exchange a symmetric key is obtained\r
-        for ($i = 0; $i < count($kex_algorithms) && !in_array($kex_algorithms[$i], $this->kex_algorithms); $i++);\r
-        if ($i == count($kex_algorithms)) {\r
-            user_error('No compatible key exchange algorithms found', E_USER_NOTICE);\r
-            return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);\r
-        }\r
-\r
-        switch ($kex_algorithms[$i]) {\r
-            // see http://tools.ietf.org/html/rfc2409#section-6.2 and \r
-            // http://tools.ietf.org/html/rfc2412, appendex E\r
-            case 'diffie-hellman-group1-sha1':\r
-                $p = pack('H256', 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . \r
-                                  '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . \r
-                                  '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . \r
-                                  'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF');\r
-                $keyLength = $keyLength < 160 ? $keyLength : 160;\r
-                $hash = 'sha1';\r
-                break;\r
-            // see http://tools.ietf.org/html/rfc3526#section-3\r
-            case 'diffie-hellman-group14-sha1':\r
-                $p = pack('H512', 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . \r
-                                  '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . \r
-                                  '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . \r
-                                  'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . \r
-                                  '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . \r
-                                  '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . \r
-                                  'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . \r
-                                  '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF');\r
-                $keyLength = $keyLength < 160 ? $keyLength : 160;\r
-                $hash = 'sha1';\r
-        }\r
-\r
-        $p = new Math_BigInteger($p, 256);\r
-        //$q = $p->bitwise_rightShift(1);\r
-\r
-        /* To increase the speed of the key exchange, both client and server may\r
-           reduce the size of their private exponents.  It should be at least\r
-           twice as long as the key material that is generated from the shared\r
-           secret.  For more details, see the paper by van Oorschot and Wiener\r
-           [VAN-OORSCHOT].\r
-\r
-           -- http://tools.ietf.org/html/rfc4419#section-6.2 */\r
-        $q = new Math_BigInteger(1);\r
-        $q = $q->bitwise_leftShift(2 * $keyLength);\r
-        $q = $q->subtract(new Math_BigInteger(1));\r
-\r
-        $g = new Math_BigInteger(2);\r
-        $x = new Math_BigInteger();\r
-        $x->setRandomGenerator('crypt_random');\r
-        $x = $x->random(new Math_BigInteger(1), $q);\r
-        $e = $g->modPow($x, $p);\r
-\r
-        $eBytes = $e->toBytes(true);\r
-        $data = pack('CNa*', NET_SSH2_MSG_KEXDH_INIT, strlen($eBytes), $eBytes);\r
-\r
-        if (!$this->_send_binary_packet($data)) {\r
-            user_error('Connection closed by server', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_binary_packet();\r
-        if ($response === false) {\r
-            user_error('Connection closed by server', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-        extract(unpack('Ctype', $this->_string_shift($response, 1)));\r
-\r
-        if ($type != NET_SSH2_MSG_KEXDH_REPLY) {\r
-            user_error('Expected SSH_MSG_KEXDH_REPLY', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        $temp = unpack('Nlength', $this->_string_shift($response, 4));\r
-        $this->server_public_host_key = $server_public_host_key = $this->_string_shift($response, $temp['length']);\r
-\r
-        $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));\r
-        $public_key_format = $this->_string_shift($server_public_host_key, $temp['length']);\r
-\r
-        $temp = unpack('Nlength', $this->_string_shift($response, 4));\r
-        $fBytes = $this->_string_shift($response, $temp['length']);\r
-        $f = new Math_BigInteger($fBytes, -256);\r
-\r
-        $temp = unpack('Nlength', $this->_string_shift($response, 4));\r
-        $this->signature = $this->_string_shift($response, $temp['length']);\r
-\r
-        $temp = unpack('Nlength', $this->_string_shift($this->signature, 4));\r
-        $this->signature_format = $this->_string_shift($this->signature, $temp['length']);\r
-\r
-        $key = $f->modPow($x, $p);\r
-        $keyBytes = $key->toBytes(true);\r
-\r
-        if ($this->session_id === false) {\r
-            $source = pack('Na*Na*Na*Na*Na*Na*Na*Na*',\r
-                strlen($this->identifier), $this->identifier, strlen($this->server_identifier), $this->server_identifier,\r
-                strlen($kexinit_payload_client), $kexinit_payload_client, strlen($kexinit_payload_server),\r
-                $kexinit_payload_server, strlen($this->server_public_host_key), $this->server_public_host_key, strlen($eBytes),\r
-                $eBytes, strlen($fBytes), $fBytes, strlen($keyBytes), $keyBytes\r
-            );\r
-\r
-            $source = pack('H*', $hash($source));\r
-\r
-            $this->session_id = $source;\r
-        }\r
-\r
-        for ($i = 0; $i < count($server_host_key_algorithms) && !in_array($server_host_key_algorithms[$i], $this->server_host_key_algorithms); $i++);\r
-        if ($i == count($server_host_key_algorithms)) {\r
-            user_error('No compatible server host key algorithms found', E_USER_NOTICE);\r
-            return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);\r
-        }\r
-\r
-        if ($public_key_format != $server_host_key_algorithms[$i] || $this->signature_format != $server_host_key_algorithms[$i]) {\r
-            user_error('Sever Host Key Algorithm Mismatch', E_USER_NOTICE);\r
-            return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);\r
-        }\r
-\r
-        $packet = pack('C',\r
-            NET_SSH2_MSG_NEWKEYS\r
-        );\r
-\r
-        if (!$this->_send_binary_packet($packet)) {\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_binary_packet();\r
-\r
-        if ($response === false) {\r
-            user_error('Connection closed by server', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        extract(unpack('Ctype', $this->_string_shift($response, 1)));\r
-\r
-        if ($type != NET_SSH2_MSG_NEWKEYS) {\r
-            user_error('Expected SSH_MSG_NEWKEYS', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        switch ($encrypt) {\r
-            case '3des-cbc':\r
-                $this->encrypt = new Crypt_TripleDES();\r
-                // $this->encrypt_block_size = 64 / 8 == the default\r
-                break;\r
-            case '3des-ctr':\r
-                $this->encrypt = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);\r
-                // $this->encrypt_block_size = 64 / 8 == the default\r
-                break;\r
-            case 'aes256-cbc':\r
-            case 'aes192-cbc':\r
-            case 'aes128-cbc':\r
-                $this->encrypt = new Crypt_AES();\r
-                $this->encrypt_block_size = 16; // eg. 128 / 8\r
-                break;\r
-            case 'aes256-ctr':\r
-            case 'aes192-ctr':\r
-            case 'aes128-ctr':\r
-                $this->encrypt = new Crypt_AES(CRYPT_AES_MODE_CTR);\r
-                $this->encrypt_block_size = 16; // eg. 128 / 8\r
-                break;\r
-            case 'arcfour':\r
-            case 'arcfour128':\r
-            case 'arcfour256':\r
-                $this->encrypt = new Crypt_RC4();\r
-                break;\r
-            case 'none';\r
-                //$this->encrypt = new Crypt_Null();\r
-        }\r
-\r
-        switch ($decrypt) {\r
-            case '3des-cbc':\r
-                $this->decrypt = new Crypt_TripleDES();\r
-                break;\r
-            case '3des-ctr':\r
-                $this->decrypt = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);\r
-                break;\r
-            case 'aes256-cbc':\r
-            case 'aes192-cbc':\r
-            case 'aes128-cbc':\r
-                $this->decrypt = new Crypt_AES();\r
-                $this->decrypt_block_size = 16;\r
-                break;\r
-            case 'aes256-ctr':\r
-            case 'aes192-ctr':\r
-            case 'aes128-ctr':\r
-                $this->decrypt = new Crypt_AES(CRYPT_AES_MODE_CTR);\r
-                $this->decrypt_block_size = 16;\r
-                break;\r
-            case 'arcfour':\r
-            case 'arcfour128':\r
-            case 'arcfour256':\r
-                $this->decrypt = new Crypt_RC4();\r
-                break;\r
-            case 'none';\r
-                //$this->decrypt = new Crypt_Null();\r
-        }\r
-\r
-        $keyBytes = pack('Na*', strlen($keyBytes), $keyBytes);\r
-\r
-        if ($this->encrypt) {\r
-            $this->encrypt->enableContinuousBuffer();\r
-            $this->encrypt->disablePadding();\r
-\r
-            $iv = pack('H*', $hash($keyBytes . $this->session_id . 'A' . $this->session_id));\r
-            while ($this->encrypt_block_size > strlen($iv)) {\r
-                $iv.= pack('H*', $hash($keyBytes . $this->session_id . $iv));\r
-            }\r
-            $this->encrypt->setIV(substr($iv, 0, $this->encrypt_block_size));\r
-\r
-            $key = pack('H*', $hash($keyBytes . $this->session_id . 'C' . $this->session_id));\r
-            while ($encryptKeyLength > strlen($key)) {\r
-                $key.= pack('H*', $hash($keyBytes . $this->session_id . $key));\r
-            }\r
-            $this->encrypt->setKey(substr($key, 0, $encryptKeyLength));\r
-        }\r
-\r
-        if ($this->decrypt) {\r
-            $this->decrypt->enableContinuousBuffer();\r
-            $this->decrypt->disablePadding();\r
-\r
-            $iv = pack('H*', $hash($keyBytes . $this->session_id . 'B' . $this->session_id));\r
-            while ($this->decrypt_block_size > strlen($iv)) {\r
-                $iv.= pack('H*', $hash($keyBytes . $this->session_id . $iv));\r
-            }\r
-            $this->decrypt->setIV(substr($iv, 0, $this->decrypt_block_size));\r
-\r
-            $key = pack('H*', $hash($keyBytes . $this->session_id . 'D' . $this->session_id));\r
-            while ($decryptKeyLength > strlen($key)) {\r
-                $key.= pack('H*', $hash($keyBytes . $this->session_id . $key));\r
-            }\r
-            $this->decrypt->setKey(substr($key, 0, $decryptKeyLength));\r
-        }\r
-\r
-        /* The "arcfour128" algorithm is the RC4 cipher, as described in\r
-           [SCHNEIER], using a 128-bit key.  The first 1536 bytes of keystream\r
-           generated by the cipher MUST be discarded, and the first byte of the\r
-           first encrypted packet MUST be encrypted using the 1537th byte of\r
-           keystream.\r
-\r
-           -- http://tools.ietf.org/html/rfc4345#section-4 */\r
-        if ($encrypt == 'arcfour128' || $encrypt == 'arcfour256') {\r
-            $this->encrypt->encrypt(str_repeat("\0", 1536));\r
-        }\r
-        if ($decrypt == 'arcfour128' || $decrypt == 'arcfour256') {\r
-            $this->decrypt->decrypt(str_repeat("\0", 1536));\r
-        }\r
-\r
-        for ($i = 0; $i < count($mac_algorithms) && !in_array($mac_algorithms[$i], $this->mac_algorithms_client_to_server); $i++);\r
-        if ($i == count($mac_algorithms)) {\r
-            user_error('No compatible client to server message authentication algorithms found', E_USER_NOTICE);\r
-            return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);\r
-        }\r
-\r
-        $createKeyLength = 0; // ie. $mac_algorithms[$i] == 'none'\r
-        switch ($mac_algorithms[$i]) {\r
-            case 'hmac-sha1':\r
-                $this->hmac_create = new Crypt_Hash('sha1');\r
-                $createKeyLength = 20;\r
-                break;\r
-            case 'hmac-sha1-96':\r
-                $this->hmac_create = new Crypt_Hash('sha1-96');\r
-                $createKeyLength = 20;\r
-                break;\r
-            case 'hmac-md5':\r
-                $this->hmac_create = new Crypt_Hash('md5');\r
-                $createKeyLength = 16;\r
-                break;\r
-            case 'hmac-md5-96':\r
-                $this->hmac_create = new Crypt_Hash('md5-96');\r
-                $createKeyLength = 16;\r
-        }\r
-\r
-        for ($i = 0; $i < count($mac_algorithms) && !in_array($mac_algorithms[$i], $this->mac_algorithms_server_to_client); $i++);\r
-        if ($i == count($mac_algorithms)) {\r
-            user_error('No compatible server to client message authentication algorithms found', E_USER_NOTICE);\r
-            return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);\r
-        }\r
-\r
-        $checkKeyLength = 0;\r
-        $this->hmac_size = 0;\r
-        switch ($mac_algorithms[$i]) {\r
-            case 'hmac-sha1':\r
-                $this->hmac_check = new Crypt_Hash('sha1');\r
-                $checkKeyLength = 20;\r
-                $this->hmac_size = 20;\r
-                break;\r
-            case 'hmac-sha1-96':\r
-                $this->hmac_check = new Crypt_Hash('sha1-96');\r
-                $checkKeyLength = 20;\r
-                $this->hmac_size = 12;\r
-                break;\r
-            case 'hmac-md5':\r
-                $this->hmac_check = new Crypt_Hash('md5');\r
-                $checkKeyLength = 16;\r
-                $this->hmac_size = 16;\r
-                break;\r
-            case 'hmac-md5-96':\r
-                $this->hmac_check = new Crypt_Hash('md5-96');\r
-                $checkKeyLength = 16;\r
-                $this->hmac_size = 12;\r
-        }\r
-\r
-        $key = pack('H*', $hash($keyBytes . $this->session_id . 'E' . $this->session_id));\r
-        while ($createKeyLength > strlen($key)) {\r
-            $key.= pack('H*', $hash($keyBytes . $this->session_id . $key));\r
-        }\r
-        $this->hmac_create->setKey(substr($key, 0, $createKeyLength));\r
-\r
-        $key = pack('H*', $hash($keyBytes . $this->session_id . 'F' . $this->session_id));\r
-        while ($checkKeyLength > strlen($key)) {\r
-            $key.= pack('H*', $hash($keyBytes . $this->session_id . $key));\r
-        }\r
-        $this->hmac_check->setKey(substr($key, 0, $checkKeyLength));\r
-\r
-        for ($i = 0; $i < count($compression_algorithms) && !in_array($compression_algorithms[$i], $this->compression_algorithms_server_to_client); $i++);\r
-        if ($i == count($compression_algorithms)) {\r
-            user_error('No compatible server to client compression algorithms found', E_USER_NOTICE);\r
-            return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);\r
-        }\r
-        $this->decompress = $compression_algorithms[$i] == 'zlib';\r
-\r
-        for ($i = 0; $i < count($compression_algorithms) && !in_array($compression_algorithms[$i], $this->compression_algorithms_client_to_server); $i++);\r
-        if ($i == count($compression_algorithms)) {\r
-            user_error('No compatible client to server compression algorithms found', E_USER_NOTICE);\r
-            return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);\r
-        }\r
-        $this->compress = $compression_algorithms[$i] == 'zlib';\r
-\r
-        return true;\r
-    }\r
-\r
-    /**\r
-     * Login\r
-     *\r
-     * @param String $username\r
-     * @param optional String $password\r
-     * @return Boolean\r
-     * @access public\r
-     * @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis}\r
-     *           by sending dummy SSH_MSG_IGNORE messages.\r
-     */\r
-    function login($username, $password = '')\r
-    {\r
-        if (!($this->bitmap & NET_SSH2_MASK_CONSTRUCTOR)) {\r
-            return false;\r
-        }\r
-\r
-        $packet = pack('CNa*',\r
-            NET_SSH2_MSG_SERVICE_REQUEST, strlen('ssh-userauth'), 'ssh-userauth'\r
-        );\r
-\r
-        if (!$this->_send_binary_packet($packet)) {\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_binary_packet();\r
-        if ($response === false) {\r
-            user_error('Connection closed by server', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        extract(unpack('Ctype', $this->_string_shift($response, 1)));\r
-\r
-        if ($type != NET_SSH2_MSG_SERVICE_ACCEPT) {\r
-            user_error('Expected SSH_MSG_SERVICE_ACCEPT', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        // although PHP5's get_class() preserves the case, PHP4's does not\r
-        if (is_object($password) && strtolower(get_class($password)) == 'crypt_rsa')  {\r
-            return $this->_privatekey_login($username, $password);\r
-        }\r
-\r
-        $utf8_password = utf8_encode($password);\r
-        $packet = pack('CNa*Na*Na*CNa*',\r
-            NET_SSH2_MSG_USERAUTH_REQUEST, strlen($username), $username, strlen('ssh-connection'), 'ssh-connection',\r
-            strlen('password'), 'password', 0, strlen($utf8_password), $utf8_password\r
-        );\r
-\r
-        if (!$this->_send_binary_packet($packet)) {\r
-            return false;\r
-        }\r
-\r
-        // remove the username and password from the last logged packet\r
-        if (defined('NET_SSH2_LOGGING') && NET_SSH2_LOGGING == NET_SSH2_LOG_COMPLEX) {\r
-            $packet = pack('CNa*Na*Na*CNa*',\r
-                NET_SSH2_MSG_USERAUTH_REQUEST, strlen('username'), 'username', strlen('ssh-connection'), 'ssh-connection',\r
-                strlen('password'), 'password', 0, strlen('password'), 'password'\r
-            );\r
-            $this->message_log[count($this->message_log) - 1] = $packet;\r
-        }\r
-\r
-        $response = $this->_get_binary_packet();\r
-        if ($response === false) {\r
-            user_error('Connection closed by server', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        extract(unpack('Ctype', $this->_string_shift($response, 1)));\r
-\r
-        switch ($type) {\r
-            case NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ: // in theory, the password can be changed\r
-                if (defined('NET_SSH2_LOGGING')) {\r
-                    $this->message_number_log[count($this->message_number_log) - 1] = 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ';\r
-                }\r
-                extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-                $this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . utf8_decode($this->_string_shift($response, $length));\r
-                return $this->_disconnect(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);\r
-            case NET_SSH2_MSG_USERAUTH_FAILURE:\r
-                // either the login is bad or the server employees multi-factor authentication\r
-                return false;\r
-            case NET_SSH2_MSG_USERAUTH_SUCCESS:\r
-                $this->bitmap |= NET_SSH2_MASK_LOGIN;\r
-                return true;\r
-        }\r
-\r
-        return false;\r
-    }\r
-\r
-    /**\r
-     * Login with an RSA private key\r
-     *\r
-     * @param String $username\r
-     * @param Crypt_RSA $password\r
-     * @return Boolean\r
-     * @access private\r
-     * @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis}\r
-     *           by sending dummy SSH_MSG_IGNORE messages.\r
-     */\r
-    function _privatekey_login($username, $privatekey)\r
-    {\r
-        // see http://tools.ietf.org/html/rfc4253#page-15\r
-        $publickey = $privatekey->getPublicKey(CRYPT_RSA_PUBLIC_FORMAT_RAW);\r
-        if ($publickey === false) {\r
-            return false;\r
-        }\r
-\r
-        $publickey = array(\r
-            'e' => $publickey['e']->toBytes(true),\r
-            'n' => $publickey['n']->toBytes(true)\r
-        );\r
-        $publickey = pack('Na*Na*Na*',\r
-            strlen('ssh-rsa'), 'ssh-rsa', strlen($publickey['e']), $publickey['e'], strlen($publickey['n']), $publickey['n']\r
-        );\r
-\r
-        $part1 = pack('CNa*Na*Na*',\r
-            NET_SSH2_MSG_USERAUTH_REQUEST, strlen($username), $username, strlen('ssh-connection'), 'ssh-connection',\r
-            strlen('publickey'), 'publickey'\r
-        );\r
-        $part2 = pack('Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publickey), $publickey);\r
-\r
-        $packet = $part1 . chr(0) . $part2;\r
-\r
-        if (!$this->_send_binary_packet($packet)) {\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_binary_packet();\r
-        if ($response === false) {\r
-            user_error('Connection closed by server', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        extract(unpack('Ctype', $this->_string_shift($response, 1)));\r
-\r
-        switch ($type) {\r
-            case NET_SSH2_MSG_USERAUTH_FAILURE:\r
-                extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-                $this->errors[] = 'SSH_MSG_USERAUTH_FAILURE: ' . $this->_string_shift($response, $length);\r
-                return $this->_disconnect(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);\r
-            case NET_SSH2_MSG_USERAUTH_PK_OK:\r
-                // we'll just take it on faith that the public key blob and the public key algorithm name are as\r
-                // they should be\r
-                if (defined('NET_SSH2_LOGGING')) {\r
-                    $this->message_number_log[count($this->message_number_log) - 1] = 'NET_SSH2_MSG_USERAUTH_PK_OK';\r
-                }\r
-        }\r
-\r
-        $packet = $part1 . chr(1) . $part2;\r
-        $privatekey->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);\r
-        $signature = $privatekey->sign(pack('Na*a*', strlen($this->session_id), $this->session_id, $packet));\r
-        $signature = pack('Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($signature), $signature);\r
-        $packet.= pack('Na*', strlen($signature), $signature);\r
-\r
-        if (!$this->_send_binary_packet($packet)) {\r
-            return false;\r
-        }\r
-\r
-        $response = $this->_get_binary_packet();\r
-        if ($response === false) {\r
-            user_error('Connection closed by server', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        extract(unpack('Ctype', $this->_string_shift($response, 1)));\r
-\r
-        switch ($type) {\r
-            case NET_SSH2_MSG_USERAUTH_FAILURE:\r
-                // either the login is bad or the server employees multi-factor authentication\r
-                return false;\r
-            case NET_SSH2_MSG_USERAUTH_SUCCESS:\r
-                $this->bitmap |= NET_SSH2_MASK_LOGIN;\r
-                return true;\r
-        }\r
-\r
-        return false;\r
-    }\r
-\r
-    /**\r
-     * Execute Command\r
-     *\r
-     * @param String $command\r
-     * @return String\r
-     * @access public\r
-     */\r
-    function exec($command)\r
-    {\r
-        if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {\r
-            return false;\r
-        }\r
-\r
-        // RFC4254 defines the (client) window size as "bytes the other party can send before it must wait for the window to\r
-        // be adjusted".  0x7FFFFFFF is, at 4GB, the max size.  technically, it should probably be decremented, but, \r
-        // honestly, if you're transfering more than 4GB, you probably shouldn't be using phpseclib, anyway.\r
-        // see http://tools.ietf.org/html/rfc4254#section-5.2 for more info\r
-        $this->window_size_client_to_server[NET_SSH2_CHANNEL_EXEC] = 0x7FFFFFFF;\r
-        // 0x8000 is the maximum max packet size, per http://tools.ietf.org/html/rfc4253#section-6.1, although since PuTTy\r
-        // uses 0x4000, that's what will be used here, as well.\r
-        $packet_size = 0x4000;\r
-\r
-        $packet = pack('CNa*N3',\r
-            NET_SSH2_MSG_CHANNEL_OPEN, strlen('session'), 'session', NET_SSH2_CHANNEL_EXEC, $this->window_size_client_to_server[NET_SSH2_CHANNEL_EXEC], $packet_size);\r
-\r
-        if (!$this->_send_binary_packet($packet)) {\r
-            return false;\r
-        }\r
-\r
-        $this->channel_status[NET_SSH2_CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_OPEN;\r
-\r
-        $response = $this->_get_channel_packet(NET_SSH2_CHANNEL_EXEC);\r
-        if ($response === false) {\r
-            return false;\r
-        }\r
-\r
-        // sending a pty-req SSH_MSG_CHANNEL_REQUEST message is unnecessary and, in fact, in most cases, slows things\r
-        // down.  the one place where it might be desirable is if you're doing something like Net_SSH2::exec('ping localhost &').\r
-        // with a pty-req SSH_MSG_cHANNEL_REQUEST, exec() will return immediately and the ping process will then\r
-        // then immediately terminate.  without such a request exec() will loop indefinitely.  the ping process won't end but\r
-        // neither will your script.\r
-\r
-        // although, in theory, the size of SSH_MSG_CHANNEL_REQUEST could exceed the maximum packet size established by\r
-        // SSH_MSG_CHANNEL_OPEN_CONFIRMATION, RFC4254#section-5.1 states that the "maximum packet size" refers to the \r
-        // "maximum size of an individual data packet". ie. SSH_MSG_CHANNEL_DATA.  RFC4254#section-5.2 corroborates.\r
-        $packet = pack('CNNa*CNa*',\r
-            NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[NET_SSH2_CHANNEL_EXEC], strlen('exec'), 'exec', 1, strlen($command), $command);\r
-        if (!$this->_send_binary_packet($packet)) {\r
-            return false;\r
-        }\r
-\r
-        $this->channel_status[NET_SSH2_CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_REQUEST;\r
-\r
-        $response = $this->_get_channel_packet(NET_SSH2_CHANNEL_EXEC);\r
-        if ($response === false) {\r
-            return false;\r
-        }\r
-\r
-        $this->channel_status[NET_SSH2_CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_DATA;\r
-\r
-        $output = '';\r
-        while (true) {\r
-            $temp = $this->_get_channel_packet(NET_SSH2_CHANNEL_EXEC);\r
-            switch (true) {\r
-                case $temp === true:\r
-                    return $output;\r
-                case $temp === false:\r
-                    return false;\r
-                default:\r
-                    $output.= $temp;\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Disconnect\r
-     *\r
-     * @access public\r
-     */\r
-    function disconnect()\r
-    {\r
-        $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);\r
-    }\r
-\r
-    /**\r
-     * Destructor.\r
-     *\r
-     * Will be called, automatically, if you're supporting just PHP5.  If you're supporting PHP4, you'll need to call\r
-     * disconnect().\r
-     *\r
-     * @access public\r
-     */\r
-    function __destruct()\r
-    {\r
-        $this->disconnect();\r
-    }\r
-\r
-    /**\r
-     * Gets Binary Packets\r
-     *\r
-     * See '6. Binary Packet Protocol' of rfc4253 for more info.\r
-     *\r
-     * @see Net_SSH2::_send_binary_packet()\r
-     * @return String\r
-     * @access private\r
-     */\r
-    function _get_binary_packet()\r
-    {\r
-        if (feof($this->fsock)) {\r
-            user_error('Connection closed prematurely', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838\r
-        $raw = fread($this->fsock, $this->decrypt_block_size);\r
-        $stop = strtok(microtime(), ' ') + strtok('');\r
-\r
-        if ($this->decrypt !== false) {\r
-            $raw = $this->decrypt->decrypt($raw);\r
-        }\r
-\r
-        extract(unpack('Npacket_length/Cpadding_length', $this->_string_shift($raw, 5)));\r
-\r
-        $remaining_length = $packet_length + 4 - $this->decrypt_block_size;\r
-        $buffer = '';\r
-        while ($remaining_length > 0) {\r
-            $temp = fread($this->fsock, $remaining_length);\r
-            $buffer.= $temp;\r
-            $remaining_length-= strlen($temp);\r
-        }\r
-        if (!empty($buffer)) {\r
-            $raw.= $this->decrypt !== false ? $this->decrypt->decrypt($buffer) : $buffer;\r
-            $buffer = $temp = '';\r
-        }\r
-\r
-        $payload = $this->_string_shift($raw, $packet_length - $padding_length - 1);\r
-        $padding = $this->_string_shift($raw, $padding_length); // should leave $raw empty\r
-\r
-        if ($this->hmac_check !== false) {\r
-            $hmac = fread($this->fsock, $this->hmac_size);\r
-            if ($hmac != $this->hmac_check->hash(pack('NNCa*', $this->get_seq_no, $packet_length, $padding_length, $payload . $padding))) {\r
-                user_error('Invalid HMAC', E_USER_NOTICE);\r
-                return false;\r
-            }\r
-        }\r
-\r
-        //if ($this->decompress) {\r
-        //    $payload = gzinflate(substr($payload, 2));\r
-        //}\r
-\r
-        $this->get_seq_no++;\r
-\r
-        if (defined('NET_SSH2_LOGGING')) {\r
-            $temp = isset($this->message_numbers[ord($payload[0])]) ? $this->message_numbers[ord($payload[0])] : 'UNKNOWN';\r
-            $this->message_number_log[] = '<- ' . $temp .\r
-                                          ' (' . round($stop - $start, 4) . 's)';\r
-            if (NET_SSH2_LOGGING == NET_SSH2_LOG_COMPLEX) {\r
-                $this->message_log[] = substr($payload, 1);\r
-            }\r
-        }\r
-\r
-        return $this->_filter($payload);\r
-    }\r
-\r
-    /**\r
-     * Filter Binary Packets\r
-     *\r
-     * Because some binary packets need to be ignored...\r
-     *\r
-     * @see Net_SSH2::_get_binary_packet()\r
-     * @return String\r
-     * @access private\r
-     */\r
-    function _filter($payload)\r
-    {\r
-        switch (ord($payload[0])) {\r
-            case NET_SSH2_MSG_DISCONNECT:\r
-                $this->_string_shift($payload, 1);\r
-                extract(unpack('Nreason_code/Nlength', $this->_string_shift($payload, 8)));\r
-                $this->errors[] = 'SSH_MSG_DISCONNECT: ' . $this->disconnect_reasons[$reason_code] . "\r\n" . utf8_decode($this->_string_shift($payload, $length));\r
-                $this->bitmask = 0;\r
-                return false;\r
-            case NET_SSH2_MSG_IGNORE:\r
-                $payload = $this->_get_binary_packet();\r
-                break;\r
-            case NET_SSH2_MSG_DEBUG:\r
-                $this->_string_shift($payload, 2);\r
-                extract(unpack('Nlength', $this->_string_shift($payload, 4)));\r
-                $this->errors[] = 'SSH_MSG_DEBUG: ' . utf8_decode($this->_string_shift($payload, $length));\r
-                $payload = $this->_get_binary_packet();\r
-                break;\r
-            case NET_SSH2_MSG_UNIMPLEMENTED:\r
-                return false;\r
-            case NET_SSH2_MSG_KEXINIT:\r
-                if ($this->session_id !== false) {\r
-                    if (!$this->_key_exchange($payload)) {\r
-                        $this->bitmask = 0;\r
-                        return false;\r
-                    }\r
-                    $payload = $this->_get_binary_packet();\r
-                }\r
-        }\r
-\r
-        // see http://tools.ietf.org/html/rfc4252#section-5.4; only called when the encryption has been activated and when we haven't already logged in\r
-        if (($this->bitmap & NET_SSH2_MASK_CONSTRUCTOR) && !($this->bitmap & NET_SSH2_MASK_LOGIN) && ord($payload[0]) == NET_SSH2_MSG_USERAUTH_BANNER) {\r
-            $this->_string_shift($payload, 1);\r
-            extract(unpack('Nlength', $this->_string_shift($payload, 4)));\r
-            $this->errors[] = 'SSH_MSG_USERAUTH_BANNER: ' . utf8_decode($this->_string_shift($payload, $length));\r
-            $payload = $this->_get_binary_packet();\r
-        }\r
-\r
-        // only called when we've already logged in\r
-        if (($this->bitmap & NET_SSH2_MASK_CONSTRUCTOR) && ($this->bitmap & NET_SSH2_MASK_LOGIN)) {\r
-            switch (ord($payload[0])) {\r
-                case NET_SSH2_MSG_GLOBAL_REQUEST: // see http://tools.ietf.org/html/rfc4254#section-4\r
-                    $this->_string_shift($payload, 1);\r
-                    extract(unpack('Nlength', $this->_string_shift($payload)));\r
-                    $this->errors[] = 'SSH_MSG_GLOBAL_REQUEST: ' . utf8_decode($this->_string_shift($payload, $length));\r
-\r
-                    if (!$this->_send_binary_packet(pack('C', NET_SSH2_MSG_REQUEST_FAILURE))) {\r
-                        return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);\r
-                    }\r
-\r
-                    $payload = $this->_get_binary_packet();\r
-                    break;\r
-                case NET_SSH2_MSG_CHANNEL_OPEN: // see http://tools.ietf.org/html/rfc4254#section-5.1\r
-                    $this->_string_shift($payload, 1);\r
-                    extract(unpack('N', $this->_string_shift($payload, 4)));\r
-                    $this->errors[] = 'SSH_MSG_CHANNEL_OPEN: ' . utf8_decode($this->_string_shift($payload, $length));\r
-\r
-                    $this->_string_shift($payload, 4); // skip over client channel\r
-                    extract(unpack('Nserver_channel', $this->_string_shift($payload, 4)));\r
-\r
-                    $packet = pack('CN3a*Na*',\r
-                        NET_SSH2_MSG_REQUEST_FAILURE, $server_channel, NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED, 0, '', 0, '');\r
-\r
-                    if (!$this->_send_binary_packet($packet)) {\r
-                        return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);\r
-                    }\r
-\r
-                    $payload = $this->_get_binary_packet();\r
-                    break;\r
-                case NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST:\r
-                    $payload = $this->_get_binary_packet();\r
-            }\r
-        }\r
-\r
-        return $payload;\r
-    }\r
-\r
-    /**\r
-     * Gets channel data\r
-     *\r
-     * Returns the data as a string if it's available and false if not.\r
-     *\r
-     * @param $client_channel\r
-     * @return Mixed\r
-     * @access private\r
-     */\r
-    function _get_channel_packet($client_channel)\r
-    {\r
-        if (!empty($this->channel_buffers[$client_channel])) {\r
-            return array_shift($this->channel_buffers[$client_channel]);\r
-        }\r
-\r
-        while (true) {\r
-            $response = $this->_get_binary_packet();\r
-            if ($response === false) {\r
-                user_error('Connection closed by server', E_USER_NOTICE);\r
-                return false;\r
-            }\r
-\r
-            extract(unpack('Ctype/Nchannel', $this->_string_shift($response, 5)));\r
-\r
-            switch ($this->channel_status[$channel]) {\r
-                case NET_SSH2_MSG_CHANNEL_OPEN:\r
-                    switch ($type) {\r
-                        case NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:\r
-                            extract(unpack('Nserver_channel', $this->_string_shift($response, 4)));\r
-                            $this->server_channels[$client_channel] = $server_channel;\r
-                            $this->_string_shift($response, 4); // skip over (server) window size\r
-                            $temp = unpack('Npacket_size_client_to_server', $this->_string_shift($response, 4));\r
-                            $this->packet_size_client_to_server[$client_channel] = $temp['packet_size_client_to_server'];\r
-                            return true;\r
-                        //case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE:\r
-                        default:\r
-                            user_error('Unable to open channel', E_USER_NOTICE);\r
-                            return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);\r
-                    }\r
-                    break;\r
-                case NET_SSH2_MSG_CHANNEL_REQUEST:\r
-                    switch ($type) {\r
-                        case NET_SSH2_MSG_CHANNEL_SUCCESS:\r
-                            return true;\r
-                        //case NET_SSH2_MSG_CHANNEL_FAILURE:\r
-                        default:\r
-                            user_error('Unable to request pseudo-terminal', E_USER_NOTICE);\r
-                            return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);\r
-                    }\r
-\r
-            }\r
-\r
-            switch ($type) {\r
-                case NET_SSH2_MSG_CHANNEL_DATA:\r
-                    if ($client_channel == NET_SSH2_CHANNEL_EXEC) {\r
-                        // SCP requires null packets, such as this, be sent.  further, in the case of the ssh.com SSH server\r
-                        // this actually seems to make things twice as fast.  more to the point, the message right after \r
-                        // SSH_MSG_CHANNEL_DATA (usually SSH_MSG_IGNORE) won't block for as long as it would have otherwise.\r
-                        // in OpenSSH it slows things down but only by a couple thousandths of a second.\r
-                        $this->_send_channel_packet($client_channel, chr(0));\r
-                    }\r
-                    extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-                    $data = $this->_string_shift($response, $length);\r
-                    if ($client_channel == $channel) {\r
-                        return $data;\r
-                    }\r
-                    if (!isset($this->channel_buffers[$client_channel])) {\r
-                        $this->channel_buffers[$client_channel] = array();\r
-                    }\r
-                    $this->channel_buffers[$client_channel][] = $data;\r
-                    break;\r
-                case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA:\r
-                    if ($client_channel == NET_SSH2_CHANNEL_EXEC) {\r
-                        $this->_send_channel_packet($client_channel, chr(0));\r
-                    }\r
-                    // currently, there's only one possible value for $data_type_code: NET_SSH2_EXTENDED_DATA_STDERR\r
-                    extract(unpack('Ndata_type_code/Nlength', $this->_string_shift($response, 8)));\r
-                    $data = $this->_string_shift($response, $length);\r
-                    if ($client_channel == $channel) {\r
-                        return $data;\r
-                    }\r
-                    if (!isset($this->channel_buffers[$client_channel])) {\r
-                        $this->channel_buffers[$client_channel] = array();\r
-                    }\r
-                    $this->channel_buffers[$client_channel][] = $data;\r
-                    break;\r
-                case NET_SSH2_MSG_CHANNEL_REQUEST:\r
-                    extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-                    $value = $this->_string_shift($response, $length);\r
-                    switch ($value) {\r
-                        case 'exit-signal':\r
-                            $this->_string_shift($response, 1);\r
-                            extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-                            $this->errors[] = 'SSH_MSG_CHANNEL_REQUEST (exit-signal): ' . $this->_string_shift($response, $length);\r
-                            $this->_string_shift($response, 1);\r
-                            extract(unpack('Nlength', $this->_string_shift($response, 4)));\r
-                            if ($length) {\r
-                                $this->errors[count($this->errors)].= "\r\n" . $this->_string_shift($response, $length);\r
-                            }\r
-                        //case 'exit-status':\r
-                        default:\r
-                            // "Some systems may not implement signals, in which case they SHOULD ignore this message."\r
-                            //  -- http://tools.ietf.org/html/rfc4254#section-6.9\r
-                            break;\r
-                    }\r
-                    break;\r
-                case NET_SSH2_MSG_CHANNEL_CLOSE:\r
-                    $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel]));\r
-                    return true;\r
-                case NET_SSH2_MSG_CHANNEL_EOF:\r
-                    break;\r
-                default:\r
-                    user_error('Error reading channel data', E_USER_NOTICE);\r
-                    return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Sends Binary Packets\r
-     *\r
-     * See '6. Binary Packet Protocol' of rfc4253 for more info.\r
-     *\r
-     * @param String $data\r
-     * @see Net_SSH2::_get_binary_packet()\r
-     * @return Boolean\r
-     * @access private\r
-     */\r
-    function _send_binary_packet($data)\r
-    {\r
-        if (feof($this->fsock)) {\r
-            user_error('Connection closed prematurely', E_USER_NOTICE);\r
-            return false;\r
-        }\r
-\r
-        //if ($this->compress) {\r
-        //    // the -4 removes the checksum:\r
-        //    // http://php.net/function.gzcompress#57710\r
-        //    $data = substr(gzcompress($data), 0, -4);\r
-        //}\r
-\r
-        // 4 (packet length) + 1 (padding length) + 4 (minimal padding amount) == 9\r
-        $packet_length = strlen($data) + 9;\r
-        // round up to the nearest $this->encrypt_block_size\r
-        $packet_length+= (($this->encrypt_block_size - 1) * $packet_length) % $this->encrypt_block_size;\r
-        // subtracting strlen($data) is obvious - subtracting 5 is necessary because of packet_length and padding_length\r
-        $padding_length = $packet_length - strlen($data) - 5;\r
-\r
-        $padding = '';\r
-        for ($i = 0; $i < $padding_length; $i++) {\r
-            $padding.= chr(crypt_random(0, 255));\r
-        }\r
-\r
-        // we subtract 4 from packet_length because the packet_length field isn't supposed to include itself\r
-        $packet = pack('NCa*', $packet_length - 4, $padding_length, $data . $padding);\r
-\r
-        $hmac = $this->hmac_create !== false ? $this->hmac_create->hash(pack('Na*', $this->send_seq_no, $packet)) : '';\r
-        $this->send_seq_no++;\r
-\r
-        if ($this->encrypt !== false) {\r
-            $packet = $this->encrypt->encrypt($packet);\r
-        }\r
-\r
-        $packet.= $hmac;\r
-\r
-        $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838\r
-        $result = strlen($packet) == fputs($this->fsock, $packet);\r
-        $stop = strtok(microtime(), ' ') + strtok('');\r
-\r
-        if (defined('NET_SSH2_LOGGING')) {\r
-            $temp = isset($this->message_numbers[ord($data[0])]) ? $this->message_numbers[ord($data[0])] : 'UNKNOWN';\r
-            $this->message_number_log[] = '-> ' . $temp .\r
-                                          ' (' . round($stop - $start, 4) . 's)';\r
-            if (NET_SSH2_LOGGING == NET_SSH2_LOG_COMPLEX) {\r
-                $this->message_log[] = substr($data, 1);\r
-            }\r
-        }\r
-\r
-        return $result;\r
-    }\r
-\r
-    /**\r
-     * Sends channel data\r
-     *\r
-     * Spans multiple SSH_MSG_CHANNEL_DATAs if appropriate\r
-     *\r
-     * @param Integer $client_channel\r
-     * @param String $data\r
-     * @return Boolean\r
-     * @access private\r
-     */\r
-    function _send_channel_packet($client_channel, $data)\r
-    {\r
-        while (strlen($data) > $this->packet_size_client_to_server[$client_channel]) {\r
-            // resize the window, if appropriate\r
-            $this->window_size_client_to_server[$client_channel]-= $this->packet_size_client_to_server[$client_channel];\r
-            if ($this->window_size_client_to_server[$client_channel] < 0) {\r
-                $packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$client_channel], $this->window_size);\r
-                if (!$this->_send_binary_packet($packet)) {\r
-                    return false;\r
-                }\r
-                $this->window_size_client_to_server[$client_channel]+= $this->window_size;\r
-            }\r
-\r
-            $packet = pack('CN2a*',\r
-                NET_SSH2_MSG_CHANNEL_DATA,\r
-                $this->server_channels[$client_channel],\r
-                $this->packet_size_client_to_server[$client_channel],\r
-                $this->_string_shift($data, $this->packet_size_client_to_server[$client_channel])\r
-            );\r
-\r
-            if (!$this->_send_binary_packet($packet)) {\r
-                return false;\r
-            }\r
-        }\r
-\r
-        // resize the window, if appropriate\r
-        $this->window_size_client_to_server[$client_channel]-= strlen($data);\r
-        if ($this->window_size_client_to_server[$client_channel] < 0) {\r
-            $packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$client_channel], $this->window_size);\r
-            if (!$this->_send_binary_packet($packet)) {\r
-                return false;\r
-            }\r
-            $this->window_size_client_to_server[$client_channel]+= $this->window_size;\r
-        }\r
-\r
-        return $this->_send_binary_packet(pack('CN2a*',\r
-            NET_SSH2_MSG_CHANNEL_DATA,\r
-            $this->server_channels[$client_channel],\r
-            strlen($data),\r
-            $data));\r
-    }\r
-\r
-    /**\r
-     * Disconnect\r
-     *\r
-     * @param Integer $reason\r
-     * @return Boolean\r
-     * @access private\r
-     */\r
-    function _disconnect($reason)\r
-    {\r
-        if ($this->bitmap) {\r
-            $data = pack('CNNa*Na*', NET_SSH2_MSG_DISCONNECT, $reason, 0, '', 0, '');\r
-            $this->_send_binary_packet($data);\r
-            $this->bitmap = 0;\r
-            fclose($this->fsock);\r
-            return false;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * String Shift\r
-     *\r
-     * Inspired by array_shift\r
-     *\r
-     * @param String $string\r
-     * @param optional Integer $index\r
-     * @return String\r
-     * @access private\r
-     */\r
-    function _string_shift(&$string, $index = 1)\r
-    {\r
-        $substr = substr($string, 0, $index);\r
-        $string = substr($string, $index);\r
-        return $substr;\r
-    }\r
-\r
-    /**\r
-     * Define Array\r
-     *\r
-     * Takes any number of arrays whose indices are integers and whose values are strings and defines a bunch of\r
-     * named constants from it, using the value as the name of the constant and the index as the value of the constant.\r
-     * If any of the constants that would be defined already exists, none of the constants will be defined.\r
-     *\r
-     * @param Array $array\r
-     * @access private\r
-     */\r
-    function _define_array()\r
-    {\r
-        $args = func_get_args();\r
-        foreach ($args as $arg) {\r
-            foreach ($arg as $key=>$value) {\r
-                if (!defined($value)) {\r
-                    define($value, $key);\r
-                } else {\r
-                    break 2;\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Returns a log of the packets that have been sent and received.\r
-     *\r
-     * Returns a string if NET_SSH2_LOGGING == NET_SSH2_LOG_COMPLEX, an array if NET_SSH2_LOGGING == NET_SSH2_LOG_SIMPLE and false if !defined('NET_SSH2_LOGGING')\r
-     *\r
-     * @access public\r
-     * @return String or Array\r
-     */\r
-    function getLog()\r
-    {\r
-        if (!defined('NET_SSH2_LOGGING')) {\r
-            return false;\r
-        }\r
-\r
-        switch (NET_SSH2_LOGGING) {\r
-            case NET_SSH2_LOG_SIMPLE:\r
-                return $this->message_number_log;\r
-                break;\r
-            case NET_SSH2_LOG_COMPLEX:\r
-                return $this->_format_log($this->message_log, $this->message_number_log);\r
-                break;\r
-            default:\r
-                return false;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Formats a log for printing\r
-     *\r
-     * @param Array $message_log\r
-     * @param Array $message_number_log\r
-     * @access private\r
-     * @return String\r
-     */\r
-    function _format_log($message_log, $message_number_log)\r
-    {\r
-        static $boundary = ':', $long_width = 65, $short_width = 16;\r
-\r
-        $output = '';\r
-        for ($i = 0; $i < count($message_log); $i++) {\r
-            $output.= $message_number_log[$i] . "\r\n";\r
-            $current_log = $message_log[$i];\r
-            $j = 0;\r
-            do {\r
-                if (!empty($current_log)) {\r
-                    $output.= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0  ';\r
-                }\r
-                $fragment = $this->_string_shift($current_log, $short_width);\r
-                $hex = substr(\r
-                           preg_replace(\r
-                               '#(.)#es',\r
-                               '"' . $boundary . '" . str_pad(dechex(ord(substr("\\1", -1))), 2, "0", STR_PAD_LEFT)',\r
-                               $fragment),\r
-                           strlen($boundary)\r
-                       );\r
-                // replace non ASCII printable characters with dots\r
-                // http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters\r
-                // also replace < with a . since < messes up the output on web browsers\r
-                $raw = preg_replace('#[^\x20-\x7E]|<#', '.', $fragment);\r
-                $output.= str_pad($hex, $long_width - $short_width, ' ') . $raw . "\r\n";\r
-                $j++;\r
-            } while (!empty($current_log));\r
-            $output.= "\r\n";\r
-        }\r
-\r
-        return $output;\r
-    }\r
-\r
-    /**\r
-     * Returns all errors\r
-     *\r
-     * @return String\r
-     * @access public\r
-     */\r
-    function getErrors()\r
-    {\r
-        return $this->errors;\r
-    }\r
-\r
-    /**\r
-     * Returns the last error\r
-     *\r
-     * @return String\r
-     * @access public\r
-     */\r
-    function getLastError()\r
-    {\r
-        return $this->errors[count($this->errors) - 1];\r
-    }\r
-\r
-    /**\r
-     * Return the server identification.\r
-     *\r
-     * @return String\r
-     * @access public\r
-     */\r
-    function getServerIdentification()\r
-    {\r
-        return $this->server_identifier;\r
-    }\r
-\r
-    /**\r
-     * Return a list of the key exchange algorithms the server supports.\r
-     *\r
-     * @return Array\r
-     * @access public\r
-     */\r
-    function getKexAlgorithms()\r
-    {\r
-        return $this->kex_algorithms;\r
-    }\r
-\r
-    /**\r
-     * Return a list of the host key (public key) algorithms the server supports.\r
-     *\r
-     * @return Array\r
-     * @access public\r
-     */\r
-    function getServerHostKeyAlgorithms()\r
-    {\r
-        return $this->server_host_key_algorithms;\r
-    }\r
-\r
-    /**\r
-     * Return a list of the (symmetric key) encryption algorithms the server supports, when receiving stuff from the client.\r
-     *\r
-     * @return Array\r
-     * @access public\r
-     */\r
-    function getEncryptionAlgorithmsClient2Server()\r
-    {\r
-        return $this->encryption_algorithms_client_to_server;\r
-    }\r
-\r
-    /**\r
-     * Return a list of the (symmetric key) encryption algorithms the server supports, when sending stuff to the client.\r
-     *\r
-     * @return Array\r
-     * @access public\r
-     */\r
-    function getEncryptionAlgorithmsServer2Client()\r
-    {\r
-        return $this->encryption_algorithms_server_to_client;\r
-    }\r
-\r
-    /**\r
-     * Return a list of the MAC algorithms the server supports, when receiving stuff from the client.\r
-     *\r
-     * @return Array\r
-     * @access public\r
-     */\r
-    function getMACAlgorithmsClient2Server()\r
-    {\r
-        return $this->mac_algorithms_client_to_server;\r
-    }\r
-\r
-    /**\r
-     * Return a list of the MAC algorithms the server supports, when sending stuff to the client.\r
-     *\r
-     * @return Array\r
-     * @access public\r
-     */\r
-    function getMACAlgorithmsServer2Client()\r
-    {\r
-        return $this->mac_algorithms_server_to_client;\r
-    }\r
-\r
-    /**\r
-     * Return a list of the compression algorithms the server supports, when receiving stuff from the client.\r
-     *\r
-     * @return Array\r
-     * @access public\r
-     */\r
-    function getCompressionAlgorithmsClient2Server()\r
-    {\r
-        return $this->compression_algorithms_client_to_server;\r
-    }\r
-\r
-    /**\r
-     * Return a list of the compression algorithms the server supports, when sending stuff to the client.\r
-     *\r
-     * @return Array\r
-     * @access public\r
-     */\r
-    function getCompressionAlgorithmsServer2Client()\r
-    {\r
-        return $this->compression_algorithms_server_to_client;\r
-    }\r
-\r
-    /**\r
-     * Return a list of the languages the server supports, when sending stuff to the client.\r
-     *\r
-     * @return Array\r
-     * @access public\r
-     */\r
-    function getLanguagesServer2Client()\r
-    {\r
-        return $this->languages_server_to_client;\r
-    }\r
-\r
-    /**\r
-     * Return a list of the languages the server supports, when receiving stuff from the client.\r
-     *\r
-     * @return Array\r
-     * @access public\r
-     */\r
-    function getLanguagesClient2Server()\r
-    {\r
-        return $this->languages_client_to_server;\r
-    }\r
-\r
-    /**\r
-     * Returns the server public host key.\r
-     *\r
-     * Caching this the first time you connect to a server and checking the result on subsequent connections\r
-     * is recommended.  Returns false if the server signature is not signed correctly with the public host key.\r
-     *\r
-     * @return Mixed\r
-     * @access public\r
-     */\r
-    function getServerPublicHostKey()\r
-    {\r
-        $signature = $this->signature;\r
-        $server_public_host_key = $this->server_public_host_key;\r
-\r
-        extract(unpack('Nlength', $this->_string_shift($server_public_host_key, 4)));\r
-        $this->_string_shift($server_public_host_key, $length);\r
-\r
-        switch ($this->signature_format) {\r
-            case 'ssh-dss':\r
-                $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));\r
-                $p = new Math_BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);\r
-\r
-                $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));\r
-                $q = new Math_BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);\r
-\r
-                $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));\r
-                $g = new Math_BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);\r
-\r
-                $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));\r
-                $y = new Math_BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);\r
-\r
-                /* The value for 'dss_signature_blob' is encoded as a string containing\r
-                   r, followed by s (which are 160-bit integers, without lengths or\r
-                   padding, unsigned, and in network byte order). */\r
-                $temp = unpack('Nlength', $this->_string_shift($signature, 4));\r
-                if ($temp['length'] != 40) {\r
-                    user_error('Invalid signature', E_USER_NOTICE);\r
-                    return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);\r
-                }\r
-\r
-                $r = new Math_BigInteger($this->_string_shift($signature, 20), 256);\r
-                $s = new Math_BigInteger($this->_string_shift($signature, 20), 256);\r
-\r
-                if ($r->compare($q) >= 0 || $s->compare($q) >= 0) {\r
-                    user_error('Invalid signature', E_USER_NOTICE);\r
-                    return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);\r
-                }\r
-\r
-                $w = $s->modInverse($q);\r
-\r
-                $u1 = $w->multiply(new Math_BigInteger(sha1($this->session_id), 16));\r
-                list(, $u1) = $u1->divide($q);\r
-\r
-                $u2 = $w->multiply($r);\r
-                list(, $u2) = $u2->divide($q);\r
-\r
-                $g = $g->modPow($u1, $p);\r
-                $y = $y->modPow($u2, $p);\r
-\r
-                $v = $g->multiply($y);\r
-                list(, $v) = $v->divide($p);\r
-                list(, $v) = $v->divide($q);\r
-\r
-                if (!$v->equals($r)) {\r
-                    user_error('Bad server signature', E_USER_NOTICE);\r
-                    return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);\r
-                }\r
-\r
-                break;\r
-            case 'ssh-rsa':\r
-                $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));\r
-                $e = new Math_BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);\r
-\r
-                $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));\r
-                $n = new Math_BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);\r
-                $nLength = $temp['length'];\r
-\r
-                /*\r
-                $temp = unpack('Nlength', $this->_string_shift($signature, 4));\r
-                $signature = $this->_string_shift($signature, $temp['length']);\r
-\r
-                if (!class_exists('Crypt_RSA')) {\r
-                    require_once('Crypt/RSA.php');\r
-                }\r
-\r
-                $rsa = new Crypt_RSA();\r
-                $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);\r
-                $rsa->loadKey(array('e' => $e, 'n' => $n), CRYPT_RSA_PUBLIC_FORMAT_RAW);\r
-                if (!$rsa->verify($this->session_id, $signature)) {\r
-                    user_error('Bad server signature', E_USER_NOTICE);\r
-                    return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);\r
-                }\r
-                */\r
-\r
-                $temp = unpack('Nlength', $this->_string_shift($signature, 4));\r
-                $s = new Math_BigInteger($this->_string_shift($signature, $temp['length']), 256);\r
-\r
-                // validate an RSA signature per "8.2 RSASSA-PKCS1-v1_5", "5.2.2 RSAVP1", and "9.1 EMSA-PSS" in the\r
-                // following URL:\r
-                // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf\r
-\r
-                // also, see SSHRSA.c (rsa2_verifysig) in PuTTy's source.\r
-\r
-                if ($s->compare(new Math_BigInteger()) < 0 || $s->compare($n->subtract(new Math_BigInteger(1))) > 0) {\r
-                    user_error('Invalid signature', E_USER_NOTICE);\r
-                    return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);\r
-                }\r
-\r
-                $s = $s->modPow($e, $n);\r
-                $s = $s->toBytes();\r
-\r
-                $h = pack('N4H*', 0x00302130, 0x0906052B, 0x0E03021A, 0x05000414, sha1($this->session_id));\r
-                $h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 3 - strlen($h)) . $h;\r
-\r
-                if ($s != $h) {\r
-                    user_error('Bad server signature', E_USER_NOTICE);\r
-                    return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);\r
-                }\r
-        }\r
-\r
-        return $this->server_public_host_key;\r
-    }\r
-}
\ No newline at end of file
diff --git a/library/phpsec/PHP/Compat/Function/array_fill.php b/library/phpsec/PHP/Compat/Function/array_fill.php
deleted file mode 100644 (file)
index e02bfa1..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php\r
-// $Id: array_fill.php,v 1.1 2007/07/02 04:19:55 terrafrost Exp $\r
-\r
-\r
-/**\r
- * Replace array_fill()\r
- *\r
- * @category    PHP\r
- * @package     PHP_Compat\r
- * @license     LGPL - http://www.gnu.org/licenses/lgpl.html\r
- * @copyright   2004-2007 Aidan Lister <aidan@php.net>, Arpad Ray <arpad@php.net>\r
- * @link        http://php.net/function.array_fill\r
- * @author      Jim Wigginton <terrafrost@php.net>\r
- * @version     $Revision: 1.1 $\r
- * @since       PHP 4.2.0\r
- */\r
-function php_compat_array_fill($start_index, $num, $value)\r
-{\r
-    if ($num <= 0) {\r
-        user_error('array_fill(): Number of elements must be positive', E_USER_WARNING);\r
-\r
-        return false;\r
-    }\r
-\r
-    $temp = array();\r
-\r
-    $end_index = $start_index + $num;\r
-    for ($i = (int) $start_index; $i < $end_index; $i++) {\r
-        $temp[$i] = $value;\r
-    }\r
-\r
-    return $temp;\r
-}\r
-\r
-// Define\r
-if (!function_exists('array_fill')) {\r
-    function array_fill($start_index, $num, $value)\r
-    {\r
-        return php_compat_array_fill($start_index, $num, $value);\r
-    }\r
-}\r
-\r
-?>
\ No newline at end of file
diff --git a/library/phpsec/PHP/Compat/Function/bcpowmod.php b/library/phpsec/PHP/Compat/Function/bcpowmod.php
deleted file mode 100644 (file)
index 6ec1b18..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-<?php\r
-// $Id: bcpowmod.php,v 1.1 2007/07/02 04:19:55 terrafrost Exp $\r
-\r
-\r
-/**\r
- * Replace bcpowmod()\r
- *\r
- * @category    PHP\r
- * @package     PHP_Compat\r
- * @license     LGPL - http://www.gnu.org/licenses/lgpl.html\r
- * @copyright   2004-2007 Aidan Lister <aidan@php.net>, Arpad Ray <arpad@php.net>\r
- * @link        http://php.net/function.bcpowmod\r
- * @author      Sara Golemon <pollita@php.net>\r
- * @version     $Revision: 1.1 $\r
- * @since       PHP 5.0.0\r
- * @require     PHP 4.0.0 (user_error)\r
- */\r
-function php_compat_bcpowmod($x, $y, $modulus, $scale = 0)\r
-{\r
-    // Sanity check\r
-    if (!is_scalar($x)) {\r
-        user_error('bcpowmod() expects parameter 1 to be string, ' .\r
-            gettype($x) . ' given', E_USER_WARNING);\r
-        return false;\r
-    }\r
-\r
-    if (!is_scalar($y)) {\r
-        user_error('bcpowmod() expects parameter 2 to be string, ' .\r
-            gettype($y) . ' given', E_USER_WARNING);\r
-        return false;\r
-    }\r
-\r
-    if (!is_scalar($modulus)) {\r
-        user_error('bcpowmod() expects parameter 3 to be string, ' .\r
-            gettype($modulus) . ' given', E_USER_WARNING);\r
-        return false;\r
-    }\r
-\r
-    if (!is_scalar($scale)) {\r
-        user_error('bcpowmod() expects parameter 4 to be integer, ' .\r
-            gettype($scale) . ' given', E_USER_WARNING);\r
-        return false;\r
-    }\r
-\r
-    $t = '1';\r
-    while (bccomp($y, '0')) {\r
-        if (bccomp(bcmod($y, '2'), '0')) {\r
-            $t = bcmod(bcmul($t, $x), $modulus);\r
-            $y = bcsub($y, '1');\r
-        }\r
-\r
-        $x = bcmod(bcmul($x, $x), $modulus);\r
-        $y = bcdiv($y, '2');\r
-    }\r
-\r
-    return $t;    \r
-}\r
-\r
-\r
-// Define\r
-if (!function_exists('bcpowmod')) {\r
-    function bcpowmod($x, $y, $modulus, $scale = 0)\r
-    {\r
-        return php_compat_bcpowmod($x, $y, $modulus, $scale);\r
-    }\r
-}\r
-?>
\ No newline at end of file
diff --git a/library/phpsec/PHP/Compat/Function/str_split.php b/library/phpsec/PHP/Compat/Function/str_split.php
deleted file mode 100644 (file)
index 8e38bdb..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-<?php\r
-/**\r
- * Replace str_split()\r
- *\r
- * @category    PHP\r
- * @package     PHP_Compat\r
- * @license     LGPL - http://www.gnu.org/licenses/lgpl.html\r
- * @copyright   2004-2007 Aidan Lister <aidan@php.net>, Arpad Ray <arpad@php.net>\r
- * @link        http://php.net/function.str_split\r
- * @author      Aidan Lister <aidan@php.net>\r
- * @version     $Revision: 1.1 $\r
- * @since       PHP 5\r
- * @require     PHP 4.0.0 (user_error)\r
- */\r
-function php_compat_str_split($string, $split_length = 1)\r
-{\r
-    if (!is_scalar($split_length)) {\r
-        user_error('str_split() expects parameter 2 to be long, ' .\r
-            gettype($split_length) . ' given', E_USER_WARNING);\r
-        return false;\r
-    }\r
-\r
-    $split_length = (int) $split_length;\r
-    if ($split_length < 1) {\r
-        user_error('str_split() The length of each segment must be greater than zero', E_USER_WARNING);\r
-        return false;\r
-    }\r
-    \r
-    // Select split method\r
-    if ($split_length < 65536) {\r
-        // Faster, but only works for less than 2^16\r
-        preg_match_all('/.{1,' . $split_length . '}/s', $string, $matches);\r
-        return $matches[0];\r
-    } else {\r
-        // Required due to preg limitations\r
-        $arr = array();\r
-        $idx = 0;\r
-        $pos = 0;\r
-        $len = strlen($string);\r
-\r
-        while ($len > 0) {\r
-            $blk = ($len < $split_length) ? $len : $split_length;\r
-            $arr[$idx++] = substr($string, $pos, $blk);\r
-            $pos += $blk;\r
-            $len -= $blk;\r
-        }\r
-\r
-        return $arr;\r
-    }\r
-}\r
-\r
-\r
-// Define\r
-if (!function_exists('str_split')) {\r
-    function str_split($string, $split_length = 1)\r
-    {\r
-        return php_compat_str_split($string, $split_length);\r
-    }\r
-}\r
diff --git a/library/phpsec/crypt.html b/library/phpsec/crypt.html
deleted file mode 100644 (file)
index 6720cf7..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 3. Cryptography</title><link rel="stylesheet" href="docbook.css" type="text/css" /><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><link rel="start" href="index.html" title="PHP Secure Communications Library" /><link rel="up" href="index.html" title="PHP Secure Communications Library" /><link rel="prev" href="math.html" title="Chapter 2. Math" /><link rel="next" href="net.html" title="Chapter 4. Networking" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 3. Cryptography</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="math.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="net.html">Next</a></td></tr></table><hr /></div><div class="chapter" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="crypt"></a>Chapter 3. Cryptography</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="crypt.html#crypt_intro">3.1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="crypt.html#crypt_dependencies">3.1.1. Dependencies</a></span></dt><dt><span class="section"><a href="crypt.html#crypt_set">3.1.2. setKey() and setIV()</a></span></dt><dt><span class="section"><a href="crypt.html#crypt_setmcrypt">3.1.3. setMCrypt()</a></span></dt><dt><span class="section"><a href="crypt.html#crypt_encrypt">3.1.4. encrypt() and decrypt()</a></span></dt><dt><span class="section"><a href="crypt.html#crypt_continuousbuffer">3.1.5. enableContinuousBuffer() and disableContinuousBuffer()</a></span></dt><dt><span class="section"><a href="crypt.html#crypt_padding">3.1.6. enablePadding() and disablePadding()</a></span></dt></dl></dd><dt><span class="section"><a href="crypt.html#crypt_des">3.2. Crypt_DES</a></span></dt><dd><dl><dt><span class="section"><a href="crypt.html#crypt_des_constructor">3.2.1. The constructor</a></span></dt></dl></dd><dt><span class="section"><a href="crypt.html#crypt_tripledes">3.3. Crypt_TripleDES</a></span></dt><dd><dl><dt><span class="section"><a href="crypt.html#crypt_tripledes_constructor">3.3.1. The constructor</a></span></dt></dl></dd><dt><span class="section"><a href="crypt.html#crypt_rc4">3.4. Crypt_RC4</a></span></dt><dd><dl><dt><span class="section"><a href="crypt.html#crypt_rc4_constructor">3.4.1. The constructor</a></span></dt></dl></dd><dt><span class="section"><a href="crypt.html#crypt_aes">3.5. Crypt_Rijndael &amp; Crypt_AES</a></span></dt><dd><dl><dt><span class="section"><a href="crypt.html#crypt_aes_constructor">3.5.1. The constructor</a></span></dt><dt><span class="section"><a href="crypt.html#crypt_aes_vs_rijndael">3.5.2. AES vs. Rijndael</a></span></dt><dt><span class="section"><a href="crypt.html#crypt_aes_setkeylength">3.5.3. setKeyLength()</a></span></dt><dt><span class="section"><a href="crypt.html#crypt_aes_setblocklength">3.5.4. setBlockLength()</a></span></dt><dt><span class="section"><a href="crypt.html#crypt_aes_benchmarks">3.5.5. Speed Comparisons</a></span></dt></dl></dd></dl></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="crypt_intro"></a>3.1. Introduction</h2></div></div></div><p>
-                All of the cryptographic libraries included in phpseclib use mcrypt, if available, and an internal implementation 
-                if it's not.  The libraries all use a common interface although some functions, for some algorithms, carry with 
-                with them certain caveats.  Those that do not have caveats attached (or have relatively few attached) are 
-                described below.  If you don't know which one to use, try <code class="code">Crypt_TripleDES</code>.
-            </p><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="crypt_dependencies"></a>3.1.1. Dependencies</h3></div></div></div><p>
-                    The Crypt_* functions require, minimally, PHP 4.0.0.  Crypt_TripleDES additionally requires Crypt/DES.php.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="crypt_set"></a>3.1.2. setKey() and setIV()</h3></div></div></div><p>
-                    Sets the key and the initialization vector, respectively.  If neither are set, each assumed to be equal to 
-                    some amount of null bytes.  The initialization vector is only used in block ciphers and even then only 
-                    in CBC mode.  If the key or the initialization vector are larger then the block size, they're truncated.
-                    If they're smaller, they're padded with null bytes.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="crypt_setmcrypt"></a>3.1.3. setMCrypt()</h3></div></div></div><p>
-                    See php.net's entry on <a class="ulink" href="http://php.net/function.mcrypt-module-open#function.mcrypt-module-open" target="_top">mcrypt_module_open</a>.
-                    The first parameter is equal to <code class="code">$algorithm_directory</code> and the second, to <code class="code">$mode_directory</code>.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="crypt_encrypt"></a>3.1.4. encrypt() and decrypt()</h3></div></div></div><p>
-                    Self-explanatory.  Encrypts or decrypts messages.  See the examples in the subsequent sections.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="crypt_continuousbuffer"></a>3.1.5. enableContinuousBuffer() and disableContinuousBuffer()</h3></div></div></div><p>
-                    Say you have a 16-byte plaintext $plaintext and that you're using <code class="code">Crypt_DES</code>.  Using the default behavior, the two following code snippets
-                    will yield different outputs:
-                </p><pre class="programlisting">    echo $des-&gt;encrypt(substr($plaintext, 0, 8));
-    echo $des-&gt;encrypt(substr($plaintext, 8, 8));</pre><pre class="programlisting">    echo $des-&gt;encrypt($plaintext);</pre><p>
-                    The solution is to enable the continuous buffer.  Although this will resolve the above discrepancy, it creates
-                    another, as demonstrated with the following:
-                </p><pre class="programlisting">    $des-&gt;encrypt(substr($plaintext, 0, 8));
-    echo $des-&gt;decrypt($des-&gt;encrypt(substr($plaintext, 8, 8)));</pre><pre class="programlisting">    echo $des-&gt;decrypt($des-&gt;encrypt(substr($plaintext, 8, 8)));</pre><p>
-                    With the continuous buffer disabled, these would yield the same output.  With it enabled, they yield different
-                    outputs.  The reason is due to the fact that the initialization vector's change after every encryption /
-                    decryption round when the continuous buffer is enabled.  When it's disabled, they remain constant.
-
-                    Put another way, when the continuous buffer is enabled, the state of the <code class="code">Crypt_DES()</code> object changes after each
-                    encryption / decryption round, whereas otherwise, it'd remain constant.  For this reason, it's recommended that
-                    continuous buffers not be used.  They do offer better security and are, in fact, sometimes required (SSH uses them),
-                    however, they are also less intuitive and more likely to cause you problems.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="crypt_padding"></a>3.1.6. enablePadding() and disablePadding()</h3></div></div></div><p>
-                    Enables / disables PKCS padding on block ciphers.  Stream ciphers (<code class="code">Crypt_RC4</code> is the only stream
-                    cipher currently included) ignore this.
-                </p></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="crypt_des"></a>3.2. Crypt_DES</h2></div></div></div><p>
-                Implements DES (a block cipher).  Here's an example of how to use it:
-            </p><pre class="programlisting">&lt;?php
-    include('Crypt/DES.php');
-
-    $des = new Crypt_DES();
-
-    $des-&gt;setKey('abcdefgh');
-
-    $size = 10 * 1024;
-    $plaintext = '';
-    for ($i = 0; $i &lt; $size; $i++) {
-        $plaintext.= 'a';
-    }
-
-    echo $des-&gt;decrypt($des-&gt;encrypt($plaintext));
-?&gt;</pre><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="crypt_des_constructor"></a>3.2.1. The constructor</h3></div></div></div><p>
-                    The constructor takes one optional parameter - $mode.  $mode can be equal to <code class="code">CRYPT_DES_MODE_ECB</code>
-                    or <code class="code">CRYPT_DES_MODE_CBC</code>.  <code class="code">CRYPT_DES_MODE_CBC</code> is generally considered more secure 
-                    and is what <code class="code">Crypt_DES</code> uses by default.  If you don't know the difference between ECB or CBC, 
-                    just use the default settings.
-                </p></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="crypt_tripledes"></a>3.3. Crypt_TripleDES</h2></div></div></div><p>
-                Implements TripleDES (a block cipher).  Here's an example of how to use it:
-            </p><pre class="programlisting">&lt;?php
-    include('Crypt/TripleDES.php');
-
-    $des = new Crypt_TripleDES();
-
-    $des-&gt;setKey('abcdefghijklmnopqrstuvwx');
-
-    $size = 10 * 1024;
-    $plaintext = '';
-    for ($i = 0; $i &lt; $size; $i++) {
-        $plaintext.= 'a';
-    }
-
-    echo $des-&gt;decrypt($des-&gt;encrypt($plaintext));
-?&gt;</pre><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="crypt_tripledes_constructor"></a>3.3.1. The constructor</h3></div></div></div><p>
-                    The constructor takes one optional parameter - $mode.  $mode can be equal to <code class="code">CRYPT_DES_MODE_ECB</code>,
-                    <code class="code">CRYPT_DES_MODE_CBC</code>, <code class="code">CRYPT_DES_MODE_3CBC</code>, or <code class="code">CRYPT_DES_MODE_CBC3</code>.
-                    <code class="code">CRYPT_DES_MODE_CBC3</code> is an alias <code class="code">CRYPT_DES_MODE_CBC</code>.  It's defined to distinguish
-                    it from <code class="code">CRYPT_DES_MODE_3CBC</code>, which uses inner chaining to propogate the initialization vector.
-                    SSH-1 uses this and it is generally considered to be less secure then <code class="code">CRYPT_DES_MODE_CBC3</code>, 
-                    which uses outer chaining (and is what SSH-2 uses).
-                </p></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="crypt_rc4"></a>3.4. Crypt_RC4</h2></div></div></div><p>
-                Implements RC4 (a stream cipher).  Here's an example of how to use it:
-            </p><pre class="programlisting">&lt;?php
-    include('Crypt/RC4.php');
-
-    $rc4 = new Crypt_RC4();
-
-    $rc4-&gt;setKey('abcdefghijklmnopqrstuvwx');
-
-    $size = 10 * 1024;
-    $plaintext = '';
-    for ($i = 0; $i &lt; $size; $i++) {
-        $plaintext.= 'a';
-    }
-
-    echo $rc4-&gt;decrypt($rc4-&gt;encrypt($plaintext));
-?&gt;</pre><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="crypt_rc4_constructor"></a>3.4.1. The constructor</h3></div></div></div><p>
-                    Not much to say about this constructor.  Since it's a stream cipher, you don't need to worry about which
-                    mode of operation to use.
-                </p></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="crypt_aes"></a>3.5. Crypt_Rijndael &amp; Crypt_AES</h2></div></div></div><p>
-                Implements Rijndael / AES.  Here's an example of how to use Crypt_AES:
-            </p><pre class="programlisting">&lt;?php
-    include('Crypt/AES.php');
-
-    $aes = new Crypt_AES();
-
-    $aes-&gt;setKey('abcdefghijklmnop');
-
-    $size = 10 * 1024;
-    $plaintext = '';
-    for ($i = 0; $i &lt; $size; $i++) {
-        $plaintext.= 'a';
-    }
-
-    echo $aes-&gt;decrypt($aes-&gt;encrypt($plaintext));
-?&gt;</pre><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="crypt_aes_constructor"></a>3.5.1. The constructor</h3></div></div></div><p>
-                    <code class="code">Crypt_AES</code>'s constructor takes <code class="code">CRYPT_AES_MODE_ECB</code> and <code class="code">CRYPT_AES_MODE_CBC</code> as parameters.  <code class="code">Crypt_Rijndael</code>, <code class="code">CRYPT_RIJNDAEL_MODE_ECB</code> and <code class="code">CRYPT_RIJNDAEL_MODE_CBC</code>.  In both cases, if no valid mode is defined, CBC will be used.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="crypt_aes_vs_rijndael"></a>3.5.2. AES vs. Rijndael</h3></div></div></div><p>
-                    AES is a subset of Rijndael.  Both have variable key sizes, however, AES's block size is fixed at 128 bytes, whereas Rijndael's is variable.  Also, Rijndael supports, by means of an extension to the specification, two key sizes that AES does not - 160 bits and 224 bits.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="crypt_aes_setkeylength"></a>3.5.3. setKeyLength()</h3></div></div></div><p>
-                    Valid key lengths for AES are 128 bits, 192 bits, and 256 bits.  If the key that is assigned is invalid and less than 256 bits, they key length is rounded up to the next closest valid size and the key will be null padded to that amount.  If the key length is greater than 256 bits, it will be truncated to 256 bits.
-                </p><p>
-                    As an example, if the key is 136 bits, it will be null padded to 192 bits (or 160 bits if Rijndael is being used).
-                </p><p>
-                    If <code class="code">setKeyLength()</code> has been called, this behavior changes somewhat.  Say you've set the key length, via this function, to 256 bits.  Then, instead of an invalid key being null padded to 192 or 160 bits, it will be null padded to 256 bits.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="crypt_aes_setblocklength"></a>3.5.4. setBlockLength()</h3></div></div></div><p>
-                    <code class="code">setBlockLength()</code> operates in a manner similar to <code class="code">setKeyLength()</code>, with one exception.  <code class="code">setBlockLength()</code> only works on Rijndael.  Although <code class="code">Crypt_AES</code> inherits <code class="code">setBlockLength()</code> as a function, the function doesn't do anything in AES.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="crypt_aes_benchmarks"></a>3.5.5. Speed Comparisons</h3></div></div></div><p>
-                    The following table compares the speed of five different pure-PHP implementations of AES (one of which is Crypt_Rijndael and one of which is Crypt_AES) when ran on 150KB of text on a 1.8GHz Pentium 4-M.  The numbers listed are averaged from five different trials and are measured in seconds.  phpseclib's two implementations are highlighted.  All implementations can be viewed by clicking on their names.
-                </p><div class="table"><a id="crypt_aes_benchmarks_table"></a><p class="title"><b>Table 3.1. AES Speed Comparisons</b></p><div class="table-contents"><table summary="AES Speed Comparisons" border="1"><colgroup><col /><col /><col /><col /><col /></colgroup><thead><tr><th align="right"><a class="ulink" href="http://phpseclib.sourceforge.net/movable-type.phps" target="_top">movable-type.phps</a></th><th align="right"><a class="ulink" href="http://phpseclib.sourceforge.net/phpaes.phps" target="_top">phpaes.phps</a></th><th align="right"><a class="ulink" href="http://phpseclib.sourceforge.net/phpclasses1.phps" target="_top">phpclasses1.phps</a></th><th align="right"><a class="ulink" href="http://phpseclib.sourceforge.net/phpclasses2.phps" target="_top">phpclasses2.phps</a></th><th align="right"><a class="ulink" href="http://phpseclib.sourceforge.net/phpseclib-aes.phps" target="_top">phpseclib-aes.phps</a></th><th align="right"><a class="ulink" href="http://phpseclib.sourceforge.net/phpseclib-rijndael.phps" target="_top">phpseclib-rijndael.phps</a></th></tr></thead><tbody><tr><td align="right">15.6844158172</td><td align="right">39.9537248135</td><td align="right">15.0100150108</td><td align="right">62.591713190079</td><td class="highlight" align="right">3.5728311081</td><td class="highlight" align="right">5.24388728142</td></tr></tbody></table></div></div><br class="table-break" /><p>
-                    As can be seen, phpseclib's implementations are the fastest.  phpseclib-aes.phps is faster than phpseclib-rijndael.phps because phpseclib-rijndael.phps has to contend with multiple block sizes whereas phpseclib-aes.phps does not.
-                </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="math.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="net.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 2. Math </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 4. Networking</td></tr></table></div></body></html>
diff --git a/library/phpsec/docbook.css b/library/phpsec/docbook.css
deleted file mode 100644 (file)
index 4f67aa4..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-body {\r
-  font-family: Georgia, "Times New Roman", Times, serif\r
-}\r
-\r
-div.author h3 {\r
-  display: none\r
-}\r
-\r
-a {\r
-  text-decoration: none;\r
-  color: #369\r
-}\r
-\r
-a:hover {\r
-  text-decoration: underline\r
-}\r
-\r
-.programlisting {\r
-  font-family: Monaco, "Andale Mono","Courier New", Courier, mono;\r
-  font-size: 10pt\r
-}\r
-\r
-.programlisting, .code {\r
-  background: #eee;\r
-  color: #181;\r
-  font-weight: bold\r
-}\r
-\r
-.red {\r
-  color: #e11\r
-}\r
-\r
-.highlight {\r
-  background: #ee1\r
-}\r
-\r
-thead {\r
-  background: #ccc\r
-}\r
-\r
-#crypt_aes_benchmarks_table.tbody {\r
-  font-weight: bold\r
-}
\ No newline at end of file
diff --git a/library/phpsec/index.html b/library/phpsec/index.html
deleted file mode 100644 (file)
index 6dda0f3..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>PHP Secure Communications Library</title><link rel="stylesheet" href="docbook.css" type="text/css" /><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><meta name="description" content="The PHP Secure Communications Library contains LGPL-licensed pure-PHP implementations of arbitrary-precision integers, fully PKCS#1 (v2.1) compliant RSA, DES, 3DES, RC4, Rijndael, AES, SSH-1, SSH-2, and SFTP. This book discusses how to use them." /><link rel="start" href="index.html" title="PHP Secure Communications Library" /><link rel="next" href="intro.html" title="Chapter 1. Introduction" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">PHP <span class="red">Secure</span> Communications Library</th></tr><tr><td width="20%" align="left"> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="intro.html">Next</a></td></tr></table><hr /></div><div class="book" lang="en" xml:lang="en"><div class="titlepage"><div><div><h1 class="title"><a id="id440772"></a>PHP <span class="red">Secure</span> Communications Library</h1></div><div><div class="author"><h3 class="author"><span class="firstname">Jim</span> <span class="othername">TerraFrost</span> <span class="surname">Wigginton</span></h3></div></div><div><p class="copyright">Copyright © 2007 - 2010 TerraFrost (Jim Wigginton)</p></div><div><div class="abstract"><p class="title"><b>Abstract</b></p><p>
-                The PHP Secure Communications Library contains LGPL-licensed pure-PHP implementations of arbitrary-precision integers, 
-                fully PKCS#1 (v2.1) compliant RSA, DES, 3DES, RC4, Rijndael, AES, SSH-1, SSH-2, and SFTP.  This book discusses how to use them.</p></div></div></div><hr /></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="chapter"><a href="intro.html">1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="intro.html#intro_intro">1.1. Who should use phpseclib</a></span></dt><dt><span class="section"><a href="intro.html#intro_usage">1.2. Using phpseclib</a></span></dt></dl></dd><dt><span class="chapter"><a href="math.html">2. Math</a></span></dt><dd><dl><dt><span class="section"><a href="math.html#math_biginteger">2.1. Math_BigInteger</a></span></dt><dd><dl><dt><span class="section"><a href="math.html#math_biginteger_dependencies">2.1.1. Dependencies</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_constructor">2.1.2. The constructor</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_output">2.1.3. toString(), toBytes(), toHex() and toBits()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_fourfunctions">2.1.4. add(), subtract(), multiply() and divide()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_modulo">2.1.5. powMod() and modInverse()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_gcd">2.1.6. gcd() and extendedGCD()</a></span></dt><dt><span class="section"><a href="math.html#math_abs">2.1.7. abs()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_compare">2.1.8. equals() and compare()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_precision">2.1.9. setPrecision()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_bitwise">2.1.10. bitwise_and(), bitwise_or(), bitwise_xor() and bitwise_not()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_shifts">2.1.11. bitwise_rightShift() and bitwise_leftShift()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_rotates">2.1.12. bitwise_rightRotate() and bitwise_leftRotate()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_setrandom">2.1.13. setRandomGenerator()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_prime">2.1.14. isPrime()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_random">2.1.15. random() and randomPrime()</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="sym_crypt.html">3. Symmetric-key Cryptography</a></span></dt><dd><dl><dt><span class="section"><a href="sym_crypt.html#sym_crypt_intro">3.1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="sym_crypt.html#sym_crypt_dependencies">3.1.1. Dependencies</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_set">3.1.2. setKey() and setIV()</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_encrypt">3.1.3. encrypt() and decrypt()</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_continuousbuffer">3.1.4. enableContinuousBuffer() and disableContinuousBuffer()</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_padding">3.1.5. enablePadding() and disablePadding()</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_caution">3.1.6. A word of caution about stream ciphers and CTR mode</a></span></dt></dl></dd><dt><span class="section"><a href="sym_crypt.html#sym_crypt_des">3.2. Crypt_DES</a></span></dt><dd><dl><dt><span class="section"><a href="sym_crypt.html#sym_crypt_des_constructor">3.2.1. The constructor</a></span></dt></dl></dd><dt><span class="section"><a href="sym_crypt.html#sym_crypt_tripledes">3.3. Crypt_TripleDES</a></span></dt><dd><dl><dt><span class="section"><a href="sym_crypt.html#sym_crypt_tripledes_constructor">3.3.1. The constructor</a></span></dt></dl></dd><dt><span class="section"><a href="sym_crypt.html#sym_crypt_rc4">3.4. Crypt_RC4</a></span></dt><dd><dl><dt><span class="section"><a href="sym_crypt.html#sym_crypt_rc4_constructor">3.4.1. The constructor</a></span></dt></dl></dd><dt><span class="section"><a href="sym_crypt.html#sym_crypt_aes">3.5. Crypt_Rijndael &amp; Crypt_AES</a></span></dt><dd><dl><dt><span class="section"><a href="sym_crypt.html#sym_crypt_aes_constructor">3.5.1. The constructor</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_aes_vs_rijndael">3.5.2. AES vs. Rijndael</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_aes_setkeylength">3.5.3. setKeyLength()</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_aes_setblocklength">3.5.4. setBlockLength()</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_aes_benchmarks">3.5.5. Speed Comparisons</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="misc_crypt.html">4. Miscellaneous Cryptography</a></span></dt><dd><dl><dt><span class="section"><a href="misc_crypt.html#misc_crypt_hash">4.1. Crypt_Hash</a></span></dt><dd><dl><dt><span class="section"><a href="misc_crypt.html#misc_crypt_hash_supported">4.1.1. Supported Algorithms and Dependencies</a></span></dt><dt><span class="section"><a href="misc_crypt.html#misc_crypt_hash_example">4.1.2. Example</a></span></dt></dl></dd><dt><span class="section"><a href="misc_crypt.html#misc_crypt_rsa">4.2. Crypt_RSA</a></span></dt><dd><dl><dt><span class="section"><a href="misc_crypt.html#misc_crypt_rsa_dependencies">4.2.1. Dependencies</a></span></dt><dt><span class="section"><a href="misc_crypt.html#misc_crypt_rsa_examples">4.2.2. Examples</a></span></dt><dt><span class="section"><a href="misc_crypt.html#misc_crypt_rsa_createkey">4.2.3. createKey()</a></span></dt><dt><span class="section"><a href="misc_crypt.html#misc_crypt_rsa_format">4.2.4. setPrivateKeyFormat(), setPublicKeyFormat(), loadKey() and setPassword()</a></span></dt><dt><span class="section"><a href="misc_crypt.html#misc_crypt_rsa_getpublickey">4.2.5. setPublicKey() and getPublicKey()</a></span></dt><dt><span class="section"><a href="misc_crypt.html#misc_crypt_rsa_encrypt">4.2.6. encrypt(), decrypt() and setEncryptionMode()</a></span></dt><dt><span class="section"><a href="misc_crypt.html#misc_crypt_rsa_sign">4.2.7. sign(), verify(), and setSignatureMode()</a></span></dt><dt><span class="section"><a href="misc_crypt.html#misc_crypt_rsa_params">4.2.8. setHash(), setMGFHash() and setSaltLength()</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="net.html">5. Networking</a></span></dt><dd><dl><dt><span class="section"><a href="net.html#net_ssh">5.1. Net_SSH</a></span></dt><dd><dl><dt><span class="section"><a href="net.html#net_ssh_dependencies">5.1.1. Dependencies</a></span></dt><dt><span class="section"><a href="net.html#net_ssh_ssh1">5.1.2. Net_SSH1 Examples</a></span></dt><dt><span class="section"><a href="net.html#net_ssh_ssh2">5.1.3. Net_SSH2 Examples</a></span></dt><dt><span class="section"><a href="net.html#net_ssh_host_key_verify">5.1.4. Host Key Verification</a></span></dt><dt><span class="section"><a href="net.html#net_ssh_interactive">5.1.5. interactiveRead() / interactiveWrite() vs. exec()</a></span></dt><dt><span class="section"><a href="net.html#net_ssh_exec">5.1.6. SSH-1's exec() vs. SSH-2's exec()</a></span></dt><dt><span class="section"><a href="net.html#net_ssh_successive">5.1.7. Successive calls to SSH-2's exec()</a></span></dt><dt><span class="section"><a href="net.html#net_ssh_debug">5.1.8. Debugging SSH-2</a></span></dt></dl></dd><dt><span class="section"><a href="net.html#net_sftp">5.2. Net_SFTP</a></span></dt><dd><dl><dt><span class="section"><a href="net.html#net_sftp_intro">5.2.1. Introduction</a></span></dt><dt><span class="section"><a href="net.html#net_sftp_dependencies">5.2.2. Dependencies</a></span></dt><dt><span class="section"><a href="net.html#net_sftp_example">5.2.3. Net_SFTP Example</a></span></dt><dt><span class="section"><a href="net.html#net_sftp_put">5.2.4. put($remote_file, $data [, $mode])</a></span></dt><dt><span class="section"><a href="net.html#net_sftp_get">5.2.5. get($remote_file [, $local_file])</a></span></dt><dt><span class="section"><a href="net.html#net_sftp_pwd">5.2.6. pwd(), chdir(), mkdir() and rmdir()</a></span></dt><dt><span class="section"><a href="net.html#net_sftp_chmod">5.2.7. chmod() and size()</a></span></dt><dt><span class="section"><a href="net.html#net_sftp_nlist">5.2.8. nlist() and rawlist()</a></span></dt><dt><span class="section"><a href="net.html#net_sftp_delete">5.2.9. delete() and rename()</a></span></dt><dt><span class="section"><a href="net.html#net_sftp_debug">5.2.10. Debugging SFTP</a></span></dt></dl></dd></dl></dd></dl></div><div class="list-of-tables"><p><b>List of Tables</b></p><dl><dt>3.1. <a href="sym_crypt.html#sym_crypt_aes_benchmarks_table">AES Speed Comparisons</a></dt></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="intro.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"> </td><td width="40%" align="right" valign="top"> Chapter 1. Introduction</td></tr></table></div></body></html>
diff --git a/library/phpsec/intro.html b/library/phpsec/intro.html
deleted file mode 100644 (file)
index 406b22f..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 1. Introduction</title><link rel="stylesheet" href="docbook.css" type="text/css" /><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><link rel="start" href="index.html" title="PHP Secure Communications Library" /><link rel="up" href="index.html" title="PHP Secure Communications Library" /><link rel="prev" href="index.html" title="PHP Secure Communications Library" /><link rel="next" href="math.html" title="Chapter 2. Math" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 1. Introduction</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="index.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="math.html">Next</a></td></tr></table><hr /></div><div class="chapter" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="intro"></a>Chapter 1. Introduction</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="intro.html#intro_intro">1.1. Who should use phpseclib</a></span></dt><dt><span class="section"><a href="intro.html#intro_usage">1.2. Using phpseclib</a></span></dt></dl></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="intro_intro"></a>1.1. Who should use phpseclib</h2></div></div></div><p>
-                Although many of the features this library implements are implemented in PHP via optional extensions, what are 
-                you, as a developer, going to do when a user tries to run your software on a host which, coincidentally, doesn't 
-                happen to have that optional extension installed?  You could, flat-out, tell that user to look for another 
-                software package that does work on their server (or to get another host, or whatever), which is liable to leave 
-                a bad impression on the user, or you could use a library like this - a library that uses those optional 
-                extensions if they're available and falls back on an internal PHP implementation if they're not.
-            </p><p>
-                Another advantage of using this library over optional PHP extensions is that you, as a developer, may find this 
-                libraries API easier to use then extensions API.
-            </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="intro_usage"></a>1.2. Using phpseclib</h2></div></div></div><p>
-                This library is written using the same conventions that libraries in the PHP Extension and Application Repository (PEAR) 
-                have been written in.  In particular, this library expects to be in your <code class="code">include_path</code>:
-            </p><pre class="programlisting">&lt;?php
-set_include_path(get_include_path() . PATH_SEPARATOR . 'phpseclib');
-
-include('Net/SSH2.php');
-?&gt;</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="index.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="math.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">PHP <span class="red">Secure</span> Communications Library </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 2. Math</td></tr></table></div></body></html>
diff --git a/library/phpsec/math.html b/library/phpsec/math.html
deleted file mode 100644 (file)
index 4e5a14a..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 2. Math</title><link rel="stylesheet" href="docbook.css" type="text/css" /><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><link rel="start" href="index.html" title="PHP Secure Communications Library" /><link rel="up" href="index.html" title="PHP Secure Communications Library" /><link rel="prev" href="intro.html" title="Chapter 1. Introduction" /><link rel="next" href="sym_crypt.html" title="Chapter 3. Symmetric-key Cryptography" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 2. Math</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="intro.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="sym_crypt.html">Next</a></td></tr></table><hr /></div><div class="chapter" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="math"></a>Chapter 2. Math</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="math.html#math_biginteger">2.1. Math_BigInteger</a></span></dt><dd><dl><dt><span class="section"><a href="math.html#math_biginteger_dependencies">2.1.1. Dependencies</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_constructor">2.1.2. The constructor</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_output">2.1.3. toString(), toBytes(), toHex() and toBits()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_fourfunctions">2.1.4. add(), subtract(), multiply() and divide()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_modulo">2.1.5. powMod() and modInverse()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_gcd">2.1.6. gcd() and extendedGCD()</a></span></dt><dt><span class="section"><a href="math.html#math_abs">2.1.7. abs()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_compare">2.1.8. equals() and compare()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_precision">2.1.9. setPrecision()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_bitwise">2.1.10. bitwise_and(), bitwise_or(), bitwise_xor() and bitwise_not()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_shifts">2.1.11. bitwise_rightShift() and bitwise_leftShift()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_rotates">2.1.12. bitwise_rightRotate() and bitwise_leftRotate()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_setrandom">2.1.13. setRandomGenerator()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_prime">2.1.14. isPrime()</a></span></dt><dt><span class="section"><a href="math.html#math_biginteger_random">2.1.15. random() and randomPrime()</a></span></dt></dl></dd></dl></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="math_biginteger"></a>2.1. Math_BigInteger</h2></div></div></div><p>
-                Implements an arbitrary precision integer arithmetic library.  Uses gmp or bcmath, if available, and an 
-                internal implementation, otherwise.  Here's an example:
-            </p><pre class="programlisting">&lt;?php
-    include('Math/BigInteger.php');
-
-    $a = new Math_BigInteger(2);
-    $b = new Math_BigInteger(3);
-
-    $c = $a-&gt;add($b);
-
-    echo $c-&gt;toString(); // outputs 5
-?&gt;</pre><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="math_biginteger_dependencies"></a>2.1.1. Dependencies</h3></div></div></div><p>
-                    If you're running PHP 5, Math_BigInteger's only dependancy is the PCRE extension (which is enabled by default).  Math_BigInteger also works on PHP 4 if PHP/Compat/Function/array_fill.php and PHP/Compat/Function/bcpowmod.php are included.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="math_biginteger_constructor"></a>2.1.2. The constructor</h3></div></div></div><p>
-                    The constructor takes two parameters.  The first is the number and the second represents the base.  Both 
-                    are optional (if they're not provided, the Math_BigInteger object will assume a value of 0).
-                </p><p>
-                    The supported bases are base-2, base-10 (default), base-16, and base-256.  To set $a, in the 
-                    above example, to 2, using base-2, we'd do <code class="code">new Math_BigInteger('10', 2)</code>.  To do it using 
-                    base-16, you could do <code class="code">new Math_BigInteger('2', 16)</code> or <code class="code">new Math_BigInteger('0x2', 16)</code>.
-                    To set it to 2 using base-256, you'd do <code class="code">new Math_BigInteger(chr(2), 256)</code>.
-                </p><p>
-                    If the base is negative (eg. -256), two's compliment will be used.  Thus, <code class="code">new Math_BigInteger(chr(0xFF), -256)</code>
-                    is equal to -1, as is <code class="code">new Math_BigInteger('0xFFFFFFFF', -16)</code> and <code class="code">new Math_BigInteger('11', -2)</code>.
-                    Basically, if the leading bit is 1, the number is assumed to be negative.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="math_biginteger_output"></a>2.1.3. toString(), toBytes(), toHex() and toBits()</h3></div></div></div><p>
-                    <code class="code">toString()</code> returns the base-10 form of a number.  <code class="code">toBytes()</code> returns the base-256 
-                    form of a number, <code class="code">toHex()</code> returns the base-16 form, and <code class="code">toBits()</code> the base-2 form.
-                    <code class="code">toBytes()</code>, <code class="code">toHex()</code>, and <code class="code">toBits()</code> also take an optional parameter which,
-                    if set, will return the two's compliment of a number.  So if, for example, $a is equal to -1,
-                    <code class="code">toBytes(true)</code> will return <code class="code">chr(0xFF)</code>.
-                </p><p>
-                    On PHP 5, <code class="code">toString()</code> is called automatically when used in a string context via the
-                    <a class="ulink" href="http://php.net/language.oop5.magic#language.oop5.magic.tostring" target="_top">__toString() magic method</a>.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="math_biginteger_fourfunctions"></a>2.1.4. add(), subtract(), multiply() and divide()</h3></div></div></div><p>
-                    <code class="code">subtract()</code> and <code class="code">multiply()</code> operate similarly to <code class="code">add()</code>.  <code class="code">divide()</code>, 
-                    however, does not.  Namely, it returns an array whose first element contains the quotient and whose 
-                    second element contains the "common residue".  If the remainder would be positive, the "common residue" 
-                    and the remainder are the same.  If the remainder would be negative, the "common residue" is equal to 
-                    the sum of the remainder and the divisor (basically, the "common residue" is the first positive modulo).
-                    Here's an example:
-                </p><pre class="programlisting">&lt;?php
-    include('Math/BigInteger.php');
-
-    $a = new Math_BigInteger('10');
-    $b = new Math_BigInteger('20');
-
-    list($quotient, $remainder) = $a-&gt;divide($b);
-
-    echo $quotient-&gt;toString(); // outputs 0
-    echo "\r\n";
-    echo $remainder-&gt;toString(); // outputs 10
-?&gt;</pre></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="math_biginteger_modulo"></a>2.1.5. powMod() and modInverse()</h3></div></div></div><p>
-                    Examples of each follow:
-                </p><pre class="programlisting">&lt;?php
-    include('Math/BigInteger.php');
-
-    $a = new Math_BigInteger('10');
-    $b = new Math_BigInteger('20');
-    $c = new Math_BigInteger('30');
-
-    $c = $a-&gt;powMod($b, $c);
-
-    echo $c-&gt;toString(); // outputs 10
-?&gt;</pre><pre class="programlisting">&lt;?php
-    include('Math/BigInteger.php');
-
-    $a = new Math_BigInteger(30);
-    $b = new Math_BigInteger(17);
-
-    $c = $a-&gt;modInverse($b);
-
-    echo $c-&gt;toString(); // outputs 4
-?&gt;</pre></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="math_biginteger_gcd"></a>2.1.6. gcd() and extendedGCD()</h3></div></div></div><p>
-                    <code class="code">extendedGCD()</code> returns an array containing three Math_BigInteger values indexed with x, y,
-                    and gcd.  x and y represent Bézout's identity.  <code class="code">gcd()</code> returns a Math_BigInteger value
-                    equal to the gcd.  An example of each follows:
-                </p><pre class="programlisting">&lt;?php
-include('Math/BigInteger.php');
-
-$a = new Math_BigInteger(693);
-$b = new Math_BigInteger(609);
-
-extract($a-&gt;extendedGCD($b));
-$c = $a-&gt;gcd($b);
-
-echo $gcd-&gt;toString() . "\r\n"; // outputs 21
-echo $c-&gt;toString() . "\r\n"; // outputs 21
-echo $a-&gt;toString() * $x-&gt;toString() + $b-&gt;toString() * $y-&gt;toString(); // outputs 21
-?&gt;</pre></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="math_abs"></a>2.1.7. abs()</h3></div></div></div><p>
-                    <code class="code">$x-&gt;abs()</code> returns the absolute value of <code class="code">$x</code>.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="math_biginteger_compare"></a>2.1.8. equals() and compare()</h3></div></div></div><p>
-                    <code class="code">$x-&gt;equals($y)</code> returns true or false depending on whether or not <code class="code">$x</code> and
-                    <code class="code">$y</code> are equal.
-                </p><p>
-                    <code class="code">$x-&gt;compare($y)</code> returns 1 if $x &gt; $y, 0 if $x == $y, and -1 if $x &lt; $y.  The reason for this
-                    is demonstrated thusly:
-                </p><pre class="programlisting">$x  &gt; $y: $x-&gt;compare($y)  &gt; 0
-$x  &lt; $y: $x-&gt;compare($y)  &lt; 0
-$x == $y: $x-&gt;compare($y) == 0
-$x &gt;= $y: $x-&gt;compare($y) &gt;= 0
-$x &lt;= $y: $x-&gt;compare($y) &lt;= 0</pre><p>
-                    As a consequence of this, <code class="code">!$x-&gt;compare($y)</code> does not mean <code class="code">$x != $y</code> but rather
-                    <code class="code">$x == $y</code>.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="math_biginteger_precision"></a>2.1.9. setPrecision()</h3></div></div></div><p>
-                    Some bitwise operations give different results depending on the precision being used.  Examples include
-                    left shift, not, and rotates, as discussed for <a class="link" href="math.html#math_biginteger_bitwise" title="2.1.10. bitwise_and(), bitwise_or(), bitwise_xor() and bitwise_not()">bitwise_not()</a>.
-                    This function lets you control the precision.
-                </p><p>
-                    Whenever a new Math_BigInteger object is created it's precision is set to the same precision as the
-                    calling object.  In other words, if you do <code class="code">$b = $a-&gt;bitwise_not()</code> then <code class="code">$b</code> will
-                    have the same precision as <code class="code">$a</code>.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="math_biginteger_bitwise"></a>2.1.10. bitwise_and(), bitwise_or(), bitwise_xor() and bitwise_not()</h3></div></div></div><p>
-                    <code class="code">bitwise_and()</code>, <code class="code">bitwise_or()</code> and <code class="code">bitwise_xor()</code> operate similar to 
-                    <code class="code">add()</code>.  <code class="code">bitwise_not()</code> is a bit more complicated.  To elaborate, if the
-                    precision (see <a class="link" href="math.html#math_biginteger_precision" title="2.1.9. setPrecision()">setPrecision</a>) is arbitrary,
-                    <code class="code">$x-&gt;bitwise_not()</code> will always yield a smaller value since the most significant bit is
-                    assumed to have a value of one.  With fixed precision, however, the leading bit can be anything.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="math_biginteger_shifts"></a>2.1.11. bitwise_rightShift() and bitwise_leftShift()</h3></div></div></div><p>
-                    <code class="code">$a-&gt;bitwise_rightShift($shift)</code> shifts $a by $shift bits, effectively dividing by 2**$shift. 
-                    <code class="code">$a-&gt;bitwise_leftShift($shift)</code> shifts $a by $shift bits, effectively multiplying by 2**$shift.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="math_biginteger_rotates"></a>2.1.12. bitwise_rightRotate() and bitwise_leftRotate()</h3></div></div></div><p>
-                    <code class="code">$a-&gt;bitwise_rightRotate($shift)</code> and <code class="code">$a-&gt;bitwise_leftRotate($shift)</code> are
-                    demonstrated thusly:
-                </p><pre class="programlisting">&lt;?php
-include('Math/BigInteger.php');
-
-$a = new Math_BigInteger('00111000', 2);
-$a-&gt;setPrecision(8);
-$b = $a-&gt;bitwise_leftRotate(2);
-echo $b-&gt;toBits(); // returns 11100000
-
-echo "\r\n";
-
-$a = new Math_BigInteger('00111000', 2);
-$b = $a-&gt;bitwise_leftRotate(2);
-echo $b-&gt;toBits(); // returns 100011
-?&gt;</pre><p>
-                    Just as with <a class="link" href="math.html#math_biginteger_bitwise" title="2.1.10. bitwise_and(), bitwise_or(), bitwise_xor() and bitwise_not()">bitwise_not()</a>, these operations are
-                    precision dependant.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="math_biginteger_setrandom"></a>2.1.13. setRandomGenerator()</h3></div></div></div><p>
-                    Sets the random generator.  To set it to <code class="code">mt_rand()</code> (which is what it is by default), call
-                    <code class="code">$x-&gt;setRandomGenerator('mt_rand')</code>.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="math_biginteger_prime"></a>2.1.14. isPrime()</h3></div></div></div><p>
-                    Returns true if a number is prime and false if it isn't.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="math_biginteger_random"></a>2.1.15. random() and randomPrime()</h3></div></div></div><p>
-                    <code class="code">random($min, $max)</code> generates a random number between <code class="code">$min</code> and <code class="code">$max</code>.
-                    <code class="code">randomPrime($min, $max)</code> generates a random prime number between <code class="code">$min</code> and <code class="code">$max</code>.
-                    If no prime number exists between <code class="code">$min</code> and <code class="code">$max</code> false is returned.
-                </p><p>
-                    <code class="code">randomPrime()</code> has an optional third parameter, as well - $timeout.  Generating prime numbers
-                    is a particurarly expensive operation and although in certain environments even 512-bit primes can be
-                    generated in a less than a second it can take other environments upwards of around a minute if not more.
-                </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="intro.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="sym_crypt.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 1. Introduction </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 3. Symmetric-key Cryptography</td></tr></table></div></body></html>
diff --git a/library/phpsec/misc_crypt.html b/library/phpsec/misc_crypt.html
deleted file mode 100644 (file)
index 9751dda..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 4. Miscellaneous Cryptography</title><link rel="stylesheet" href="docbook.css" type="text/css" /><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><link rel="start" href="index.html" title="PHP Secure Communications Library" /><link rel="up" href="index.html" title="PHP Secure Communications Library" /><link rel="prev" href="sym_crypt.html" title="Chapter 3. Symmetric-key Cryptography" /><link rel="next" href="net.html" title="Chapter 5. Networking" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 4. Miscellaneous Cryptography</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="sym_crypt.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="net.html">Next</a></td></tr></table><hr /></div><div class="chapter" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="misc_crypt"></a>Chapter 4. Miscellaneous Cryptography</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="misc_crypt.html#misc_crypt_hash">4.1. Crypt_Hash</a></span></dt><dd><dl><dt><span class="section"><a href="misc_crypt.html#misc_crypt_hash_supported">4.1.1. Supported Algorithms and Dependencies</a></span></dt><dt><span class="section"><a href="misc_crypt.html#misc_crypt_hash_example">4.1.2. Example</a></span></dt></dl></dd><dt><span class="section"><a href="misc_crypt.html#misc_crypt_rsa">4.2. Crypt_RSA</a></span></dt><dd><dl><dt><span class="section"><a href="misc_crypt.html#misc_crypt_rsa_dependencies">4.2.1. Dependencies</a></span></dt><dt><span class="section"><a href="misc_crypt.html#misc_crypt_rsa_examples">4.2.2. Examples</a></span></dt><dt><span class="section"><a href="misc_crypt.html#misc_crypt_rsa_createkey">4.2.3. createKey()</a></span></dt><dt><span class="section"><a href="misc_crypt.html#misc_crypt_rsa_format">4.2.4. setPrivateKeyFormat(), setPublicKeyFormat(), loadKey() and setPassword()</a></span></dt><dt><span class="section"><a href="misc_crypt.html#misc_crypt_rsa_getpublickey">4.2.5. setPublicKey() and getPublicKey()</a></span></dt><dt><span class="section"><a href="misc_crypt.html#misc_crypt_rsa_encrypt">4.2.6. encrypt(), decrypt() and setEncryptionMode()</a></span></dt><dt><span class="section"><a href="misc_crypt.html#misc_crypt_rsa_sign">4.2.7. sign(), verify(), and setSignatureMode()</a></span></dt><dt><span class="section"><a href="misc_crypt.html#misc_crypt_rsa_params">4.2.8. setHash(), setMGFHash() and setSaltLength()</a></span></dt></dl></dd></dl></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="misc_crypt_hash"></a>4.1. Crypt_Hash</h2></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="misc_crypt_hash_supported"></a>4.1.1. Supported Algorithms and Dependencies</h3></div></div></div><p>The following algorithms are supported:</p><p>md2, md5, md5-96, sha1, sha1-96, sha256, sha384, and sha512</p><p>
-                    Crypt_Hash requires, minimally, PHP 4.3.0 (due to its use of
-                    <a class="ulink" href="http://php.net/function.sha1" target="_top">sha1()</a>).  If sha384 or sha512 are being used and
-                    you're not running PHP 5.1.2 or greater then Math/BigInteger.php is also required.
-                </p><p>
-                    Crypt_Hash uses the hash extension if it's available (&gt; 5.1.2), mhash if it's not, and it's own
-                    internal implementation if not even mhash is available.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="misc_crypt_hash_example"></a>4.1.2. Example</h3></div></div></div><pre class="programlisting">&lt;?php
-include('Crypt/Hash.php');
-
-$hash = new Crypt_Hash('sha1');
-//$hash-&gt;setKey('abcdefg');
-echo bin2hex($hash-&gt;hash('abcdefg'));
-?&gt;</pre><p>If <code class="code">$hash-&gt;setKey()</code> had been called <code class="code">$hash-&gt;hash()</code> would have returned an HMAC.</p></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="misc_crypt_rsa"></a>4.2. Crypt_RSA</h2></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="misc_crypt_rsa_dependencies"></a>4.2.1. Dependencies</h3></div></div></div>
-                    If you're running PHP 5, Crypt_RSA requires Math/BigInteger.php and Crypt/Hash.php.  If you're running
-                    PHP 4, Crypt_RSA also requires PHP/Compat/Function/array_fill.php, PHP/Compat/Function/bcpowmod.php, and
-                    PHP/Compat/Function/str_split.php
-            </div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="misc_crypt_rsa_examples"></a>4.2.2. Examples</h3></div></div></div><p>Here's an example of how to encrypt / decrypt with Crypt_RSA:</p><pre class="programlisting">&lt;?php
-include('Crypt/RSA.php');
-
-$rsa = new Crypt_RSA();
-extract($rsa-&gt;createKey());
-
-$plaintext = 'terrafrost';
-
-$rsa-&gt;loadKey($privatekey);
-$ciphertext = $rsa-&gt;encrypt($plaintext);
-
-$rsa-&gt;loadKey($publickey);
-echo $rsa-&gt;decrypt($ciphertext);
-?&gt;</pre><p>Here's an example of how to create / verify a signature with Crypt_RSA:</p><pre class="programlisting">&lt;?php
-include('Crypt/RSA.php');
-
-$rsa = new Crypt_RSA();
-extract($rsa-&gt;createKey());
-
-$plaintext = 'terrafrost';
-
-$rsa-&gt;loadKey($privatekey);
-$signature = $rsa-&gt;sign($plaintext);
-
-$rsa-&gt;loadKey($publickey);
-echo $rsa-&gt;verify($plaintext, $signature) ? 'verified' : 'unverified';
-&gt;</pre></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="misc_crypt_rsa_createkey"></a>4.2.3. createKey()</h3></div></div></div><p>
-                    <code class="code">createKey()</code> takes three parameters - <code class="code">$bits</code>, <code class="code">$timeout</code>,
-                    and <code class="code">$primes</code>.  <code class="code">$timeout</code> is present since creating a key has the potential to be
-                    fairly time consuming and will guarantee that <code class="code">createKey()</code> does not run for more than
-                    <code class="code">$timeout</code> seconds.  <code class="code">$primes</code> lets provide pre-computed prime numbers to speed
-                    things up.
-                </p><p>
-                    <code class="code">extract($rsa-&gt;createKey())</code> creates three variables - <code class="code">$publickey</code>,
-                    <code class="code">$privatekey</code>, and <code class="code">$partialkey</code>.  If <code class="code">createKey</code> hit the timeout then
-                    it'll return all the primes that it had managed to compute so that you might pass them back to
-                    <code class="code">createKey()</code> on a subsequent call.
-                </p><p>
-                    The exponent can be set by defining <code class="code">CRYPT_RSA_EXPONENT</code> and multi-prime RSA can be utilized
-                    by adjusting <code class="code">CRYPT_RSA_SMALLEST_PRIME</code>.  Note that these must be done before a Crypt_RSA()
-                    object is initialized.
-                </p><p>
-                    Smaller values for <code class="code">CRYPT_RSA_SMALLEST_PRIME</code> result in increased speed at the cost of security.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="misc_crypt_rsa_format"></a>4.2.4. setPrivateKeyFormat(), setPublicKeyFormat(), loadKey() and setPassword()</h3></div></div></div><p>Crypt_RSA supports the following formats:</p><p>CRYPT_RSA_PRIVATE_FORMAT_PKCS1:</p><pre class="programlisting">-----BEGIN RSA PRIVATE KEY-----
-MIICWgIBAAKBgHx5XHa3LjiugtNq2xkd0oFf2SdsJ04hQYLoeRR3bqAei3Gc+PSy
-AvynCIh/03JCvBsUHaCe8BwjwaTYrpq5QunGo/wvIzvx2d3G9dlrpOIFLiatZYOf
-h07+CkSfaRXhBUKkul/gU87WPhKEcbnPDJS10uD1HqLsHfSKLNitGOf7AgElAoGA
-ENIhQHmedlzFkjEI2eFveURNxw6dhxlANEjtxH7XmRjiaUyQWGsVKQ+nNQpa2Bbb
-JkD9FbSc/OI8wz/gPmwP9eJN29CriebhaV3ebM1L1gbb5r7Vf/D/6rxB0BG/h2lA
-jyZWEZrV/Gi9ZCaw/J+IUu1pAskKid84yHphvszywCUCQQDigrtr+cVkwkUsxOGd
-B378yQCroXmybAD7FQHwVslafuFfTHkaMQSU/ZZLVY1ioMs1VVzzq/vOu0RstZOY
-AfHFAkEAjK3mIWdG4JOM44/SrDkACNatsMtXKOi4K3SlXu9ie6ikXPD+GSZ+bWCX
-GstFaXr9cHRvZPF3qYtK+j2N9UXOvwJBALeoRO/DmSFDkgifoixLRF5CHDgiD6Vs
-U9J/vGIBLaNSHoSe3rtKVr3+CyhTNF3Oe0AABi1bA4UGioGn+yFNr0UCQBbQF3sJ
-1CRq9ECT3PlVWfOYbzFtFQ2NhaYul1uAw9yzkEZsROF73SZ+XbFRZTOzFFds08su
-E2eaDCiUXDWcnhECQQCRUQn2huHlssj8kt35NAVwiHCNfaeSQ5tiDcwfOywA4YXl
-Q+kpuWq5U3V8j/9/n7pE/DL0nXEG/3QpKHJEYV5T
------END RSA PRIVATE KEY-----</pre><p>CRYPT_RSA_PRIVATE_FORMAT_PKCS1 (with password):</p><pre class="programlisting">-----BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-EDE3-CBC,0AE1DB47E71463BE
-
-pI2Kk5ceURbMYNo1xQqqA5rm2/QP4hgj/HuvrACtPSz/aesbG+h4lYXGpQ9os6Ha
-AyFW+iX2UWS6BRwJj1ztO20sKT6ckg7eINSfiSSAeOOiG5aHLxOYayO9aQ5UrrJX
-r0QmwRJRiHTW/82PLBNzfFHYskslNI9EWA5L/Gg4NAXDWwDooGvGkDq3ex7WkWLr
-k7DN2JoZuWsUZxwpgTDouRQMsygrsdSjwRDSgbnTn6luEBrL9fc5/oAWf0xoTk5h
-XMiOOHPBNPiZ1883ayq91HL/6895g8U9oIR1wQmdl0USViYYp5jI19ueowCyblzP
-xD3Bfpb6RPaZ/yqECOysPk6PDz257SGDMNk/QrQJ/eZkeniNXHJ8d+nJGuajZeBu
-6A/bglvKGNNNWe8UJMb5P2OAliD7y7F9wXrkV5FnQ/Q49tGxdBl7WXNuGp4x2d9s
-ZEnv3mOtrr1lM+2QE0Zg8mjqSem5b6Dp0LxOj5j45j5IbBrrd3MKu87jJVzp8yHy
-sBC6NMYYtO03qxV/j1kJR+MmAcCF1+4GGRWdFcoc0sXGVqmEOmK4QfYx3T0Vb6Hk
-oLdlh6ofZogezzJ8A1BvV382sTsJ90eqbgz3E+fDl8iR86+EV9bUujFE4IaBgZJP
-gxikVItdTcq1frNKTCSH/RPeRwk+oKWTpCYGgNA+bl641onW1DCLYcd14N6TDKmY
-77cOTf2ZDGOYNPycAF/FnNJJyLO3IYpU63aKBshB4dYeVrfH0FvG6g5Xt0geIkiD
-5W9El4ks7/3r97x443SagDRt6Mceo5TtzzFfAo7cZeA=
------END RSA PRIVATE KEY-----</pre><p>CRYPT_RSA_PUBLIC_FORMAT_PKCS1:</p><pre class="programlisting">-----BEGIN PUBLIC KEY-----
-MIGGAoGAfHlcdrcuOK6C02rbGR3SgV/ZJ2wnTiFBguh5FHduoB6LcZz49LIC/KcIiH/TckK8GxQd
-oJ7wHCPBpNiumrlC6caj/C8jO/HZ3cb12Wuk4gUuJq1lg5+HTv4KRJ9pFeEFQqS6X+BTztY+EoRx
-uc8MlLXS4PUeouwd9Ios2K0Y5/sCASU=
------END PUBLIC KEY-----</pre><p>CRYPT_RSA_PUBLIC_FORMAT_OPENSSH:</p><pre class="programlisting">ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIB8eVx2ty44roLTatsZHdKBX9knbCdOIUGC6HkUd26gHotx
-nPj0sgL8pwiIf9NyQrwbFB2gnvAcI8Gk2K6auULpxqP8LyM78dndxvXZa6TiBS4mrWWDn4dO/gpEn2kV
-4QVCpLpf4FPO1j4ShHG5zwyUtdLg9R6i7B30iizYrRjn+w== phpseclib-generated-key</pre><p>
-                    Passwords can be set via <code class="code">setPassword()</code> and are only supported on private keys.
-                    CRYPT_RSA_PUBLIC_FORMAT_OPENSSH generates keys that are intended to go in $HOME/.ssh/authorized_keys
-                    for use with OpenSSH.  Another format - CRYPT_RSA_PUBLIC_FORMAT_RAW - is stored as an array with two
-                    indexes - one for the modulus and one for the exponent.  Indexes accepted by <code class="code">loadkey()</code>
-                    are as follows:
-                </p><p>
-                    e, exponent, publicExponent, modulus, modulo, n
-                </p><p>
-                    <code class="code">loadKey()</code> has two parameters - <code class="code">$key</code> and the optional <code class="code">$type</code>.
-                    The default type, if <code class="code">$type</code> is not explicitely set, is CRYPT_RSA_PRIVATE_FORMAT_PKCS1.
-                    It should, at this point, be noted that Crypt_RSA treats public and private keys largelly identically.
-                    A key can be formatted as a CRYPT_RSA_PUBLIC_FORMAT_PKCS1 and still conform to the 
-                    CRYPT_RSA_PRIVATE_FORMAT_PKCS1 format and vice versa.  The only real difference between private keys and
-                    public keys is that private keys *can* contain their public key counterparts whereas public keys cannot.
-                    That said, this distinction is, for the most part, irrelevant and academic.  For a more thorough
-                    discussion of this see <a class="link" href="misc_crypt.html#misc_crypt_rsa_getpublickey" title="4.2.5. setPublicKey() and getPublicKey()">setPublicKey() and getPublicKey()</a>.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="misc_crypt_rsa_getpublickey"></a>4.2.5. setPublicKey() and getPublicKey()</h3></div></div></div><p>
-                    As noted in <a class="link" href="misc_crypt.html#misc_crypt_rsa_format" title="4.2.4. setPrivateKeyFormat(), setPublicKeyFormat(), loadKey() and setPassword()">setPrivateKeyFormat(), setPublicKeyFormat(), loadKey() and setPassword()</a>,
-                    Crypt_RSA treats public and private keys largely identically.  The only real difference is that some
-                    private key formats contain the public key within them whereas no public key format does.  The reason
-                    you'd want to do this is for indexing purposes.  For example, in SSH-2, RSA authentication works by
-                    sending your public key along with a signature created by your private key.  The SSH-2 server then looks
-                    the public key up in an index of public keys to see if it's an allowed key and then verifies the signature.
-                    To that end, <code class="code">setPublicKey()</code> defines the public key if it hasn't already been defined and
-                    <code class="code">getPublicKey()</code> returns it.  <code class="code">getPublicKey()</code> has an optional parameter - $type -
-                    that sets the format.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="misc_crypt_rsa_encrypt"></a>4.2.6. encrypt(), decrypt() and setEncryptionMode()</h3></div></div></div><p>
-                    Crypt_RSA supports two encryption modes - <code class="code">CRYPT_RSA_ENCRYPTION_OAEP</code> and
-                    <code class="code">CRYPT_RSA_ENCRYPTION_PKCS1</code>.  <code class="code">CRYPT_RSA_ENCRYPTION_OAEP</code> uses
-                    <a class="ulink" href="http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding" target="_top">Optimal Asymmetric Encryption Padding</a>
-                    and provides more security than <code class="code">CRYPT_RSA_ENCRYPTION_PKCS1</code>.
-                </p><p>
-                    Both <code class="code">CRYPT_RSA_ENCRYPTION_OAEP</code> and <code class="code">CRYPT_RSA_ENCRYPTION_PKCS1</code> impose limits
-                    on how large the plaintext can be.  If the plaintext exceeds these limits the plaintext will be split
-                    up such that each block falls within those limits.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="misc_crypt_rsa_sign"></a>4.2.7. sign(), verify(), and setSignatureMode()</h3></div></div></div><p>
-                    Crypt_RSA supports two signature modes - <code class="code">CRYPT_RSA_SIGNATURE_PSS</code> and
-                    <code class="code">CRYPT_RSA_SIGNATURE_PKCS1</code>.  The former is assumed to provide more security than the latter.
-                    See <a class="link" href="misc_crypt.html#misc_crypt_rsa_examples" title="4.2.2. Examples">Examples</a> for examples.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="misc_crypt_rsa_params"></a>4.2.8. setHash(), setMGFHash() and setSaltLength()</h3></div></div></div><p>
-                   In all likelihood, calling these functions will be unnecessary as the default values should be sufficient.
-                   None-the-less a discussion of them follows.
-                </p><p>
-                    <code class="code">setHash()</code> is used with signature production / verification and (if the encryption mode is
-                    CRYPT_RSA_ENCRYPTION_OAEP) encryption and decryption.  If the specified hash isn't supported sha1 will
-                    be used.
-                </p><p>
-                    <code class="code">setMGFHash()</code> determines which hashing function should be used for the mask generation
-                    function as utilized in CRYPT_RSA_ENCRYPTION_OAEP and CRYPT_RSA_SIGNATURE_PSS.  PKCS#1 recommends
-                    but does not require that the MGFHash and the Hash be set to the same thing.
-                </p><p>
-                    <code class="code">setSaltLength()</code> is only utilized with CRYPT_RSA_SIGNATURE_PSS.  PKCS#1 recommends this
-                    value either be 0 (which is what it is by default) or the length of the output of the hash function as
-                    set via <code class="code">setHash()</code>
-                </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sym_crypt.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="net.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 3. Symmetric-key Cryptography </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 5. Networking</td></tr></table></div></body></html>
diff --git a/library/phpsec/net.html b/library/phpsec/net.html
deleted file mode 100644 (file)
index 2752b82..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 5. Networking</title><link rel="stylesheet" href="docbook.css" type="text/css" /><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><link rel="start" href="index.html" title="PHP Secure Communications Library" /><link rel="up" href="index.html" title="PHP Secure Communications Library" /><link rel="prev" href="misc_crypt.html" title="Chapter 4. Miscellaneous Cryptography" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 5. Networking</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="misc_crypt.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> </td></tr></table><hr /></div><div class="chapter" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="net"></a>Chapter 5. Networking</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="net.html#net_ssh">5.1. Net_SSH</a></span></dt><dd><dl><dt><span class="section"><a href="net.html#net_ssh_dependencies">5.1.1. Dependencies</a></span></dt><dt><span class="section"><a href="net.html#net_ssh_ssh1">5.1.2. Net_SSH1 Examples</a></span></dt><dt><span class="section"><a href="net.html#net_ssh_ssh2">5.1.3. Net_SSH2 Examples</a></span></dt><dt><span class="section"><a href="net.html#net_ssh_host_key_verify">5.1.4. Host Key Verification</a></span></dt><dt><span class="section"><a href="net.html#net_ssh_interactive">5.1.5. interactiveRead() / interactiveWrite() vs. exec()</a></span></dt><dt><span class="section"><a href="net.html#net_ssh_exec">5.1.6. SSH-1's exec() vs. SSH-2's exec()</a></span></dt><dt><span class="section"><a href="net.html#net_ssh_successive">5.1.7. Successive calls to SSH-2's exec()</a></span></dt><dt><span class="section"><a href="net.html#net_ssh_debug">5.1.8. Debugging SSH-2</a></span></dt></dl></dd><dt><span class="section"><a href="net.html#net_sftp">5.2. Net_SFTP</a></span></dt><dd><dl><dt><span class="section"><a href="net.html#net_sftp_intro">5.2.1. Introduction</a></span></dt><dt><span class="section"><a href="net.html#net_sftp_dependencies">5.2.2. Dependencies</a></span></dt><dt><span class="section"><a href="net.html#net_sftp_example">5.2.3. Net_SFTP Example</a></span></dt><dt><span class="section"><a href="net.html#net_sftp_put">5.2.4. put($remote_file, $data [, $mode])</a></span></dt><dt><span class="section"><a href="net.html#net_sftp_get">5.2.5. get($remote_file [, $local_file])</a></span></dt><dt><span class="section"><a href="net.html#net_sftp_pwd">5.2.6. pwd(), chdir(), mkdir() and rmdir()</a></span></dt><dt><span class="section"><a href="net.html#net_sftp_chmod">5.2.7. chmod() and size()</a></span></dt><dt><span class="section"><a href="net.html#net_sftp_nlist">5.2.8. nlist() and rawlist()</a></span></dt><dt><span class="section"><a href="net.html#net_sftp_delete">5.2.9. delete() and rename()</a></span></dt><dt><span class="section"><a href="net.html#net_sftp_debug">5.2.10. Debugging SFTP</a></span></dt></dl></dd></dl></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="net_ssh"></a>5.1. Net_SSH</h2></div></div></div><p>
-                The Net_SSH1 and Net_SSH2 libraries have, for the most part, an identical API.  Some functions, however, do behave differently.
-            </p><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="net_ssh_dependencies"></a>5.1.1. Dependencies</h3></div></div></div><p>
-                    Net_SSH1/2 require, minimally, Math/BigInteger.php, Crypt/*.php, and PHP/Compat/Function/*.php.  Net_SSH1 requires PHP 4.0.0 unless you're using the interactive functions, which require PHP 4.3.0.  Net_SSH2 requires PHP 4.3.0 due to it's use of <a class="ulink" href="http://php.net/function.sha1" target="_top">sha1()</a>.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="net_ssh_ssh1"></a>5.1.2. Net_SSH1 Examples</h3></div></div></div><pre class="programlisting">&lt;?php
-    include('Net/SSH1.php');
-
-    $ssh = new Net_SSH1('www.domain.tld');
-    if (!$ssh-&gt;login('username', 'password')) {
-        exit('Login Failed');
-    }
-
-    while (true) {
-        echo $ssh-&gt;interactiveRead();
-
-        $read = array(STDIN);
-        $write = $except = NULL;
-        if (stream_select($read, $write, $except, 0)) {
-            $ssh-&gt;interactiveWrite(fread(STDIN, 1));
-        }
-    }
-?&gt;</pre><pre class="programlisting">&lt;?php
-    include('Net/SSH1.php');
-
-    $ssh = new Net_SSH1('www.domain.tld');
-    if (!$ssh-&gt;login('username', 'password')) {
-        exit('Login Failed');
-    }
-
-    echo $ssh-&gt;exec('ls -la');
-?&gt;</pre></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="net_ssh_ssh2"></a>5.1.3. Net_SSH2 Examples</h3></div></div></div><pre class="programlisting">&lt;?php
-    include('Net/SSH2.php');
-
-    $ssh = new Net_SSH2('www.domain.tld');
-    if (!$ssh-&gt;login('username', 'password')) {
-        exit('Login Failed');
-    }
-
-    echo $ssh-&gt;exec('pwd');
-    echo $ssh-&gt;exec('ls -la');
-?&gt;</pre><pre class="programlisting">&lt;?php
-    include('Crypt/RSA.php');
-    include('Net/SSH2.php');
-
-    $key = new Crypt_RSA();
-    //$key-&gt;setPassword('whatever');
-    $key-&gt;loadKey(file_get_contents('privatekey'));
-
-    $ssh = new Net_SSH2('www.domain.tld');
-    if (!$ssh-&gt;login('username', $key)) {
-        exit('Login Failed');
-    }
-
-    echo $ssh-&gt;exec('pwd');
-    echo $ssh-&gt;exec('ls -la');
-?&lt;</pre></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="net_ssh_host_key_verify"></a>5.1.4. Host Key Verification</h3></div></div></div><p>
-                    SSH protects itself against active eavesdroppers by providing a host key.  The first time you connect the host key is supposed to be cached in some manner.  On subsequent connections, the host key being used for this connection should be checked against the cached host key.  If they match, it's the same server.  If not, it's a different one.
-                </p><p>
-                    In SSH-1, <code class="code">getHostKeyPublicModulus()</code> and <code class="code">getHostKeyPublicExponent()</code> will provide you with the host key.  In SSH-2, <code class="code">getServerPublicHostKey()</code> gets you the key.
-                </p><p>
-                    The Net_SSH1 and Net_SSH2 examples omit the key verification stage for brevity.  Also, depending on the context in which this library is used, it may even be unnecessary.  For example, if you're connecting to www.example.com:22 from www.example.com:80, eavesdroppers are not something you need to worry about.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="net_ssh_interactive"></a>5.1.5. interactiveRead() / interactiveWrite() vs. exec()</h3></div></div></div><p>
-                    Say you wanted to use SSH to get the contents of a directory.  If you used <code class="code">interactiveWrite('ls')</code> to do this, and then <code class="code">interactiveRead()</code> to get the output, you, in all likelihood, wouldn't get the whole output.  You'd have to call <code class="code">interactiveRead()</code> multiple times - you'd have to call it as many times as it took for you to get the complete output, which, in turn, begs the question...  how do you know when you have the complete output?
-                    You could assume that whenever the prompt (eg. <code class="code">root@desktop:/root#</code>) showed up, that that'd mean you had the complete output, but that's not fool proof.  And what about messages of the day?  The first <code class="code">interactiveRead()</code> you do is liable to include a part of that rather than the directory listing.  So, not only do you have to make some sort of guestimate as to when the output ends - you often may have to guestimate as to when it begins.
-                </p><p>
-                    To top it all off, you may also get <a class="ulink" href="http://en.wikipedia.org/wiki/ANSI_escape_code" target="_top">ANSI escape codes</a> interspersed amongst the output, which would need to be removed.
-                </p><p>
-                    Using <code class="code">exec('ls')</code> resolves all of these issues.  If you're implementing an interactive client, the interactive functions are the ones you'll want to use.  Otherwise, <code class="code">exec()</code> is likely what you'll want to use.
-                </p><p>
-                    interactiveRead() / interactiveWrite() are not implemented in Net_SSH2.  The SSH-2 protocol supports them, however, phpseclib does not.  The reasons are discussed in the <a class="link" href="net.html#net_ssh_exec" title="5.1.6. SSH-1's exec() vs. SSH-2's exec()">SSH-1's exec() vs. SSH-2's exec()</a> section.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="net_ssh_exec"></a>5.1.6. SSH-1's exec() vs. SSH-2's exec()</h3></div></div></div><p>
-                    <code class="code">exec()</code> works by creating a channel, issuing a command, and then subsequently destroying that channel.  Since SSH-1 <a class="ulink" href="http://www.snailbook.com/faq/ssh-1-vs-2.auto.html" target="_top">only allows one channel</a>, exec() can only be called once.  SSH-2, in contrast, allows an unlimited number of channels, and as such, you can perform as many <code class="code">exec()</code>'s as you see fit.
-                </p><p>
-                    As a consequence of this difference, Net_SSH2 does not implement <a class="link" href="net.html#net_ssh_interactive" title="5.1.5. interactiveRead() / interactiveWrite() vs. exec()">interactiveRead() / interactiveWrite()</a>, even though the SSH-2 specifications provide for those functions.  Simply put, in SSH-1, those functions are necessary to do multiple commands.  In SSH-2, they're not, and so they're not implemented.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="net_ssh_successive"></a>5.1.7. Successive calls to SSH-2's exec()</h3></div></div></div><p>
-                    Successive calls to SSH-2's exec() may not work as expected.  Consider the following:
-                </p><pre class="programlisting">&lt;?php
-    include('Net/SSH2.php');
-
-    $ssh = new Net_SSH2('www.domain.tld');
-    if (!$ssh-&gt;login('username', 'password')) {
-        exit('Login Failed');
-    }
-
-    echo $ssh-&gt;exec('pwd');
-    echo $ssh-&gt;exec('cd /');
-    echo $ssh-&gt;exec('pwd');
-?&gt;</pre><p>
-                    If done on an interactive shell, the output you'd receive for the first <code class="code">pwd</code> would (depending on how your system is setup) be different than the output of the second <code class="code">pwd</code>.  The above code snippet, however, will yield two identical lines.  The reason for this is that any "state changes" you make to the one-time shell are gone once the <code class="code">exec()</code> has been ran and the channel has been deleted.
-                    As such, if you want to support <code class="code">cd</code> in your program, it'd be best to just handle that internally and rewrite all commands, before they're passed to <code class="code">exec()</code> such that the relative paths are expanded to the absolute paths.
-                    Alternatively, one could always run a shell script, however, that may not always be an option.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="net_ssh_debug"></a>5.1.8. Debugging SSH-2</h3></div></div></div><p>
-                    To log output, the NET_SSH2_LOGGING constant will need to be defined.  If you want full logs, you'll need to do <code class="code">define('NET_SSH2_LOGGING', NET_SSH2_LOG_COMPLEX)</code>.  <code class="code">$ssh-&gt;getLog()</code> will then return a string containing the unencrypted packets in hex and ASCII.  If you want to just record the packet types that are being sent to and fro, you'll need to do <code class="code">define('NET_SSH2_LOGGING', NET_SSH2_LOG_SIMPLE)</code>.  <code class="code">$ssh-&gt;getLog()</code> will then return an array.  Both log types include the amount of time it took to send the packet in question.  The former is useful for general diagnostics and the latter is more useful for profiling.  An example follows:
-                </p><pre class="programlisting">&lt;?php
-    include('Net/SSH2.php');
-    define('NET_SSH2_LOGGING', NET_SSH2_LOG_COMPLEX);
-
-    $ssh = new Net_SSH2('www.domain.tld');
-    if (!$ssh-&gt;login('username', 'password')) {
-        exit('Login Failed');
-    }
-
-    echo $ssh-&gt;exec('pwd');
-    echo $ssh-&gt;getLog();
-?&gt;</pre><p>
-                    Depending on the problem, it may be more effective to just look at the output of <code class="code">$ssh-&gt;getLastError()</code> (which returns a string) and <code class="code">$ssh-&gt;getErrors()</code> (which returns an array) than to sift through the logs.
-                </p></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="net_sftp"></a>5.2. Net_SFTP</h2></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="net_sftp_intro"></a>5.2.1. Introduction</h3></div></div></div><p>
-                    Net_SFTP currently only supports SFTPv3, which, according to wikipedia.org, "is the most widely used 
-                    version, implemented by the popular OpenSSH SFTP server".
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="net_sftp_dependencies"></a>5.2.2. Dependencies</h3></div></div></div><p>
-                    Net_SFTP requires, minimally, PHP 4.3.0 and Net/SSH2.php, Math/BigInteger.php, Crypt/*.php, and PHP/Compat/Function/*.php.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="net_sftp_example"></a>5.2.3. Net_SFTP Example</h3></div></div></div><pre class="programlisting">&lt;?php
-include('Net/SFTP.php');
-
-$sftp = new Net_SFTP('www.domain.tld');
-if (!$sftp-&gt;login('username', 'password')) {
-    exit('Login Failed');
-}
-
-echo $sftp-&gt;pwd() . "\r\n";
-$sftp-&gt;put('filename.ext', 'hello, world!');
-print_r($sftp-&gt;nlist());
-?&gt;</pre></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="net_sftp_put"></a>5.2.4. put($remote_file, $data [, $mode])</h3></div></div></div><p>
-                    By default, put() does not read from the local filesystem.  $data is dumped directly into $remote_file.
-                    So, for example, if you set $data to 'filename.ext' and then do get(), you will get a file, twelve bytes
-                    long, containing 'filename.ext' as its contents.
-                </p><p>
-                    Setting $mode to NET_SFTP_LOCAL_FILE will change the above behavior.  With NET_SFTP_LOCAL_FILE, $remote_file will 
-                    contain as many bytes as filename.ext does on your local filesystem.  If your filename.ext is 1MB then that is how
-                    large $remote_file will be, as well.
-                </p><p>
-                    Currently, only binary mode is supported.  As such, if the line endings need to be adjusted, you will need to take
-                    care of that, yourself.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="net_sftp_get"></a>5.2.5. get($remote_file [, $local_file])</h3></div></div></div><p>
-                    Returns a string containing the contents of $remote_file if $local_file is left undefined or a boolean false if
-                    the operation was unsuccessful.  If $local_file is defined, returns true or false depending on the success of the
-                    operation
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="net_sftp_pwd"></a>5.2.6. pwd(), chdir(), mkdir() and rmdir()</h3></div></div></div><p>
-                    pwd() returns the current directory, chdir() changes directories, mkdir() creates direcotires, and rmdir() removes directories.
-                    In the event of failure, they all return false.  chdir(), mkdir(), and rmdir() return true on successful completion of the operation.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="net_sftp_chmod"></a>5.2.7. chmod() and size()</h3></div></div></div><p>
-                    chmod() sets the permissions on a file and returns the new file permissions on success or false on error.  Permissions are expected to be in octal so to set a file to 777 do <code class="code">$sftp-&gt;chmod(0777, $filename)</code>
-                </p><p>
-                    size() returns the size, in bytes, of an arbitrary file.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="net_sftp_nlist"></a>5.2.8. nlist() and rawlist()</h3></div></div></div><p>
-                    nlist($dir = '.') returns the contents of the current directory as a numerically indexed array and rawlist() returns an associate array where the filenames are the array keys and the array values are, themselves, arrays containing the file attributes.  The directory can be changed with the first parameter.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="net_sftp_delete"></a>5.2.9. delete() and rename()</h3></div></div></div><p>
-                    The purpose of both functions should be easy enough to glean - delete() deletes files or directories and rename() renames them.  Both return true on success and false on failure.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="net_sftp_debug"></a>5.2.10. Debugging SFTP</h3></div></div></div><p>
-                    Debbuging SFTP connections in phpseclib works in a manner similar to <a class="link" href="net.html#net_ssh_debug" title="5.1.8. Debugging SSH-2">debugging SSH-2</a>  Instead of the constant being NET_SSH2_LOGGING, however, it's <code class="code">NET_SFTP_LOGGING</code>.  And instead of NET_SSH2_LOG_COMPLEX or NET_SSH2_LOG_SIMPLE it's NET_SFTP_LOG_COMPLEX or NET_SFTP_LOG_SIMPLE respectively.  And instead of calling $sftp-&gt;getLog() you call <code class="code">$sftp-&gt;getSFTPLog()</code> or <code class="code">$sftp-&gt;getLastSFTPError()</code> or whatever.
-                </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="misc_crypt.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> </td></tr><tr><td width="40%" align="left" valign="top">Chapter 4. Miscellaneous Cryptography </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div></body></html>
diff --git a/library/phpsec/sym_crypt.html b/library/phpsec/sym_crypt.html
deleted file mode 100644 (file)
index 9565062..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 3. Symmetric-key Cryptography</title><link rel="stylesheet" href="docbook.css" type="text/css" /><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><link rel="start" href="index.html" title="PHP Secure Communications Library" /><link rel="up" href="index.html" title="PHP Secure Communications Library" /><link rel="prev" href="math.html" title="Chapter 2. Math" /><link rel="next" href="misc_crypt.html" title="Chapter 4. Miscellaneous Cryptography" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 3. Symmetric-key Cryptography</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="math.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="misc_crypt.html">Next</a></td></tr></table><hr /></div><div class="chapter" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="sym_crypt"></a>Chapter 3. Symmetric-key Cryptography</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="sym_crypt.html#sym_crypt_intro">3.1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="sym_crypt.html#sym_crypt_dependencies">3.1.1. Dependencies</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_set">3.1.2. setKey() and setIV()</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_encrypt">3.1.3. encrypt() and decrypt()</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_continuousbuffer">3.1.4. enableContinuousBuffer() and disableContinuousBuffer()</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_padding">3.1.5. enablePadding() and disablePadding()</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_caution">3.1.6. A word of caution about stream ciphers and CTR mode</a></span></dt></dl></dd><dt><span class="section"><a href="sym_crypt.html#sym_crypt_des">3.2. Crypt_DES</a></span></dt><dd><dl><dt><span class="section"><a href="sym_crypt.html#sym_crypt_des_constructor">3.2.1. The constructor</a></span></dt></dl></dd><dt><span class="section"><a href="sym_crypt.html#sym_crypt_tripledes">3.3. Crypt_TripleDES</a></span></dt><dd><dl><dt><span class="section"><a href="sym_crypt.html#sym_crypt_tripledes_constructor">3.3.1. The constructor</a></span></dt></dl></dd><dt><span class="section"><a href="sym_crypt.html#sym_crypt_rc4">3.4. Crypt_RC4</a></span></dt><dd><dl><dt><span class="section"><a href="sym_crypt.html#sym_crypt_rc4_constructor">3.4.1. The constructor</a></span></dt></dl></dd><dt><span class="section"><a href="sym_crypt.html#sym_crypt_aes">3.5. Crypt_Rijndael &amp; Crypt_AES</a></span></dt><dd><dl><dt><span class="section"><a href="sym_crypt.html#sym_crypt_aes_constructor">3.5.1. The constructor</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_aes_vs_rijndael">3.5.2. AES vs. Rijndael</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_aes_setkeylength">3.5.3. setKeyLength()</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_aes_setblocklength">3.5.4. setBlockLength()</a></span></dt><dt><span class="section"><a href="sym_crypt.html#sym_crypt_aes_benchmarks">3.5.5. Speed Comparisons</a></span></dt></dl></dd></dl></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sym_crypt_intro"></a>3.1. Introduction</h2></div></div></div><p>
-                All of the cryptographic libraries included in phpseclib use mcrypt, if available, and an internal implementation 
-                if it's not.  The libraries all use a common interface although some functions, for some algorithms, carry with 
-                with them certain caveats.  Those that do not have caveats attached (or have relatively few attached) are 
-                described below.  If you don't know which one to use, try <code class="code">Crypt_TripleDES</code>.
-            </p><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_dependencies"></a>3.1.1. Dependencies</h3></div></div></div><p>
-                    The Crypt_* functions require, minimally, PHP 4.0.0.  Crypt_TripleDES additionally requires Crypt/DES.php.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_set"></a>3.1.2. setKey() and setIV()</h3></div></div></div><p>
-                    Sets the key and the initialization vector, respectively.  If neither are set, each assumed to be equal to 
-                    some amount of null bytes.  The initialization vector is only used in block ciphers and even then only 
-                    in CBC mode.  If the key or the initialization vector are larger then the block size, they're truncated.
-                    If they're smaller, they're padded with null bytes.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_encrypt"></a>3.1.3. encrypt() and decrypt()</h3></div></div></div><p>
-                    Self-explanatory.  Encrypts or decrypts messages.  See the examples in the subsequent sections.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_continuousbuffer"></a>3.1.4. enableContinuousBuffer() and disableContinuousBuffer()</h3></div></div></div><p>
-                    If the continuous buffer is enabled and you're using a stream cipher or a block cipher mode other than ECB then encrypting the same string twice will yield different ciphertexts.
-                    The reason being that the IV doesn't reset after each encryption / decryption round when the continuous buffer is used.
-                    This provides better security but it may also make for less intuitive behavior.
-                    For this reason, the continuous buffer is disabled by default.
-                 </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_padding"></a>3.1.5. enablePadding() and disablePadding()</h3></div></div></div><p>
-                    Enables / disables PKCS padding on block ciphers.  Stream ciphers (<code class="code">Crypt_RC4</code> is the only stream
-                    cipher currently included) ignore this.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_caution"></a>3.1.6. A word of caution about stream ciphers and CTR mode</h3></div></div></div><p>
-                    Most stream ciphers (and block ciphers operating in a mode - like CTR - that turns them into stream ciphers) work by generating a stream of pseudorandom characters called a <a class="ulink" href="http://en.wikipedia.org/wiki/Keystream" target="_top">keystream</a> and then XOR'ing that with the plaintext.
-                    This *effectively* makes them <a class="ulink" href="http://en.wikipedia.org/wiki/One-time_pad" target="_top">one-time pads</a> which, in theory, can provide perfect secrecy.  The problem with one-time pads is that they're not as versatile as one might desire.
-                    Among other things, a keystream must never be reset, lest it be possible for an attacker to recover the keystream via a <a class="ulink" href="http://en.wikipedia.org/wiki/Known-plaintext_attack" target="_top">known-plaintext attack</a>.  ie. <code class="code">$ciphertext ^ $plaintext = $key</code>.  If <code class="code">$key</code> is constant (because the keystream's being reset or something) than an attacker can recover any <code class="code">$plaintext</code>, but if not - if it's dynamic - then the only key that an attacker could recover is their own.
-                </p></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sym_crypt_des"></a>3.2. Crypt_DES</h2></div></div></div><p>
-                Implements DES (a block cipher).  Here's an example of how to use it:
-            </p><pre class="programlisting">&lt;?php
-    include('Crypt/DES.php');
-
-    $des = new Crypt_DES();
-
-    $des-&gt;setKey('abcdefgh');
-
-    $size = 10 * 1024;
-    $plaintext = '';
-    for ($i = 0; $i &lt; $size; $i++) {
-        $plaintext.= 'a';
-    }
-
-    echo $des-&gt;decrypt($des-&gt;encrypt($plaintext));
-?&gt;</pre><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_des_constructor"></a>3.2.1. The constructor</h3></div></div></div><p>
-                    The constructor takes one optional parameter - $mode.  Valid values for $mode are as follows:
-                </p><div class="itemizedlist"><ul type="disc"><li><code class="code">CRYPT_DES_MODE_ECB</code></li><li><code class="code">CRYPT_DES_MODE_CBC</code>: The default value.</li><li><code class="code">CRYPT_DES_MODE_CTR</code></li></ul></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sym_crypt_tripledes"></a>3.3. Crypt_TripleDES</h2></div></div></div><p>
-                Implements TripleDES (a block cipher).  Here's an example of how to use it:
-            </p><pre class="programlisting">&lt;?php
-    include('Crypt/TripleDES.php');
-
-    $des = new Crypt_TripleDES();
-
-    $des-&gt;setKey('abcdefghijklmnopqrstuvwx');
-
-    $size = 10 * 1024;
-    $plaintext = '';
-    for ($i = 0; $i &lt; $size; $i++) {
-        $plaintext.= 'a';
-    }
-
-    echo $des-&gt;decrypt($des-&gt;encrypt($plaintext));
-?&gt;</pre><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_tripledes_constructor"></a>3.3.1. The constructor</h3></div></div></div><p>
-                    The constructor takes one optional parameter - $mode.  Valid values for $mode are as follows:
-                </p><div class="itemizedlist"><ul type="disc"><li><code class="code">CRYPT_DES_MODE_ECB</code></li><li><code class="code">CRYPT_DES_MODE_CBC3</code>: Employs outer chaining to propogate the initialization vector.  Used by SSH-2 and generally considered more secure than inner chaining.</li><li><code class="code">CRYPT_DES_MODE_3CBC</code>: Employs inner chaining to propogate the initialization vector.  Used by SSH-1.</li><li><code class="code">CRYPT_DES_MODE_CBC</code>: The default value.  An alias for <code class="code">CRYPT_DES_MODE_CBC3</code>.</li><li><code class="code">CRYPT_DES_MODE_CTR</code></li></ul></div></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sym_crypt_rc4"></a>3.4. Crypt_RC4</h2></div></div></div><p>
-                Implements RC4 (a stream cipher).  Here's an example of how to use it:
-            </p><pre class="programlisting">&lt;?php
-    include('Crypt/RC4.php');
-
-    $rc4 = new Crypt_RC4();
-
-    $rc4-&gt;setKey('abcdefghijklmnopqrstuvwx');
-
-    $size = 10 * 1024;
-    $plaintext = '';
-    for ($i = 0; $i &lt; $size; $i++) {
-        $plaintext.= 'a';
-    }
-
-    echo $rc4-&gt;decrypt($rc4-&gt;encrypt($plaintext));
-?&gt;</pre><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_rc4_constructor"></a>3.4.1. The constructor</h3></div></div></div><p>
-                    Not much to say about this constructor.  Since it's a stream cipher, you don't need to worry about which
-                    mode of operation to use.
-                </p></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="sym_crypt_aes"></a>3.5. Crypt_Rijndael &amp; Crypt_AES</h2></div></div></div><p>
-                Implements Rijndael / AES.  Here's an example of how to use Crypt_AES:
-            </p><pre class="programlisting">&lt;?php
-    include('Crypt/AES.php');
-
-    $aes = new Crypt_AES();
-
-    $aes-&gt;setKey('abcdefghijklmnop');
-
-    $size = 10 * 1024;
-    $plaintext = '';
-    for ($i = 0; $i &lt; $size; $i++) {
-        $plaintext.= 'a';
-    }
-
-    echo $aes-&gt;decrypt($aes-&gt;encrypt($plaintext));
-?&gt;</pre><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_aes_constructor"></a>3.5.1. The constructor</h3></div></div></div><p>
-                    <code class="code">Crypt_AES</code>'s constructor's optional parameter can take the following values:
-                </p><div class="itemizedlist"><ul type="disc"><li><code class="code">CRYPT_AES_MODE_ECB</code></li><li><code class="code">CRYPT_AES_MODE_CBC</code>: The default value.</li><li><code class="code">CRYPT_AES_MODE_CTR</code></li></ul></div><p>
-                    <code class="code">Crypt_Rijndael</code> takes the following:
-                </p><div class="itemizedlist"><ul type="disc"><li><code class="code">CRYPT_RIJNDAEL_MODE_ECB</code></li><li><code class="code">CRYPT_RIJNDAEL_MODE_CBC</code>: The default value.</li><li><code class="code">CRYPT_RIJNDAEL_MODE_CTR</code></li></ul></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_aes_vs_rijndael"></a>3.5.2. AES vs. Rijndael</h3></div></div></div><p>
-                    AES is a subset of Rijndael.  Both have variable key sizes, however, AES's block size is fixed at 128 bits, whereas Rijndael's is variable.  Also, Rijndael supports, by means of an extension to the specification, two key sizes that AES does not - 160 bits and 224 bits.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_aes_setkeylength"></a>3.5.3. setKeyLength()</h3></div></div></div><p>
-                    Valid key lengths for AES are 128 bits, 192 bits, and 256 bits.  If the key that is assigned is invalid and less than 256 bits, they key length is rounded up to the next closest valid size and the key will be null padded to that amount.  If the key length is greater than 256 bits, it will be truncated to 256 bits.
-                </p><p>
-                    As an example, if the key is 136 bits, it will be null padded to 192 bits (or 160 bits if Rijndael is being used).
-                </p><p>
-                    If <code class="code">setKeyLength()</code> has been called, this behavior changes somewhat.  Say you've set the key length, via this function, to 256 bits.  Then, instead of an invalid key being null padded to 192 or 160 bits, it will be null padded to 256 bits.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_aes_setblocklength"></a>3.5.4. setBlockLength()</h3></div></div></div><p>
-                    <code class="code">setBlockLength()</code> operates in a manner similar to <code class="code">setKeyLength()</code>, with one exception.  <code class="code">setBlockLength()</code> only works on Rijndael.  Although <code class="code">Crypt_AES</code> inherits <code class="code">setBlockLength()</code> as a function, the function doesn't do anything in AES.
-                </p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="sym_crypt_aes_benchmarks"></a>3.5.5. Speed Comparisons</h3></div></div></div><p>
-                    The following table compares the speed of five different pure-PHP implementations of AES (one of which is Crypt_Rijndael and one of which is Crypt_AES) when ran on 150KB of text on a 1.8GHz Pentium 4-M.  The numbers listed are averaged from five different trials and are measured in seconds.  phpseclib's two implementations are highlighted.  All implementations can be viewed by clicking on their names.
-                </p><div class="table"><a id="sym_crypt_aes_benchmarks_table"></a><p class="title"><b>Table 3.1. AES Speed Comparisons</b></p><div class="table-contents"><table summary="AES Speed Comparisons" border="1"><colgroup><col /><col /><col /><col /><col /></colgroup><thead><tr><th align="right"><a class="ulink" href="http://phpseclib.sourceforge.net/movable-type.phps" target="_top">movable-type.phps</a></th><th align="right"><a class="ulink" href="http://phpseclib.sourceforge.net/phpaes.phps" target="_top">phpaes.phps</a></th><th align="right"><a class="ulink" href="http://phpseclib.sourceforge.net/phpclasses1.phps" target="_top">phpclasses1.phps</a></th><th align="right"><a class="ulink" href="http://phpseclib.sourceforge.net/phpclasses2.phps" target="_top">phpclasses2.phps</a></th><th align="right"><a class="ulink" href="http://phpseclib.sourceforge.net/phpseclib-aes.phps" target="_top">phpseclib-aes.phps</a></th><th align="right"><a class="ulink" href="http://phpseclib.sourceforge.net/phpseclib-rijndael.phps" target="_top">phpseclib-rijndael.phps</a></th></tr></thead><tbody><tr><td align="right">15.6844158172</td><td align="right">39.9537248135</td><td align="right">15.0100150108</td><td align="right">62.591713190079</td><td class="highlight" align="right">2.03581542968752</td><td class="highlight" align="right">2.62501101493836</td></tr></tbody></table></div></div><br class="table-break" /><p>
-                    As can be seen, phpseclib's implementations are the fastest.  phpseclib-aes.phps is faster than phpseclib-rijndael.phps because phpseclib-rijndael.phps has to contend with multiple block sizes whereas phpseclib-aes.phps does not.  Note that if mcrypt weren't explicitily disabled phpseclib would have been even faster.
-                </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="math.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="misc_crypt.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 2. Math </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 4. Miscellaneous Cryptography</td></tr></table></div></body></html>
diff --git a/library/spam/README b/library/spam/README
deleted file mode 100644 (file)
index a0d67fc..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-B8 for Friendica
-
-B8 is an excellent bayesian spam implementation for PHP. However when evaluating it for use in Friendica there were a few shortcomings. B8's primary audience is guestbooks and blogs - single user situations. 
-
-Friendica is a multi-user distributed social environment. So the first thing we need to add to b8 is a concept of user ID. 
-
-Second we don't want to use a second stored set of DB login credentials so we're going to implemetn Friendica's MySQL driver and use our existing connection and credentials.
-
-The third requirement is that the B8 processing model is to load a set of word/data sets from the DB, perform processing (which may change the value of the data) and then store the results back to the DB. We're in a highly dynamic environment with lots of sometimes concurrent message processing. So the plan is to alter the storage architecture to read data in, do processing, and then apply a somewhat atomic change operation where the changes are performed in a single query using the current data in storage rather than something passed through outside processing and where the data may be outdated come time to store it.
-
-In accordance with the LGPL of the B8 package these changes are available in source form at http://github.com/friendica/friendica in the directory library/spam
-  
\ No newline at end of file
diff --git a/library/spam/b8/b8.php b/library/spam/b8/b8.php
deleted file mode 100644 (file)
index 28a3dd2..0000000
+++ /dev/null
@@ -1,503 +0,0 @@
-<?php
-
-#   Copyright (C) 2006-2010 Tobias Leupold <tobias.leupold@web.de>
-#
-#   b8 - A Bayesian spam filter written in PHP 5
-#
-#   This program is free software; you can redistribute it and/or modify it
-#   under the terms of the GNU Lesser General Public License as published by
-#   the Free Software Foundation in version 2.1 of the License.
-#
-#   This program is distributed in the hope that it will be useful, but
-#   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-#   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-#   License for more details.
-#
-#   You should have received a copy of the GNU Lesser General Public License
-#   along with this program; if not, write to the Free Software Foundation,
-#   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-
-/**
- * Copyright (C) 2006-2010 Tobias Leupold <tobias.leupold@web.de>
- *
- * @license LGPL
- * @access public
- * @package b8
- * @author Tobias Leupold
- * @author Oliver Lillie (aka buggedcom) (original PHP 5 port)
- */
-
-class b8
-{
-
-       public $config = array(
-               'min_size'      => 3,
-               'max_size'      => 30,
-               'allow_numbers' => FALSE,
-               'lexer'         => 'default',
-               'degenerator'   => 'default',
-               'storage'       => 'dba',
-               'use_relevant'  => 15,
-               'min_dev'       => 0.2,
-               'rob_s'         => 0.3,
-               'rob_x'         => 0.5
-       );
-
-       private $_lexer      = NULL;
-       private $_database   = NULL;
-       private $_token_data = NULL;
-
-       const SPAM    = 'spam';
-       const HAM     = 'ham';
-       const LEARN   = 'learn';
-       const UNLEARN = 'unlearn';
-
-       const STARTUP_FAIL_DATABASE = 'STARTUP_FAIL_DATABASE';
-       const STARTUP_FAIL_LEXER    = 'STARTUP_FAIL_LEXER';
-       const TRAINER_CATEGORY_FAIL = 'TRAINER_CATEGORY_FAIL';
-
-       /**
-        * Constructs b8
-        *
-        * @access public
-        * @return void
-        */
-
-       function __construct($config = array(), $database_config)
-       {
-
-               # Validate config data
-
-               if(count($config) > 0) {
-
-                       foreach ($config as $name=>$value) {
-
-                               switch($name) {
-
-                                       case 'min_dev':
-                                       case 'rob_s':
-                                       case 'rob_x':
-                                               $this->config[$name] = (float) $value;
-                                               break;
-
-                                       case 'min_size':
-                                       case 'max_size':
-                                       case 'use_relevant':
-                                               $this->config[$name] = (int) $value;
-                                               break;
-
-                                       case 'allow_numbers':
-                                               $this->config[$name] = (bool) $value;
-                                               break;
-
-                                       case 'lexer':
-                                               $value = (string) strtolower($value);
-                                               $this->config[$name] = is_file(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'lexer' . DIRECTORY_SEPARATOR . "lexer_" . $value . '.php') === TRUE ? $value : 'default';
-                                               break;
-
-                                       case 'storage':
-                                               $this->config[$name] = (string) $value;
-                                               break;
-
-                               }
-
-                       }
-
-               }
-
-               # Setup the database backend
-
-               # Get the basic storage class used by all backends
-               if($this->load_class('b8_storage_base', dirname(__FILE__) . DIRECTORY_SEPARATOR . 'storage' . DIRECTORY_SEPARATOR . 'storage_base.php') === FALSE)
-                       return;
-
-               # Get the degenerator we need
-               if($this->load_class('b8_degenerator_' . $this->config['degenerator'], dirname(__FILE__) . DIRECTORY_SEPARATOR . 'degenerator' . DIRECTORY_SEPARATOR . 'degenerator_' . $this->config['degenerator'] . '.php') === FALSE)
-                       return;
-
-               # Get the actual storage backend we need
-               if($this->load_class('b8_storage_' . $this->config['storage'], dirname(__FILE__) . DIRECTORY_SEPARATOR . 'storage' . DIRECTORY_SEPARATOR . 'storage_' . $this->config['storage'] . '.php') === FALSE)
-                       return;
-
-               # Setup the backend
-               $class = 'b8_storage_' . $this->config['storage'];
-               $this->_database = new $class(
-                       $database_config,
-                       $this->config['degenerator'], date('ymd')
-               );
-
-               # Setup the lexer class
-
-               if($this->load_class('b8_lexer_' . $this->config['lexer'], dirname(__FILE__) . DIRECTORY_SEPARATOR . 'lexer' . DIRECTORY_SEPARATOR . 'lexer_' . $this->config['lexer'] . '.php') === FALSE)
-                       return;
-
-               $class = 'b8_lexer_' . $this->config['lexer'];
-               $this->_lexer = new $class(
-                       array(
-                               'min_size' => $this->config['min_size'],
-                               'max_size' => $this->config['max_size'],
-                               'allow_numbers' => $this->config['allow_numbers']
-                       )
-               );
-
-       }
-
-       /**
-        * Load a class file if a class has not been defined yet.
-        *
-        * @access public
-        * @return boolean Returns TRUE if everything is okay, otherwise FALSE.
-        */
-
-       public function load_class($class_name, $class_file)
-       {
-
-               if(class_exists($class_name, FALSE) === FALSE) {
-
-                       $included = require_once $class_file;
-
-                       if($included === FALSE or class_exists($class_name, FALSE) === FALSE)
-                               return FALSE;
-
-               }
-
-               return TRUE;
-
-       }
-
-       /**
-        * Validates the class has all it needs to work.
-        *
-        * @access public
-        * @return mixed Returns TRUE if everything is okay, otherwise an error code.
-        */
-
-       public function validate()
-       {
-
-               if($this->_database === NULL)
-                       return self::STARTUP_FAIL_DATABASE;
-
-               # Connect the database backend if we aren't connected yet
-
-               elseif($this->_database->connected === FALSE) {
-
-                       $connection = $this->_database->connect();
-
-                       if($connection !== TRUE)
-                               return $connection;
-
-               }
-
-               if($this->_lexer === NULL)
-                       return self::STARTUP_FAIL_LEXER;
-
-               return TRUE;
-
-       }
-
-       /**
-        * Classifies a text
-        *
-        * @access public
-        * @package default
-        * @param string $text
-        * @return float The rating between 0 (ham) and 1 (spam)
-        */
-
-       public function classify($uid,$text)
-       {
-
-               # Validate the startup
-
-               $started_up = $this->validate();
-
-               if($started_up !== TRUE)
-                       return $started_up;
-
-               # Get the internal database variables, containing the number of ham and
-               # spam texts so the spam probability can be calculated in relation to them
-               $internals = $this->_database->get_internals($uid);
-
-               # Calculate the spamminess of all tokens
-
-               # Get all tokens we want to rate
-
-               $tokens = $this->_lexer->get_tokens($text);
-
-               # Check if the lexer failed
-               # (if so, $tokens will be a lexer error code, if not, $tokens will be an array)
-               if(!is_array($tokens))
-                       return $tokens;
-
-               # Fetch all availible data for the token set from the database
-               $this->_token_data = $this->_database->get(array_keys($tokens),$uid);
-
-               # Calculate the spamminess and importance for each token (or a degenerated form of it)
-
-               $word_count = array();
-               $rating     = array();
-               $importance = array();
-
-               foreach($tokens as $word => $count) {
-
-                       $word_count[$word] = $count;
-
-                       # Although we only call this function only here ... let's do the
-                       # calculation stuff in a function to make this a bit less confusing ;-)
-                       $rating[$word] = $this->_get_probability($word, $internals['texts_ham'], $internals['texts_spam']);
-
-                       $importance[$word] = abs(0.5 - $rating[$word]);
-
-               }
-
-               # Order by importance
-               arsort($importance);
-               reset($importance);
-
-               # Get the most interesting tokens (use all if we have less than the given number)
-
-               $relevant = array();
-
-               for($i = 0; $i < $this->config['use_relevant']; $i++) {
-
-                       if($tmp = each($importance)) {
-
-                               # Important tokens remain
-
-                               # If the token's rating is relevant enough, use it
-
-                               if(abs(0.5 - $rating[$tmp['key']]) > $this->config['min_dev']) {
-
-                                       # Tokens that appear more than once also count more than once
-
-                                       for($x = 0, $l = $word_count[$tmp['key']]; $x < $l; $x++)
-                                               array_push($relevant, $rating[$tmp['key']]);
-
-                               }
-
-                       }
-
-                       else {
-                               # We have less than words to use, so we already
-                               # use what we have and can break here
-                               break;
-                       }
-
-               }
-
-               # Calculate the spamminess of the text (thanks to Mr. Robinson ;-)
-               # We set both hamminess and Spamminess to 1 for the first multiplying
-               $hamminess  = 1;
-               $spamminess = 1;
-
-               # Consider all relevant ratings
-               foreach($relevant as $value) {
-                       $hamminess  *= (1.0 - $value);
-                       $spamminess *= $value;
-               }
-
-               # If no token was good for calculation, we really don't know how
-               # to rate this text; so we assume a spam and ham probability of 0.5
-
-               if($hamminess === 1 and $spamminess === 1) {
-                       $hamminess = 0.5;
-                       $spamminess = 0.5;
-                       $n = 1;
-               }
-               else {
-                       # Get the number of relevant ratings
-                       $n = count($relevant);
-               }
-
-               # Calculate the combined rating
-
-               # The actual hamminess and spamminess
-               $hamminess  = 1 - pow($hamminess,  (1 / $n));
-               $spamminess = 1 - pow($spamminess, (1 / $n));
-
-               # Calculate the combined indicator
-               $probability = ($hamminess - $spamminess) / ($hamminess + $spamminess);
-
-               # We want a value between 0 and 1, not between -1 and +1, so ...
-               $probability = (1 + $probability) / 2;
-
-               # Alea iacta est
-               return $probability;
-
-       }
-
-       /**
-        * Calculate the spamminess of a single token also considering "degenerated" versions
-        *
-        * @access private
-        * @param string $word
-        * @param string $texts_ham
-        * @param string $texts_spam
-        * @return void
-        */
-
-       private function _get_probability($word, $texts_ham, $texts_spam)
-       {
-
-               # Let's see what we have!
-
-               if(isset($this->_token_data['tokens'][$word]) === TRUE) {
-                       # The token was in the database, so we can use it's data as-is
-                       # and calculate the spamminess of this token directly
-                       return $this->_calc_probability($this->_token_data['tokens'][$word], $texts_ham, $texts_spam);
-               }
-
-               # Damn. The token was not found, so do we have at least similar words?
-
-               if(isset($this->_token_data['degenerates'][$word]) === TRUE) {
-
-                       # We found similar words, so calculate the spamminess for each one
-                       # and choose the most important one for the further calculation
-
-                       # The default rating is 0.5 simply saying nothing
-                       $rating = 0.5;
-
-                       foreach($this->_token_data['degenerates'][$word] as $degenerate => $count) {
-
-                               # Calculate the rating of the current degenerated token
-                               $rating_tmp = $this->_calc_probability($count, $texts_ham, $texts_spam);
-
-                               # Is it more important than the rating of another degenerated version?
-                               if(abs(0.5 - $rating_tmp) > abs(0.5 - $rating))
-                                       $rating = $rating_tmp;
-
-                       }
-
-                       return $rating;
-
-               }
-
-               else {
-                       # The token is really unknown, so choose the default rating
-                       # for completely unknown tokens. This strips down to the
-                       # robX parameter so we can cheap out the freaky math ;-)
-                       return $this->config['rob_x'];
-               }
-
-       }
-
-       /**
-        * Do the actual spamminess calculation of a single token
-        *
-        * @access private
-        * @param array $data
-        * @param string $texts_ham
-        * @param string $texts_spam
-        * @return void
-        */
-
-       private function _calc_probability($data, $texts_ham, $texts_spam)
-       {
-
-               # Calculate the basic probability by Mr. Graham
-
-               # But: consider the number of ham and spam texts saved instead of the
-               # number of entries where the token appeared to calculate a relative
-               # spamminess because we count tokens appearing multiple times not just
-               # once but as often as they appear in the learned texts
-
-               $rel_ham = $data['count_ham'];
-               $rel_spam = $data['count_spam'];
-
-               if($texts_ham > 0)
-                       $rel_ham = $data['count_ham'] / $texts_ham;
-
-               if($texts_spam > 0)
-                       $rel_spam = $data['count_spam'] / $texts_spam;
-
-               $rating = $rel_spam / ($rel_ham + $rel_spam);
-
-               # Calculate the better probability proposed by Mr. Robinson
-               $all = $data['count_ham'] + $data['count_spam'];
-               return (($this->config['rob_s'] * $this->config['rob_x']) + ($all * $rating)) / ($this->config['rob_s'] + $all);
-
-       }
-
-       /**
-        * Check the validity of the category of a request
-        *
-        * @access private
-        * @param string $category
-        * @return void
-        */
-
-       private function _check_category($category)
-       {
-               return $category === self::HAM or $category === self::SPAM;
-       }
-
-       /**
-        * Learn a reference text
-        *
-        * @access public
-        * @param string $text
-        * @param const $category Either b8::SPAM or b8::HAM
-        * @return void
-        */
-
-       public function learn($text, $category, $uid)
-       {
-               return $this->_process_text($text, $category, self::LEARN, $uid);
-       }
-
-       /**
-        * Unlearn a reference text
-        *
-        * @access public
-        * @param string $text
-        * @param const $category Either b8::SPAM or b8::HAM
-        * @return void
-        */
-
-       public function unlearn($text, $category, $uid)
-       {
-               return $this->_process_text($text, $category, self::UNLEARN, $uid);
-       }
-
-       /**
-        * Does the actual interaction with the storage backend for learning or unlearning texts
-        *
-        * @access private
-        * @param string $text
-        * @param const $category Either b8::SPAM or b8::HAM
-        * @param const $action Either b8::LEARN or b8::UNLEARN
-        * @return void
-        */
-
-       private function _process_text($text, $category, $action, $uid = 0)
-       {
-
-               # Validate the startup
-
-               $started_up = $this->validate();
-
-               if($started_up !== TRUE)
-                       return $started_up;
-
-               # Look if the request is okay
-               if($this->_check_category($category) === FALSE)
-                       return self::TRAINER_CATEGORY_FAIL;
-
-               # Get all tokens from $text
-
-               $tokens = $this->_lexer->get_tokens($text);
-
-               # Check if the lexer failed
-               # (if so, $tokens will be a lexer error code, if not, $tokens will be an array)
-               if(!is_array($tokens))
-                       return $tokens;
-
-               # Pass the tokens and what to do with it to the storage backend
-               return $this->_database->process_text($tokens, $category, $action, $uid);
-
-       }
-
-}
-
-?>
\ No newline at end of file
diff --git a/library/spam/b8/b8.php.ORIG b/library/spam/b8/b8.php.ORIG
deleted file mode 100644 (file)
index ea1e15f..0000000
+++ /dev/null
@@ -1,503 +0,0 @@
-<?php
-
-#   Copyright (C) 2006-2010 Tobias Leupold <tobias.leupold@web.de>
-#
-#   b8 - A Bayesian spam filter written in PHP 5
-#
-#   This program is free software; you can redistribute it and/or modify it
-#   under the terms of the GNU Lesser General Public License as published by
-#   the Free Software Foundation in version 2.1 of the License.
-#
-#   This program is distributed in the hope that it will be useful, but
-#   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-#   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-#   License for more details.
-#
-#   You should have received a copy of the GNU Lesser General Public License
-#   along with this program; if not, write to the Free Software Foundation,
-#   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-
-/**
- * Copyright (C) 2006-2010 Tobias Leupold <tobias.leupold@web.de>
- *
- * @license LGPL
- * @access public
- * @package b8
- * @author Tobias Leupold
- * @author Oliver Lillie (aka buggedcom) (original PHP 5 port)
- */
-
-class b8
-{
-
-       public $config = array(
-               'min_size'      => 3,
-               'max_size'      => 30,
-               'allow_numbers' => FALSE,
-               'lexer'         => 'default',
-               'degenerator'   => 'default',
-               'storage'       => 'dba',
-               'use_relevant'  => 15,
-               'min_dev'       => 0.2,
-               'rob_s'         => 0.3,
-               'rob_x'         => 0.5
-       );
-
-       private $_lexer      = NULL;
-       private $_database   = NULL;
-       private $_token_data = NULL;
-
-       const SPAM    = 'spam';
-       const HAM     = 'ham';
-       const LEARN   = 'learn';
-       const UNLEARN = 'unlearn';
-
-       const STARTUP_FAIL_DATABASE = 'STARTUP_FAIL_DATABASE';
-       const STARTUP_FAIL_LEXER    = 'STARTUP_FAIL_LEXER';
-       const TRAINER_CATEGORY_FAIL = 'TRAINER_CATEGORY_FAIL';
-
-       /**
-        * Constructs b8
-        *
-        * @access public
-        * @return void
-        */
-
-       function __construct($config = array(), $database_config)
-       {
-
-               # Validate config data
-
-               if(count($config) > 0) {
-
-                       foreach ($config as $name=>$value) {
-
-                               switch($name) {
-
-                                       case 'min_dev':
-                                       case 'rob_s':
-                                       case 'rob_x':
-                                               $this->config[$name] = (float) $value;
-                                               break;
-
-                                       case 'min_size':
-                                       case 'max_size':
-                                       case 'use_relevant':
-                                               $this->config[$name] = (int) $value;
-                                               break;
-
-                                       case 'allow_numbers':
-                                               $this->config[$name] = (bool) $value;
-                                               break;
-
-                                       case 'lexer':
-                                               $value = (string) strtolower($value);
-                                               $this->config[$name] = is_file(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'lexer' . DIRECTORY_SEPARATOR . "lexer_" . $value . '.php') === TRUE ? $value : 'default';
-                                               break;
-
-                                       case 'storage':
-                                               $this->config[$name] = (string) $value;
-                                               break;
-
-                               }
-
-                       }
-
-               }
-
-               # Setup the database backend
-
-               # Get the basic storage class used by all backends
-               if($this->load_class('b8_storage_base', dirname(__FILE__) . DIRECTORY_SEPARATOR . 'storage' . DIRECTORY_SEPARATOR . 'storage_base.php') === FALSE)
-                       return;
-
-               # Get the degenerator we need
-               if($this->load_class('b8_degenerator_' . $this->config['degenerator'], dirname(__FILE__) . DIRECTORY_SEPARATOR . 'degenerator' . DIRECTORY_SEPARATOR . 'degenerator_' . $this->config['degenerator'] . '.php') === FALSE)
-                       return;
-
-               # Get the actual storage backend we need
-               if($this->load_class('b8_storage_' . $this->config['storage'], dirname(__FILE__) . DIRECTORY_SEPARATOR . 'storage' . DIRECTORY_SEPARATOR . 'storage_' . $this->config['storage'] . '.php') === FALSE)
-                       return;
-
-               # Setup the backend
-               $class = 'b8_storage_' . $this->config['storage'];
-               $this->_database = new $class(
-                       $database_config,
-                       $this->config['degenerator'], date('ymd')
-               );
-
-               # Setup the lexer class
-
-               if($this->load_class('b8_lexer_' . $this->config['lexer'], dirname(__FILE__) . DIRECTORY_SEPARATOR . 'lexer' . DIRECTORY_SEPARATOR . 'lexer_' . $this->config['lexer'] . '.php') === FALSE)
-                       return;
-
-               $class = 'b8_lexer_' . $this->config['lexer'];
-               $this->_lexer = new $class(
-                       array(
-                               'min_size' => $this->config['min_size'],
-                               'max_size' => $this->config['max_size'],
-                               'allow_numbers' => $this->config['allow_numbers']
-                       )
-               );
-
-       }
-
-       /**
-        * Load a class file if a class has not been defined yet.
-        *
-        * @access public
-        * @return boolean Returns TRUE if everything is okay, otherwise FALSE.
-        */
-
-       public function load_class($class_name, $class_file)
-       {
-
-               if(class_exists($class_name, FALSE) === FALSE) {
-
-                       $included = require_once $class_file;
-
-                       if($included === FALSE or class_exists($class_name, FALSE) === FALSE)
-                               return FALSE;
-
-               }
-
-               return TRUE;
-
-       }
-
-       /**
-        * Validates the class has all it needs to work.
-        *
-        * @access public
-        * @return mixed Returns TRUE if everything is okay, otherwise an error code.
-        */
-
-       public function validate()
-       {
-
-               if($this->_database === NULL)
-                       return self::STARTUP_FAIL_DATABASE;
-
-               # Connect the database backend if we aren't connected yet
-
-               elseif($this->_database->connected === FALSE) {
-
-                       $connection = $this->_database->connect();
-
-                       if($connection !== TRUE)
-                               return $connection;
-
-               }
-
-               if($this->_lexer === NULL)
-                       return self::STARTUP_FAIL_LEXER;
-
-               return TRUE;
-
-       }
-
-       /**
-        * Classifies a text
-        *
-        * @access public
-        * @package default
-        * @param string $text
-        * @return float The rating between 0 (ham) and 1 (spam)
-        */
-
-       public function classify($text)
-       {
-
-               # Validate the startup
-
-               $started_up = $this->validate();
-
-               if($started_up !== TRUE)
-                       return $started_up;
-
-               # Get the internal database variables, containing the number of ham and
-               # spam texts so the spam probability can be calculated in relation to them
-               $internals = $this->_database->get_internals();
-
-               # Calculate the spamminess of all tokens
-
-               # Get all tokens we want to rate
-
-               $tokens = $this->_lexer->get_tokens($text);
-
-               # Check if the lexer failed
-               # (if so, $tokens will be a lexer error code, if not, $tokens will be an array)
-               if(!is_array($tokens))
-                       return $tokens;
-
-               # Fetch all availible data for the token set from the database
-               $this->_token_data = $this->_database->get(array_keys($tokens));
-
-               # Calculate the spamminess and importance for each token (or a degenerated form of it)
-
-               $word_count = array();
-               $rating     = array();
-               $importance = array();
-
-               foreach($tokens as $word => $count) {
-
-                       $word_count[$word] = $count;
-
-                       # Although we only call this function only here ... let's do the
-                       # calculation stuff in a function to make this a bit less confusing ;-)
-                       $rating[$word] = $this->_get_probability($word, $internals['texts_ham'], $internals['texts_spam']);
-
-                       $importance[$word] = abs(0.5 - $rating[$word]);
-
-               }
-
-               # Order by importance
-               arsort($importance);
-               reset($importance);
-
-               # Get the most interesting tokens (use all if we have less than the given number)
-
-               $relevant = array();
-
-               for($i = 0; $i < $this->config['use_relevant']; $i++) {
-
-                       if($tmp = each($importance)) {
-
-                               # Important tokens remain
-
-                               # If the token's rating is relevant enough, use it
-
-                               if(abs(0.5 - $rating[$tmp['key']]) > $this->config['min_dev']) {
-
-                                       # Tokens that appear more than once also count more than once
-
-                                       for($x = 0, $l = $word_count[$tmp['key']]; $x < $l; $x++)
-                                               array_push($relevant, $rating[$tmp['key']]);
-
-                               }
-
-                       }
-
-                       else {
-                               # We have less than words to use, so we already
-                               # use what we have and can break here
-                               break;
-                       }
-
-               }
-
-               # Calculate the spamminess of the text (thanks to Mr. Robinson ;-)
-               # We set both hamminess and Spamminess to 1 for the first multiplying
-               $hamminess  = 1;
-               $spamminess = 1;
-
-               # Consider all relevant ratings
-               foreach($relevant as $value) {
-                       $hamminess  *= (1.0 - $value);
-                       $spamminess *= $value;
-               }
-
-               # If no token was good for calculation, we really don't know how
-               # to rate this text; so we assume a spam and ham probability of 0.5
-
-               if($hamminess === 1 and $spamminess === 1) {
-                       $hamminess = 0.5;
-                       $spamminess = 0.5;
-                       $n = 1;
-               }
-               else {
-                       # Get the number of relevant ratings
-                       $n = count($relevant);
-               }
-
-               # Calculate the combined rating
-
-               # The actual hamminess and spamminess
-               $hamminess  = 1 - pow($hamminess,  (1 / $n));
-               $spamminess = 1 - pow($spamminess, (1 / $n));
-
-               # Calculate the combined indicator
-               $probability = ($hamminess - $spamminess) / ($hamminess + $spamminess);
-
-               # We want a value between 0 and 1, not between -1 and +1, so ...
-               $probability = (1 + $probability) / 2;
-
-               # Alea iacta est
-               return $probability;
-
-       }
-
-       /**
-        * Calculate the spamminess of a single token also considering "degenerated" versions
-        *
-        * @access private
-        * @param string $word
-        * @param string $texts_ham
-        * @param string $texts_spam
-        * @return void
-        */
-
-       private function _get_probability($word, $texts_ham, $texts_spam)
-       {
-
-               # Let's see what we have!
-
-               if(isset($this->_token_data['tokens'][$word]) === TRUE) {
-                       # The token was in the database, so we can use it's data as-is
-                       # and calculate the spamminess of this token directly
-                       return $this->_calc_probability($this->_token_data['tokens'][$word], $texts_ham, $texts_spam);
-               }
-
-               # Damn. The token was not found, so do we have at least similar words?
-
-               if(isset($this->_token_data['degenerates'][$word]) === TRUE) {
-
-                       # We found similar words, so calculate the spamminess for each one
-                       # and choose the most important one for the further calculation
-
-                       # The default rating is 0.5 simply saying nothing
-                       $rating = 0.5;
-
-                       foreach($this->_token_data['degenerates'][$word] as $degenerate => $count) {
-
-                               # Calculate the rating of the current degenerated token
-                               $rating_tmp = $this->_calc_probability($count, $texts_ham, $texts_spam);
-
-                               # Is it more important than the rating of another degenerated version?
-                               if(abs(0.5 - $rating_tmp) > abs(0.5 - $rating))
-                                       $rating = $rating_tmp;
-
-                       }
-
-                       return $rating;
-
-               }
-
-               else {
-                       # The token is really unknown, so choose the default rating
-                       # for completely unknown tokens. This strips down to the
-                       # robX parameter so we can cheap out the freaky math ;-)
-                       return $this->config['rob_x'];
-               }
-
-       }
-
-       /**
-        * Do the actual spamminess calculation of a single token
-        *
-        * @access private
-        * @param array $data
-        * @param string $texts_ham
-        * @param string $texts_spam
-        * @return void
-        */
-
-       private function _calc_probability($data, $texts_ham, $texts_spam)
-       {
-
-               # Calculate the basic probability by Mr. Graham
-
-               # But: consider the number of ham and spam texts saved instead of the
-               # number of entries where the token appeared to calculate a relative
-               # spamminess because we count tokens appearing multiple times not just
-               # once but as often as they appear in the learned texts
-
-               $rel_ham = $data['count_ham'];
-               $rel_spam = $data['count_spam'];
-
-               if($texts_ham > 0)
-                       $rel_ham = $data['count_ham'] / $texts_ham;
-
-               if($texts_spam > 0)
-                       $rel_spam = $data['count_spam'] / $texts_spam;
-
-               $rating = $rel_spam / ($rel_ham + $rel_spam);
-
-               # Calculate the better probability proposed by Mr. Robinson
-               $all = $data['count_ham'] + $data['count_spam'];
-               return (($this->config['rob_s'] * $this->config['rob_x']) + ($all * $rating)) / ($this->config['rob_s'] + $all);
-
-       }
-
-       /**
-        * Check the validity of the category of a request
-        *
-        * @access private
-        * @param string $category
-        * @return void
-        */
-
-       private function _check_category($category)
-       {
-               return $category === self::HAM or $category === self::SPAM;
-       }
-
-       /**
-        * Learn a reference text
-        *
-        * @access public
-        * @param string $text
-        * @param const $category Either b8::SPAM or b8::HAM
-        * @return void
-        */
-
-       public function learn($text, $category)
-       {
-               return $this->_process_text($text, $category, self::LEARN);
-       }
-
-       /**
-        * Unlearn a reference text
-        *
-        * @access public
-        * @param string $text
-        * @param const $category Either b8::SPAM or b8::HAM
-        * @return void
-        */
-
-       public function unlearn($text, $category)
-       {
-               return $this->_process_text($text, $category, self::UNLEARN);
-       }
-
-       /**
-        * Does the actual interaction with the storage backend for learning or unlearning texts
-        *
-        * @access private
-        * @param string $text
-        * @param const $category Either b8::SPAM or b8::HAM
-        * @param const $action Either b8::LEARN or b8::UNLEARN
-        * @return void
-        */
-
-       private function _process_text($text, $category, $action)
-       {
-
-               # Validate the startup
-
-               $started_up = $this->validate();
-
-               if($started_up !== TRUE)
-                       return $started_up;
-
-               # Look if the request is okay
-               if($this->_check_category($category) === FALSE)
-                       return self::TRAINER_CATEGORY_FAIL;
-
-               # Get all tokens from $text
-
-               $tokens = $this->_lexer->get_tokens($text);
-
-               # Check if the lexer failed
-               # (if so, $tokens will be a lexer error code, if not, $tokens will be an array)
-               if(!is_array($tokens))
-                       return $tokens;
-
-               # Pass the tokens and what to do with it to the storage backend
-               return $this->_database->process_text($tokens, $category, $action);
-
-       }
-
-}
-
-?>
\ No newline at end of file
diff --git a/library/spam/b8/degenerator/degenerator_default.php b/library/spam/b8/degenerator/degenerator_default.php
deleted file mode 100644 (file)
index 4ff6d88..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-<?php
-
-#   Copyright (C) 2006-2010 Tobias Leupold <tobias.leupold@web.de>
-#
-#   This file is part of the b8 package
-#
-#   This program is free software; you can redistribute it and/or modify it
-#   under the terms of the GNU Lesser General Public License as published by
-#   the Free Software Foundation in version 2.1 of the License.
-#
-#   This program is distributed in the hope that it will be useful, but
-#   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-#   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-#   License for more details.
-#
-#   You should have received a copy of the GNU Lesser General Public License
-#   along with this program; if not, write to the Free Software Foundation,
-#   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-
-/**
- * Copyright (C) 2006-2010 Tobias Leupold <tobias.leupold@web.de>
- *
- * @license LGPL
- * @access public
- * @package b8
- * @author Tobias Leupold
- */
-
-class b8_degenerator_default
-{
-
-       public $degenerates = array();
-
-       /**
-        * Generates a list of "degenerated" words for a list of words.
-        *
-        * @access public
-        * @param array $tokens
-        * @return array An array containing an array of degenerated tokens for each token
-        */
-
-       public function degenerate(array $words)
-       {
-
-               $degenerates = array();
-
-               foreach($words as $word)
-                       $degenerates[$word] = $this->_degenerate_word($word);
-
-               return $degenerates;
-
-       }
-
-       /**
-        * If the original word is not found in the database then
-        * we build "degenerated" versions of the word to lookup.
-        *
-        * @access private
-        * @param string $word
-        * @return array An array of degenerated words
-        */
-
-       protected function _degenerate_word($word)
-       {
-
-               # Check for any stored words so the process doesn't have to repeat
-               if(isset($this->degenerates[$word]) === TRUE)
-                       return $this->degenerates[$word];
-
-               $degenerate = array();
-
-               # Add different version of upper and lower case and ucfirst
-               array_push($degenerate, strtolower($word));
-               array_push($degenerate, strtoupper($word));
-               array_push($degenerate, ucfirst($word));
-
-               # Degenerate all versions
-
-               foreach($degenerate as $alt_word) {
-
-                       # Look for stuff like !!! and ???
-
-                       if(preg_match('/[!?]$/', $alt_word) > 0) {
-
-                               # Add versions with different !s and ?s
-
-                               if(preg_match('/[!?]{2,}$/', $alt_word) > 0) {
-                                       $tmp = preg_replace('/([!?])+$/', '$1', $alt_word);
-                                       array_push($degenerate, $tmp);
-                               }
-
-                               $tmp = preg_replace('/([!?])+$/', '', $alt_word);
-                               array_push($degenerate, $tmp);
-
-                       }
-
-                       # Look for ... at the end of the word
-
-                       $alt_word_int = $alt_word;
-
-                       while(preg_match('/[\.]$/', $alt_word_int) > 0) {
-                               $alt_word_int = substr($alt_word_int, 0, strlen($alt_word_int) - 1);
-                               array_push($degenerate, $alt_word_int);
-                       }
-
-               }
-
-               # Some degenerates are the same as the original word. These don't have
-               # to be fetched, so we create a new array with only new tokens
-
-               $real_degenerate = array();
-
-               foreach($degenerate as $deg_word) {
-                       if($word != $deg_word)
-                               array_push($real_degenerate, $deg_word);
-               }
-
-               # Store the list of degenerates for the token
-               $this->degenerates[$word] = $real_degenerate;
-
-               return $real_degenerate;
-
-       }
-
-}
-
-?>
\ No newline at end of file
diff --git a/library/spam/b8/lexer/lexer_default.php b/library/spam/b8/lexer/lexer_default.php
deleted file mode 100644 (file)
index 7b5ca22..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-<?php
-
-#   Copyright (C) 2006-2010 Tobias Leupold <tobias.leupold@web.de>
-#
-#   This file is part of the b8 package
-#
-#   This program is free software; you can redistribute it and/or modify it
-#   under the terms of the GNU Lesser General Public License as published by
-#   the Free Software Foundation in version 2.1 of the License.
-#
-#   This program is distributed in the hope that it will be useful, but
-#   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-#   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-#   License for more details.
-#
-#   You should have received a copy of the GNU Lesser General Public License
-#   along with this program; if not, write to the Free Software Foundation,
-#   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-
-/**
- * Copyright (C) 2006-2010 Tobias Leupold <tobias.leupold@web.de>
- *
- * @license LGPL
- * @access public
- * @package b8
- * @author Tobias Leupold
- * @author Oliver Lillie (aka buggedcom) (original PHP 5 port)
- */
-
-class b8_lexer_default
-{
-
-       const LEXER_TEXT_NOT_STRING = 'LEXER_TEXT_NOT_STRING';
-       const LEXER_TEXT_EMPTY      = 'LEXER_TEXT_EMPTY';
-
-       public $config = NULL;
-
-       # The regular expressions we use to split the text to tokens
-
-       public $regexp = array(
-               'ip'        => '/([A-Za-z0-9\_\-\.]+)/',
-               'raw_split' => '/[\s,\.\/"\:;\|<>\-_\[\]{}\+=\)\(\*\&\^%]+/',
-               'html'      => '/(<.+?>)/',
-               'tagname'   => '/(.+?)\s/',
-               'numbers'   => '/^[0-9]+$/'
-       );
-
-       /**
-        * Constructs the lexer.
-        *
-        * @access public
-        * @return void
-        */
-
-       function __construct($config)
-       {
-               $this->config = $config;
-       }
-
-       /**
-        * Generates the tokens required for the bayesian filter.
-        *
-        * @access public
-        * @param string $text
-        * @return array Returns the list of tokens
-        */
-
-       public function get_tokens($text)
-       {
-
-               # Check that we actually have a string ...
-               if(is_string($text) === FALSE)
-                       return self::LEXER_TEXT_NOT_STRING;
-
-               # ... and that it's not empty
-               if(empty($text) === TRUE)
-                       return self::LEXER_TEXT_EMPTY;
-
-               # Re-convert the text to the original characters coded in UTF-8, as
-               # they have been coded in html entities during the post process
-               $text = html_entity_decode($text, ENT_QUOTES, 'UTF-8');
-
-               $tokens = array();
-
-               # Find URLs and IP addresses
-
-               preg_match_all($this->regexp['ip'], $text, $raw_tokens);
-
-               foreach($raw_tokens[1] as $word) {
-
-                       # Check for a dot
-                       if(strpos($word, '.') === FALSE)
-                               continue;
-
-                       # Check that the word is valid, min and max sizes, etc.
-                       if($this->_is_valid($word) === FALSE)
-                               continue;
-
-                       if(isset($tokens[$word]) === FALSE)
-                               $tokens[$word] = 1;
-                       else
-                               $tokens[$word] += 1;
-
-                       # Delete the word from the text so it doesn't get re-added.
-                       $text = str_replace($word, '', $text);
-
-                       # Also process the parts of the URLs
-                       $url_parts = preg_split($this->regexp['raw_split'], $word);
-
-                       foreach($url_parts as $word) {
-
-                               # Again validate the part
-
-                               if($this->_is_valid($word) === FALSE)
-                                       continue;
-
-                               if(isset($tokens[$word]) === FALSE)
-                                       $tokens[$word] = 1;
-                               else
-                                       $tokens[$word] += 1;
-
-                       }
-
-               }
-
-               # Split the remaining text
-
-               $raw_tokens = preg_split($this->regexp['raw_split'], $text);
-
-               foreach($raw_tokens as $word) {
-
-                       # Again validate the part
-
-                       if($this->_is_valid($word) === FALSE)
-                               continue;
-
-                       if(isset($tokens[$word]) === FALSE)
-                               $tokens[$word] = 1;
-                       else
-                               $tokens[$word] += 1;
-
-               }
-
-               # Process the HTML
-
-               preg_match_all($this->regexp['html'], $text, $raw_tokens);
-
-               foreach($raw_tokens[1] as $word) {
-
-                       # Again validate the part
-
-                       if($this->_is_valid($word) === FALSE)
-                               continue;
-
-                       # If the tag has parameters, just use the tag itself
-
-                       if(strpos($word, ' ') !== FALSE) {
-                               preg_match($this->regexp['tagname'], $word, $tmp);
-                               $word = "{$tmp[1]}...>";
-                       }
-
-                       if(isset($tokens[$word]) === FALSE)
-                               $tokens[$word] = 1;
-                       else
-                               $tokens[$word] += 1;
-
-               }
-
-               # Return a list of all found tokens
-               return $tokens;
-
-       }
-
-       /**
-        * Validates a token.
-        *
-        * @access private
-        * @param string $token The token string.
-        * @return boolean Returns TRUE if the token is valid, otherwise returns FALSE
-        */
-
-       private function _is_valid($token)
-       {
-
-               # Validate the size of the token
-
-               $len = strlen($token);
-
-               if($len < $this->config['min_size'] or $len > $this->config['max_size'])
-                       return FALSE;
-
-               # We may want to exclude pure numbers
-               if($this->config['allow_numbers'] === FALSE) {
-                       if(preg_match($this->regexp['numbers'], $token) > 0)
-                               return FALSE;
-               }
-
-               # Token is okay
-               return TRUE;
-
-       }
-
-}
-
-?>
\ No newline at end of file
diff --git a/library/spam/b8/storage/storage_base.php b/library/spam/b8/storage/storage_base.php
deleted file mode 100644 (file)
index 6b181ee..0000000
+++ /dev/null
@@ -1,396 +0,0 @@
-<?php
-
-#   Copyright (C) 2010 Tobias Leupold <tobias.leupold@web.de>
-#
-#   This file is part of the b8 package
-#
-#   This program is free software; you can redistribute it and/or modify it
-#   under the terms of the GNU Lesser General Public License as published by
-#   the Free Software Foundation in version 2.1 of the License.
-#
-#   This program is distributed in the hope that it will be useful, but
-#   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-#   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-#   License for more details.
-#
-#   You should have received a copy of the GNU Lesser General Public License
-#   along with this program; if not, write to the Free Software Foundation,
-#   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-
-/**
- * Functions used by all storage backends
- * Copyright (C) 2010 Tobias Leupold <tobias.leupold@web.de>
- *
- * @license LGPL
- * @access public
- * @package b8
- * @author Tobias Leupold
- */
-
-abstract class b8_storage_base
-{
-
-       public $connected            = FALSE;
-
-       protected $_degenerator      = NULL;
-
-       const INTERNALS_TEXTS_HAM    = 'bayes*texts.ham';
-       const INTERNALS_TEXTS_SPAM   = 'bayes*texts.spam';
-       const INTERNALS_DBVERSION    = 'bayes*dbversion';
-
-       const BACKEND_NOT_CONNECTED  = 'BACKEND_NOT_CONNECTED';
-       const DATABASE_WRONG_VERSION = 'DATABASE_WRONG_VERSION';
-       const DATABASE_NOT_B8        = 'DATABASE_NOT_B8';
-
-       /**
-        * Validates the class has all it needs to work.
-        *
-        * @access protected
-        * @return mixed Returns TRUE if everything is okay, otherwise an error code.
-        */
-
-       protected function validate()
-       {
-
-               # We set up the degenerator here, as we would have to duplicate code if it
-               # was done in the constructor of the respective storage backend.
-               $class = 'b8_degenerator_' . $this->b8_config['degenerator'];
-               $this->_degenerator = new $class();
-
-               if($this->connected !== TRUE)
-                       return self::BACKEND_NOT_CONNECTED;
-
-               return TRUE;
-
-       }
-
-       /**
-        * Checks if a b8 database is used and if it's version is okay
-        *
-        * @access protected
-        * @return mixed Returns TRUE if everything is okay, otherwise an error code.
-        */
-
-       protected function check_database($uid)
-       {
-
-               $internals = $this->get_internals($uid);
-
-               if(isset($internals['dbversion'])) {
-                       if($internals['dbversion'] == "2") {
-                               return TRUE;
-                       }
-                       else {
-                               $this->connected = FALSE;
-                               return self::DATABASE_WRONG_VERSION;
-                       }
-               }
-               else {
-                       $this->connected = FALSE;
-                       return self::DATABASE_NOT_B8;
-               }
-
-       }
-
-       /**
-        * Parses the "count" data of a token.
-        *
-        * @access private
-        * @param string $data
-        * @return array Returns an array of the parsed data: array(count_ham, count_spam, lastseen).
-        */
-
-       private function _parse_count($data)
-       {
-
-               list($count_ham, $count_spam, $lastseen) = explode(' ', $data);
-
-               $count_ham  = (int) $count_ham;
-               $count_spam = (int) $count_spam;
-
-               return array(
-                       'count_ham'  => $count_ham,
-                       'count_spam' => $count_spam
-               );
-
-       }
-
-       /**
-        * Get the database's internal variables.
-        *
-        * @access public
-        * @return array Returns an array of all internals.
-        */
-
-       public function get_internals($uid)
-       {
-
-               $internals = $this->_get_query(
-                       array(
-                               self::INTERNALS_TEXTS_HAM,
-                               self::INTERNALS_TEXTS_SPAM,
-                               self::INTERNALS_DBVERSION
-                       ),
-                       $uid
-               );
-
-               return array(
-                       'texts_ham'  => (int) $internals[self::INTERNALS_TEXTS_HAM],
-                       'texts_spam' => (int) $internals[self::INTERNALS_TEXTS_SPAM],
-                       'dbversion'  => (int) $internals[self::INTERNALS_DBVERSION]
-               );
-
-       }
-
-       /**
-        * Get all data about a list of tags from the database.
-        *
-        * @access public
-        * @param array $tokens
-        * @return mixed Returns FALSE on failure, otherwise returns array of returned data in the format array('tokens' => array(token => count), 'degenerates' => array(token => array(degenerate => count))).
-        */
-
-       public function get($tokens, $uid)
-       {
-
-               # Validate the startup
-
-               $started_up = $this->validate();
-
-               if($started_up !== TRUE)
-                       return $started_up;
-
-               # First we see what we have in the database.
-               $token_data = $this->_get_query($tokens, $uid);
-
-               # Check if we have to degenerate some tokens
-
-               $missing_tokens = array();
-
-               foreach($tokens as $token) {
-                       if(!isset($token_data[$token]))
-                               $missing_tokens[] = $token;
-               }
-
-               if(count($missing_tokens) > 0) {
-
-                       # We have to degenerate some tokens
-                       $degenerates_list = array();
-
-                       # Generate a list of degenerated tokens for the missing tokens ...
-                       $degenerates = $this->_degenerator->degenerate($missing_tokens);
-
-                       # ... and look them up
-
-                       foreach($degenerates as $token => $token_degenerates)
-                               $degenerates_list = array_merge($degenerates_list, $token_degenerates);
-
-                       $token_data = array_merge($token_data, $this->_get_query($degenerates_list));
-
-               }
-
-               # Here, we have all availible data in $token_data.
-
-               $return_data_tokens = array();
-               $return_data_degenerates = array();
-
-               foreach($tokens as $token) {
-
-                       if(isset($token_data[$token]) === TRUE) {
-
-                               # The token was found in the database
-
-                               # Add the data ...
-                               $return_data_tokens[$token] = $this->_parse_count($token_data[$token]);
-
-                               # ... and update it's lastseen parameter
-                               $this->_update($token, "{$return_data_tokens[$token]['count_ham']} {$return_data_tokens[$token]['count_spam']} " . $this->b8_config['today'], $uid );
-
-                       }
-
-                       else {
-
-                               # The token was not found, so we look if we
-                               # can return data for degenerated tokens
-
-                               # Check all degenerated forms of the token
-
-                               foreach($this->_degenerator->degenerates[$token] as $degenerate) {
-
-                                       if(isset($token_data[$degenerate]) === TRUE) {
-
-                                               # A degeneration of the token way found in the database
-
-                                               # Add the data ...
-                                               $return_data_degenerates[$token][$degenerate] = $this->_parse_count($token_data[$degenerate]);
-
-                                               # ... and update it's lastseen parameter
-                                               $this->_update($degenerate, "{$return_data_degenerates[$token][$degenerate]['count_ham']} {$return_data_degenerates[$token][$degenerate]['count_spam']} " . $this->b8_config['today'], $uid);
-
-                                       }
-
-                               }
-
-                       }
-
-               }
-
-               # Now, all token data directly found in the database is in $return_data_tokens
-               # and all data for degenerated versions is in $return_data_degenerates
-
-               # First, we commit the changes to the lastseen parameters
-               $this->_commit();
-
-               # Then, we return what we have
-               return array(
-                       'tokens'      => $return_data_tokens,
-                       'degenerates' => $return_data_degenerates
-               );
-
-       }
-
-       /**
-        * Stores or deletes a list of tokens from the given category.
-        *
-        * @access public
-        * @param array $tokens
-        * @param const $category Either b8::HAM or b8::SPAM
-        * @param const $action Either b8::LEARN or b8::UNLEARN
-        * @return void
-        */
-
-       public function process_text($tokens, $category, $action, $uid)
-       {
-
-               # Validate the startup
-
-               $started_up = $this->validate();
-
-               if($started_up !== TRUE)
-                       return $started_up;
-
-               # No matter what we do, we first have to check what data we have.
-
-               # First get the internals, including the ham texts and spam texts counter
-               $internals = $this->get_internals($uid);
-
-               # Then, fetch all data for all tokens we have (and update their lastseen parameters)
-               $token_data = $this->_get_query(array_keys($tokens), $uid);
-
-               # Process all tokens to learn/unlearn
-
-               foreach($tokens as $token => $count) {
-
-                       if(isset($token_data[$token])) {
-
-                               # We already have this token, so update it's data
-
-                               # Get the existing data
-                               list($count_ham, $count_spam, $lastseen) = explode(' ', $token_data[$token]);
-                               $count_ham  = (int) $count_ham;
-                               $count_spam = (int) $count_spam;
-
-                               # Increase or decrease the right counter
-
-                               if($action === b8::LEARN) {
-                                       if($category === b8::HAM)
-                                               $count_ham += $count;
-                                       elseif($category === b8::SPAM)
-                                               $count_spam += $count;
-                               }
-
-                               elseif($action == b8::UNLEARN) {
-                                       if($category === b8::HAM)
-                                               $count_ham -= $count;
-                                       elseif($category === b8::SPAM)
-                                               $count_spam -= $count;
-                               }
-
-                               # We don't want to have negative values
-
-                               if($count_ham < 0)
-                                       $count_ham = 0;
-
-                               if($count_spam < 0)
-                                       $count_spam = 0;
-
-                               # Now let's see if we have to update or delete the token
-                               if($count_ham !== 0 or $count_spam !== 0)
-                                       $this->_update($token, "$count_ham $count_spam " . $this->b8_config['today'], $uid);
-                               else
-                                       $this->_del($token, $uid);
-
-                       }
-
-                       else {
-
-                               # We don't have the token. If we unlearn a text, we can't delete it
-                               # as we don't have it anyway, so just do something if we learn a text
-
-                               if($action === b8::LEARN) {
-
-                                       if($category === b8::HAM)
-                                               $data = '1 0 ';
-                                       elseif($category === b8::SPAM)
-                                               $data = '0 1 ';
-
-                                       $data .= $this->b8_config['today'];
-
-                                       $this->_put($token, $data, $uid);
-
-                               }
-
-                       }
-
-               }
-
-               # Now, all token have been processed, so let's update the right text
-
-               if($action === b8::LEARN) {
-
-                       if($category === b8::HAM) {
-                               $internals['texts_ham']++;
-                               $this->_update(self::INTERNALS_TEXTS_HAM, $internals['texts_ham'], $uid);
-                       }
-
-                       elseif($category === b8::SPAM) {
-                               $internals['texts_spam']++;
-                               $this->_update(self::INTERNALS_TEXTS_SPAM, $internals['texts_spam'], $uid);
-                       }
-
-               }
-
-               elseif($action == b8::UNLEARN) {
-
-                       if($category === b8::HAM) {
-
-                               $internals['texts_ham']--;
-
-                               if($internals['texts_ham'] < 0)
-                                       $internals['texts_ham'] = 0;
-
-                               $this->_update(self::INTERNALS_TEXTS_HAM, $internals['texts_ham'], $uid);
-
-                       }
-
-                       elseif($category === b8::SPAM) {
-
-                               $internals['texts_spam']--;
-
-                               if($internals['texts_spam'] < 0)
-                                       $internals['texts_spam'] = 0;
-
-                               $this->_update(self::INTERNALS_TEXTS_SPAM, $internals['texts_spam'], $uid);
-
-                       }
-
-               }
-
-               # We're done and can commit all changes to the database now
-               $this->_commit($uid);
-
-       }
-
-}
-
-?>
\ No newline at end of file
diff --git a/library/spam/b8/storage/storage_base.php.ORIG b/library/spam/b8/storage/storage_base.php.ORIG
deleted file mode 100644 (file)
index 01f5a69..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-<?php
-
-#   Copyright (C) 2010 Tobias Leupold <tobias.leupold@web.de>
-#
-#   This file is part of the b8 package
-#
-#   This program is free software; you can redistribute it and/or modify it
-#   under the terms of the GNU Lesser General Public License as published by
-#   the Free Software Foundation in version 2.1 of the License.
-#
-#   This program is distributed in the hope that it will be useful, but
-#   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-#   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-#   License for more details.
-#
-#   You should have received a copy of the GNU Lesser General Public License
-#   along with this program; if not, write to the Free Software Foundation,
-#   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-
-/**
- * Functions used by all storage backends
- * Copyright (C) 2010 Tobias Leupold <tobias.leupold@web.de>
- *
- * @license LGPL
- * @access public
- * @package b8
- * @author Tobias Leupold
- */
-
-abstract class b8_storage_base
-{
-
-       public $connected            = FALSE;
-
-       protected $_degenerator      = NULL;
-
-       const INTERNALS_TEXTS_HAM    = 'bayes*texts.ham';
-       const INTERNALS_TEXTS_SPAM   = 'bayes*texts.spam';
-       const INTERNALS_DBVERSION    = 'bayes*dbversion';
-
-       const BACKEND_NOT_CONNECTED  = 'BACKEND_NOT_CONNECTED';
-       const DATABASE_WRONG_VERSION = 'DATABASE_WRONG_VERSION';
-       const DATABASE_NOT_B8        = 'DATABASE_NOT_B8';
-
-       /**
-        * Validates the class has all it needs to work.
-        *
-        * @access protected
-        * @return mixed Returns TRUE if everything is okay, otherwise an error code.
-        */
-
-       protected function validate()
-       {
-
-               # We set up the degenerator here, as we would have to duplicate code if it
-               # was done in the constructor of the respective storage backend.
-               $class = 'b8_degenerator_' . $this->b8_config['degenerator'];
-               $this->_degenerator = new $class();
-
-               if($this->connected !== TRUE)
-                       return self::BACKEND_NOT_CONNECTED;
-
-               return TRUE;
-
-       }
-
-       /**
-        * Checks if a b8 database is used and if it's version is okay
-        *
-        * @access protected
-        * @return mixed Returns TRUE if everything is okay, otherwise an error code.
-        */
-
-       protected function check_database()
-       {
-
-               $internals = $this->get_internals();
-
-               if(isset($internals['dbversion'])) {
-                       if($internals['dbversion'] == "2") {
-                               return TRUE;
-                       }
-                       else {
-                               $this->connected = FALSE;
-                               return self::DATABASE_WRONG_VERSION;
-                       }
-               }
-               else {
-                       $this->connected = FALSE;
-                       return self::DATABASE_NOT_B8;
-               }
-
-       }
-
-       /**
-        * Parses the "count" data of a token.
-        *
-        * @access private
-        * @param string $data
-        * @return array Returns an array of the parsed data: array(count_ham, count_spam, lastseen).
-        */
-
-       private function _parse_count($data)
-       {
-
-               list($count_ham, $count_spam, $lastseen) = explode(' ', $data);
-
-               $count_ham  = (int) $count_ham;
-               $count_spam = (int) $count_spam;
-
-               return array(
-                       'count_ham'  => $count_ham,
-                       'count_spam' => $count_spam
-               );
-
-       }
-
-       /**
-        * Get the database's internal variables.
-        *
-        * @access public
-        * @return array Returns an array of all internals.
-        */
-
-       public function get_internals()
-       {
-
-               $internals = $this->_get_query(
-                       array(
-                               self::INTERNALS_TEXTS_HAM,
-                               self::INTERNALS_TEXTS_SPAM,
-                               self::INTERNALS_DBVERSION
-                       )
-               );
-
-               return array(
-                       'texts_ham'  => (int) $internals[self::INTERNALS_TEXTS_HAM],
-                       'texts_spam' => (int) $internals[self::INTERNALS_TEXTS_SPAM],
-                       'dbversion'  => (int) $internals[self::INTERNALS_DBVERSION]
-               );
-
-       }
-
-       /**
-        * Get all data about a list of tags from the database.
-        *
-        * @access public
-        * @param array $tokens
-        * @return mixed Returns FALSE on failure, otherwise returns array of returned data in the format array('tokens' => array(token => count), 'degenerates' => array(token => array(degenerate => count))).
-        */
-
-       public function get($tokens)
-       {
-
-               # Validate the startup
-
-               $started_up = $this->validate();
-
-               if($started_up !== TRUE)
-                       return $started_up;
-
-               # First we see what we have in the database.
-               $token_data = $this->_get_query($tokens);
-
-               # Check if we have to degenerate some tokens
-
-               $missing_tokens = array();
-
-               foreach($tokens as $token) {
-                       if(!isset($token_data[$token]))
-                               $missing_tokens[] = $token;
-               }
-
-               if(count($missing_tokens) > 0) {
-
-                       # We have to degenerate some tokens
-                       $degenerates_list = array();
-
-                       # Generate a list of degenerated tokens for the missing tokens ...
-                       $degenerates = $this->_degenerator->degenerate($missing_tokens);
-
-                       # ... and look them up
-
-                       foreach($degenerates as $token => $token_degenerates)
-                               $degenerates_list = array_merge($degenerates_list, $token_degenerates);
-
-                       $token_data = array_merge($token_data, $this->_get_query($degenerates_list));
-
-               }
-
-               # Here, we have all availible data in $token_data.
-
-               $return_data_tokens = array();
-               $return_data_degenerates = array();
-
-               foreach($tokens as $token) {
-
-                       if(isset($token_data[$token]) === TRUE) {
-
-                               # The token was found in the database
-
-                               # Add the data ...
-                               $return_data_tokens[$token] = $this->_parse_count($token_data[$token]);
-
-                               # ... and update it's lastseen parameter
-                               $this->_update($token, "{$return_data_tokens[$token]['count_ham']} {$return_data_tokens[$token]['count_spam']} " . $this->b8_config['today']);
-
-                       }
-
-                       else {
-
-                               # The token was not found, so we look if we
-                               # can return data for degenerated tokens
-
-                               # Check all degenerated forms of the token
-
-                               foreach($this->_degenerator->degenerates[$token] as $degenerate) {
-
-                                       if(isset($token_data[$degenerate]) === TRUE) {
-
-                                               # A degeneration of the token way found in the database
-
-                                               # Add the data ...
-                                               $return_data_degenerates[$token][$degenerate] = $this->_parse_count($token_data[$degenerate]);
-
-                                               # ... and update it's lastseen parameter
-                                               $this->_update($degenerate, "{$return_data_degenerates[$token][$degenerate]['count_ham']} {$return_data_degenerates[$token][$degenerate]['count_spam']} " . $this->b8_config['today']);
-
-                                       }
-
-                               }
-
-                       }
-
-               }
-
-               # Now, all token data directly found in the database is in $return_data_tokens
-               # and all data for degenerated versions is in $return_data_degenerates
-
-               # First, we commit the changes to the lastseen parameters
-               $this->_commit();
-
-               # Then, we return what we have
-               return array(
-                       'tokens'      => $return_data_tokens,
-                       'degenerates' => $return_data_degenerates
-               );
-
-       }
-
-       /**
-        * Stores or deletes a list of tokens from the given category.
-        *
-        * @access public
-        * @param array $tokens
-        * @param const $category Either b8::HAM or b8::SPAM
-        * @param const $action Either b8::LEARN or b8::UNLEARN
-        * @return void
-        */
-
-       public function process_text($tokens, $category, $action)
-       {
-
-               # Validate the startup
-
-               $started_up = $this->validate();
-
-               if($started_up !== TRUE)
-                       return $started_up;
-
-               # No matter what we do, we first have to check what data we have.
-
-               # First get the internals, including the ham texts and spam texts counter
-               $internals = $this->get_internals();
-
-               # Then, fetch all data for all tokens we have (and update their lastseen parameters)
-               $token_data = $this->_get_query(array_keys($tokens));
-
-               # Process all tokens to learn/unlearn
-
-               foreach($tokens as $token => $count) {
-
-                       if(isset($token_data[$token])) {
-
-                               # We already have this token, so update it's data
-
-                               # Get the existing data
-                               list($count_ham, $count_spam, $lastseen) = explode(' ', $token_data[$token]);
-                               $count_ham  = (int) $count_ham;
-                               $count_spam = (int) $count_spam;
-
-                               # Increase or decrease the right counter
-
-                               if($action === b8::LEARN) {
-                                       if($category === b8::HAM)
-                                               $count_ham += $count;
-                                       elseif($category === b8::SPAM)
-                                               $count_spam += $count;
-                               }
-
-                               elseif($action == b8::UNLEARN) {
-                                       if($category === b8::HAM)
-                                               $count_ham -= $count;
-                                       elseif($category === b8::SPAM)
-                                               $count_spam -= $count;
-                               }
-
-                               # We don't want to have negative values
-
-                               if($count_ham < 0)
-                                       $count_ham = 0;
-
-                               if($count_spam < 0)
-                                       $count_spam = 0;
-
-                               # Now let's see if we have to update or delete the token
-                               if($count_ham !== 0 or $count_spam !== 0)
-                                       $this->_update($token, "$count_ham $count_spam " . $this->b8_config['today']);
-                               else
-                                       $this->_del($token);
-
-                       }
-
-                       else {
-
-                               # We don't have the token. If we unlearn a text, we can't delete it
-                               # as we don't have it anyway, so just do something if we learn a text
-
-                               if($action === b8::LEARN) {
-
-                                       if($category === b8::HAM)
-                                               $data = '1 0 ';
-                                       elseif($category === b8::SPAM)
-                                               $data = '0 1 ';
-
-                                       $data .= $this->b8_config['today'];
-
-                                       $this->_put($token, $data);
-
-                               }
-
-                       }
-
-               }
-
-               # Now, all token have been processed, so let's update the right text
-
-               if($action === b8::LEARN) {
-
-                       if($category === b8::HAM) {
-                               $internals['texts_ham']++;
-                               $this->_update(self::INTERNALS_TEXTS_HAM, $internals['texts_ham']);
-                       }
-
-                       elseif($category === b8::SPAM) {
-                               $internals['texts_spam']++;
-                               $this->_update(self::INTERNALS_TEXTS_SPAM, $internals['texts_spam']);
-                       }
-
-               }
-
-               elseif($action == b8::UNLEARN) {
-
-                       if($category === b8::HAM) {
-
-                               $internals['texts_ham']--;
-
-                               if($internals['texts_ham'] < 0)
-                                       $internals['texts_ham'] = 0;
-
-                               $this->_update(self::INTERNALS_TEXTS_HAM, $internals['texts_ham']);
-
-                       }
-
-                       elseif($category === b8::SPAM) {
-
-                               $internals['texts_spam']--;
-
-                               if($internals['texts_spam'] < 0)
-                                       $internals['texts_spam'] = 0;
-
-                               $this->_update(self::INTERNALS_TEXTS_SPAM, $internals['texts_spam']);
-
-                       }
-
-               }
-
-               # We're done and can commit all changes to the database now
-               $this->_commit();
-
-       }
-
-}
-
-?>
\ No newline at end of file
diff --git a/library/spam/b8/storage/storage_dba.php b/library/spam/b8/storage/storage_dba.php
deleted file mode 100644 (file)
index 04618b2..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-<?php
-
-#   Copyright (C) 2006-2010 Tobias Leupold <tobias.leupold@web.de>
-#
-#   This file is part of the b8 package
-#
-#   This program is free software; you can redistribute it and/or modify it
-#   under the terms of the GNU Lesser General Public License as published by
-#   the Free Software Foundation in version 2.1 of the License.
-#
-#   This program is distributed in the hope that it will be useful, but
-#   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-#   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-#   License for more details.
-#
-#   You should have received a copy of the GNU Lesser General Public License
-#   along with this program; if not, write to the Free Software Foundation,
-#   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-
-/**
- * The DBA (Berkeley DB) abstraction layer for communicating with the database.
- * Copyright (C) 2006-2010 Tobias Leupold <tobias.leupold@web.de>
- *
- * @license LGPL
- * @access public
- * @package b8
- * @author Tobias Leupold
- */
-
-class b8_storage_dba extends b8_storage_base
-{
-
-       public $config = array(
-               'database'    => 'wordlist.db',
-               'handler'     => 'db4',
-       );
-
-       public $b8_config = array(
-               'degenerator' => NULL,
-               'today'       => NULL
-       );
-
-       private $_db          = NULL;
-
-       const DATABASE_CONNECTION_FAIL = 'DATABASE_CONNECTION_FAIL';
-
-       /**
-        * Constructs the database layer.
-        *
-        * @access public
-        * @param string $config
-        */
-
-       function __construct($config, $degenerator, $today)
-       {
-
-               # Pass some variables of the main b8 config to this class
-               $this->b8_config['degenerator'] = $degenerator;
-               $this->b8_config['today']       = $today;
-
-               # Validate the config items
-               if(count($config) > 0) {
-                       foreach ($config as $name => $value) {
-                               $this->config[$name] = (string) $value;
-                       }
-               }
-
-       }
-
-       /**
-        * Closes the database connection.
-        *
-        * @access public
-        * @return void
-        */
-
-       function __destruct()
-       {
-               if($this->_db !== NULL) {
-                       dba_close($this->_db);
-                       $this->connected = FALSE;
-               }
-       }
-
-       /**
-        * Connect to the database and do some checks.
-        *
-        * @access public
-        * @return mixed Returns TRUE on a successful database connection, otherwise returns a constant from b8.
-        */
-
-       public function connect()
-       {
-
-               # Have we already connected?
-               if($this->_db !== NULL)
-                       return TRUE;
-
-               # Open the database connection
-               $this->_db = dba_open(dirname(__FILE__) . DIRECTORY_SEPARATOR . ".." . DIRECTORY_SEPARATOR . $this->config['database'], "w", $this->config['handler']);
-
-               if($this->_db === FALSE) {
-                       $this->connected = FALSE;
-                       $this->_db = NULL;
-                       return self::DATABASE_CONNECTION_FAIL;
-               }
-
-               # Everything is okay and connected
-
-               $this->connected = TRUE;
-
-               # Let's see if this is a b8 database and the version is okay
-               return $this->check_database();
-
-       }
-
-       /**
-        * Does the actual interaction with the database when fetching data.
-        *
-        * @access protected
-        * @param array $tokens
-        * @return mixed Returns an array of the returned data in the format array(token => data) or an empty array if there was no data.
-        */
-
-       protected function _get_query($tokens)
-       {
-
-               $data = array();
-
-               foreach ($tokens as $token) {
-
-                       $count = dba_fetch($token, $this->_db);
-
-                       if($count !== FALSE)
-                               $data[$token] = $count;
-
-               }
-
-               return $data;
-
-       }
-
-       /**
-        * Store a token to the database.
-        *
-        * @access protected
-        * @param string $token
-        * @param string $count
-        * @return bool TRUE on success or FALSE on failure
-        */
-
-       protected function _put($token, $count) {
-               return dba_insert($token, $count, $this->_db);
-       }
-
-       /**
-        * Update an existing token.
-        *
-        * @access protected
-        * @param string $token
-        * @param string $count
-        * @return bool TRUE on success or FALSE on failure
-        */
-
-       protected function _update($token, $count)
-       {
-               return dba_replace($token, $count, $this->_db);
-       }
-
-       /**
-        * Remove a token from the database.
-        *
-        * @access protected
-        * @param string $token
-        * @return bool TRUE on success or FALSE on failure
-        */
-
-       protected function _del($token)
-       {
-               return dba_delete($token, $this->_db);
-       }
-
-       /**
-        * Does nothing :-D
-        *
-        * @access protected
-        * @return void
-        */
-
-       protected function _commit()
-       {
-               # We just need this function because the (My)SQL backend(s) need it.
-               return;
-       }
-
-}
-
-?>
\ No newline at end of file
diff --git a/library/spam/b8/storage/storage_frndc.php b/library/spam/b8/storage/storage_frndc.php
deleted file mode 100644 (file)
index e01e652..0000000
+++ /dev/null
@@ -1,313 +0,0 @@
-<?php
-
-#   Copyright (C) 2006-2011 Tobias Leupold <tobias.leupold@web.de>
-#
-#   This file is part of the b8 package
-#
-#   This program is free software; you can redistribute it and/or modify it
-#   under the terms of the GNU Lesser General Public License as published by
-#   the Free Software Foundation in version 2.1 of the License.
-#
-#   This program is distributed in the hope that it will be useful, but
-#   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-#   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-#   License for more details.
-#
-#   You should have received a copy of the GNU Lesser General Public License
-#   along with this program; if not, write to the Free Software Foundation,
-#   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-
-/**
- * The MySQL abstraction layer for communicating with the database.
- * Copyright (C) 2009 Oliver Lillie (aka buggedcom)
- * Copyright (C) 2010-2011 Tobias Leupold <tobias.leupold@web.de>
- *
- * @license LGPL
- * @access public
- * @package b8
- * @author Oliver Lillie (aka buggedcom) (original PHP 5 port and optimizations)
- * @author Tobias Leupold
- */
-
-class b8_storage_frndc extends b8_storage_base
-{
-
-       public $config = array(
-               'database'        => 'b8_wordlist',
-               'table_name'      => 'b8_wordlist',
-               'host'            => 'localhost',
-               'user'            => FALSE,
-               'pass'            => FALSE,
-               'connection'      => NULL
-       );
-
-       public $b8_config = array(
-               'degenerator'     => NULL,
-               'today'           => NULL
-       );
-
-       private $_connection                   = NULL;
-       private $_deletes                      = array();
-       private $_puts                         = array();
-       private $_updates                      = array();
-       private $uid                           = 0;
-
-       const DATABASE_CONNECTION_FAIL         = 'DATABASE_CONNECTION_FAIL';
-       const DATABASE_CONNECTION_ERROR        = 'DATABASE_CONNECTION_ERROR';
-       const DATABASE_CONNECTION_BAD_RESOURCE = 'DATABASE_CONNECTION_BAD_RESOURCE';
-       const DATABASE_SELECT_ERROR            = 'DATABASE_SELECT_ERROR';
-       const DATABASE_TABLE_ACCESS_FAIL       = 'DATABASE_TABLE_ACCESS_FAIL';
-       const DATABASE_WRONG_VERSION           = 'DATABASE_WRONG_VERSION';
-
-       /**
-        * Constructs the database layer.
-        *
-        * @access public
-        * @param string $config
-        */
-
-       function __construct($config, $degenerator, $today)
-       {
-
-               # Pass some variables of the main b8 config to this class
-               $this->b8_config['degenerator'] = $degenerator;
-               $this->b8_config['today']       = $today;
-
-               # Validate the config items
-
-               if(count($config) > 0) {
-
-                       foreach ($config as $name => $value) {
-
-                               switch($name) {
-
-                                       case 'table_name':
-                                       case 'host':
-                                       case 'user':
-                                       case 'pass':
-                                       case 'database':
-                                               $this->config[$name] = (string) $value;
-                                               break;
-
-                                       case 'connection':
-
-                                               if($value !== NULL) {
-
-                                                       if(is_resource($value) === TRUE) {
-                                                               $resource_type = get_resource_type($value);
-                                                               $this->config['connection'] = $resource_type !== 'mysql link' && $resource_type !== 'mysql link persistent' ? FALSE : $value;
-                                                       }
-
-                                                       else
-                                                               $this->config['connection'] = FALSE;
-
-                                               }
-
-                                               break;
-
-                               }
-
-                       }
-
-               }
-
-       }
-
-       /**
-        * Closes the database connection.
-        *
-        * @access public
-        * @return void
-        */
-
-       function __destruct()
-       {
-
-               if ($this->_connection === NULL) {
-                       return;
-               }
-
-               // Commit any changes before closing
-               $this->_commit();
-
-               // Just close the connection if no link-resource was passed and b8 created it's own connection
-               if ($this->config['connection'] === NULL) {
-                       mysql_close($this->_connection);
-               }
-
-               $this->connected = FALSE;
-
-       }
-
-       /**
-        * Connect to the database and do some checks.
-        *
-        * @access public
-        * @return mixed Returns TRUE on a successful database connection, otherwise returns a constant from b8.
-        */
-
-       public function connect()
-       {
-
-               $this->connected = TRUE;
-               return TRUE;
-
-       }
-
-       /**
-        * Does the actual interaction with the database when fetching data.
-        *
-        * @access protected
-        * @param array $tokens
-        * @return mixed Returns an array of the returned data in the format array(token => data) or an empty array if there was no data.
-        */
-
-       protected function _get_query($tokens, $uid)
-       {
-
-               // Construct the query ...
-               if (count($tokens) > 0) {
-
-                       $where = array();
-
-                       foreach ($tokens as $token) {
-                               $token = dbesc($token);
-                               array_push($where, $token);
-                       }
-
-                       $where = 'term IN ("' . implode('", "', $where) . '")';
-               } else {
-                       $token = dbesc($token);
-                       $where = 'term = "' . $token . '"';
-               }
-
-               // ... and fetch the data
-
-               $result = q('SELECT * FROM `spam` WHERE ' . $where . ' AND `uid` = ' . $uid );
-
-
-               $returned_tokens = array();
-               if (dbm::is_result($result)) {
-                       foreach ($result as $rr) {
-                               $returned_tokens[] = $rr['term'];
-                       }
-               }
-               $to_create = array();
-
-               if (count($tokens) > 0) {
-                       foreach($tokens as $token)
-                               if(! in_array($token,$returned_tokens))
-                                       $to_create[] = str_tolower($token); 
-               }
-               if (count($to_create)) {
-                       $sql = '';
-                       foreach ($to_create as $term) {
-                               if (strlen($sql)) {
-                                       $sql .= ',';
-                               }
-                               $sql .= sprintf("(`term`,`datetime`,`uid`) VALUES('%s','%s',%d)",
-                                       dbesc(str_tolower($term)),
-                                       dbesc(datetime_convert()),
-                                       intval($uid)
-                               );
-                       }
-                       q("INSERT INTO `spam` " . $sql);
-               }
-
-               return $result;
-
-       }
-
-       /**
-        * Store a token to the database.
-        *
-        * @access protected
-        * @param string $token
-        * @param string $count
-        * @return void
-        */
-       protected function _put($token, $count, $uid) {
-               $token = dbesc($token);
-               $count = dbesc($count);
-               $uid = dbesc($uid);
-               array_push($this->_puts, '("' . $token . '", "' . $count . '", "' . $uid .'")');
-       }
-
-       /**
-        * Update an existing token.
-        *
-        * @access protected
-        * @param string $token
-        * @param string $count
-        * @return void
-        */
-       protected function _update($token, $count, $uid)
-       {
-               $token = dbesc($token);
-               $count = dbesc($count);
-               $uid = dbesc($uid);
-               array_push($this->_puts, '("' . $token . '", "' . $count . '", "' . $uid .'")');
-       }
-
-       /**
-        * Remove a token from the database.
-        *
-        * @access protected
-        * @param string $token
-        * @return void
-        */
-       protected function _del($token, $uid)
-       {
-               $token = dbesc($token);
-               $uid = dbesc($uid);
-               $this->uid = $uid;
-               array_push($this->_deletes, $token);
-       }
-
-       /**
-        * Commits any modification queries.
-        *
-        * @access protected
-        * @return void
-        */
-       protected function _commit($uid)
-       {
-
-               if(count($this->_deletes) > 0) {
-
-                       $result = q('
-                               DELETE FROM ' . $this->config['table_name'] . '
-                               WHERE token IN ("' . implode('", "', $this->_deletes) . '") AND uid = ' . $this->uid);
-
-                       $this->_deletes = array();
-
-               }
-
-               if(count($this->_puts) > 0) {
-
-                       $result = q('
-                               INSERT INTO ' . $this->config['table_name'] . '(token, count, uid)
-                               VALUES ' . implode(', ', $this->_puts));
-
-                       $this->_puts = array();
-
-               }
-
-               if(count($this->_updates) > 0) {
-
-                       // this still needs work
-                       $result = q("select * from " . $this->config['table_name'] . ' where token = ');
-
-                       
-                       $result = q('
-                               INSERT INTO ' . $this->config['table_name'] . '(token, count, uid)
-                               VALUES ' . implode(', ', $this->_updates) . ', ' . $uid . '
-                               ON DUPLICATE KEY UPDATE ' . $this->config['table_name'] . '.count = VALUES(count);', $this->_connection);
-
-                       $this->_updates = array();
-
-               }
-
-       }
-
-}
diff --git a/library/spam/b8/storage/storage_mysql.php b/library/spam/b8/storage/storage_mysql.php
deleted file mode 100644 (file)
index 0225363..0000000
+++ /dev/null
@@ -1,351 +0,0 @@
-<?php
-
-#   Copyright (C) 2006-2011 Tobias Leupold <tobias.leupold@web.de>
-#
-#   This file is part of the b8 package
-#
-#   This program is free software; you can redistribute it and/or modify it
-#   under the terms of the GNU Lesser General Public License as published by
-#   the Free Software Foundation in version 2.1 of the License.
-#
-#   This program is distributed in the hope that it will be useful, but
-#   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-#   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-#   License for more details.
-#
-#   You should have received a copy of the GNU Lesser General Public License
-#   along with this program; if not, write to the Free Software Foundation,
-#   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-
-/**
- * The MySQL abstraction layer for communicating with the database.
- * Copyright (C) 2009 Oliver Lillie (aka buggedcom)
- * Copyright (C) 2010-2011 Tobias Leupold <tobias.leupold@web.de>
- *
- * @license LGPL
- * @access public
- * @package b8
- * @author Oliver Lillie (aka buggedcom) (original PHP 5 port and optimizations)
- * @author Tobias Leupold
- */
-
-class b8_storage_mysql extends b8_storage_base
-{
-
-       public $config = array(
-               'database'        => 'b8_wordlist',
-               'table_name'      => 'b8_wordlist',
-               'host'            => 'localhost',
-               'user'            => FALSE,
-               'pass'            => FALSE,
-               'connection'      => NULL
-       );
-
-       public $b8_config = array(
-               'degenerator'     => NULL,
-               'today'           => NULL
-       );
-
-       private $_connection                   = NULL;
-       private $_deletes                      = array();
-       private $_puts                         = array();
-       private $_updates                      = array();
-
-       const DATABASE_CONNECTION_FAIL         = 'DATABASE_CONNECTION_FAIL';
-       const DATABASE_CONNECTION_ERROR        = 'DATABASE_CONNECTION_ERROR';
-       const DATABASE_CONNECTION_BAD_RESOURCE = 'DATABASE_CONNECTION_BAD_RESOURCE';
-       const DATABASE_SELECT_ERROR            = 'DATABASE_SELECT_ERROR';
-       const DATABASE_TABLE_ACCESS_FAIL       = 'DATABASE_TABLE_ACCESS_FAIL';
-       const DATABASE_WRONG_VERSION           = 'DATABASE_WRONG_VERSION';
-
-       /**
-        * Constructs the database layer.
-        *
-        * @access public
-        * @param string $config
-        */
-
-       function __construct($config, $degenerator, $today)
-       {
-
-               # Pass some variables of the main b8 config to this class
-               $this->b8_config['degenerator'] = $degenerator;
-               $this->b8_config['today']       = $today;
-
-               # Validate the config items
-
-               if(count($config) > 0) {
-
-                       foreach ($config as $name => $value) {
-
-                               switch($name) {
-
-                                       case 'table_name':
-                                       case 'host':
-                                       case 'user':
-                                       case 'pass':
-                                       case 'database':
-                                               $this->config[$name] = (string) $value;
-                                               break;
-
-                                       case 'connection':
-
-                                               if($value !== NULL) {
-
-                                                       if(is_resource($value) === TRUE) {
-                                                               $resource_type = get_resource_type($value);
-                                                               $this->config['connection'] = $resource_type !== 'mysql link' && $resource_type !== 'mysql link persistent' ? FALSE : $value;
-                                                       }
-
-                                                       else
-                                                               $this->config['connection'] = FALSE;
-
-                                               }
-
-                                               break;
-
-                               }
-
-                       }
-
-               }
-
-       }
-
-       /**
-        * Closes the database connection.
-        *
-        * @access public
-        * @return void
-        */
-
-       function __destruct()
-       {
-
-               if($this->_connection === NULL)
-                       return;
-
-               # Commit any changes before closing
-               $this->_commit();
-
-               # Just close the connection if no link-resource was passed and b8 created it's own connection
-               if($this->config['connection'] === NULL)
-                       mysql_close($this->_connection);
-
-               $this->connected = FALSE;
-
-       }
-
-       /**
-        * Connect to the database and do some checks.
-        *
-        * @access public
-        * @return mixed Returns TRUE on a successful database connection, otherwise returns a constant from b8.
-        */
-
-       public function connect()
-       {
-
-               # Are we already connected?
-               if($this->connected === TRUE)
-                       return TRUE;
-
-               # Are we using an existing passed resource?
-               if($this->config['connection'] === FALSE) {
-                       # ... yes we are, but the connection is not a resource, so return an error
-                       $this->connected = FALSE;
-                       return self::DATABASE_CONNECTION_BAD_RESOURCE;
-               }
-
-               elseif($this->config['connection'] === NULL) {
-
-                       # ... no we aren't so we have to connect.
-
-                       if($this->_connection = mysql_connect($this->config['host'], $this->config['user'], $this->config['pass'])) {
-                               if(mysql_select_db($this->config['database'], $this->_connection) === FALSE) {
-                                       $this->connected = FALSE;
-                                       return self::DATABASE_SELECT_ERROR . ": " . mysql_error();
-                               }
-                       }
-                       else {
-                               $this->connected = FALSE;
-                               return self::DATABASE_CONNECTION_ERROR;
-                       }
-
-               }
-
-               else {
-                       # ... yes we are
-                       $this->_connection = $this->config['connection'];
-               }
-
-               # Just in case ...
-               if($this->_connection === NULL) {
-                       $this->connected = FALSE;
-                       return self::DATABASE_CONNECTION_FAIL;
-               }
-
-               # Check to see if the wordlist table exists
-               if(mysql_query('DESCRIBE ' . $this->config['table_name'], $this->_connection) === FALSE) {
-                       $this->connected = FALSE;
-                       return self::DATABASE_TABLE_ACCESS_FAIL . ": " . mysql_error();
-               }
-
-               # Everything is okay and connected
-               $this->connected = TRUE;
-
-               # Let's see if this is a b8 database and the version is okay
-               return $this->check_database();
-
-       }
-
-       /**
-        * Does the actual interaction with the database when fetching data.
-        *
-        * @access protected
-        * @param array $tokens
-        * @return mixed Returns an array of the returned data in the format array(token => data) or an empty array if there was no data.
-        */
-
-       protected function _get_query($tokens)
-       {
-
-               # Construct the query ...
-
-               if(count($tokens) > 0) {
-
-                       $where = array();
-
-                       foreach ($tokens as $token) {
-                               $token = mysql_real_escape_string($token, $this->_connection);
-                               array_push($where, $token);
-                       }
-
-                       $where = 'token IN ("' . implode('", "', $where) . '")';
-               }
-
-               else {
-                       $token = mysql_real_escape_string($token, $this->_connection);
-                       $where = 'token = "' . $token . '"';
-               }
-
-               # ... and fetch the data
-
-               $result = mysql_query('
-                       SELECT token, count
-                       FROM ' . $this->config['table_name'] . '
-                       WHERE ' . $where . ';
-               ', $this->_connection);
-
-               $data = array();
-
-               while ($row = mysql_fetch_array($result, MYSQL_ASSOC))
-                       $data[$row['token']] = $row['count'];
-
-               mysql_free_result($result);
-
-               return $data;
-
-       }
-
-       /**
-        * Store a token to the database.
-        *
-        * @access protected
-        * @param string $token
-        * @param string $count
-        * @return void
-        */
-
-       protected function _put($token, $count) {
-               $token = mysql_real_escape_string($token, $this->_connection);
-               $count = mysql_real_escape_string($count, $this->_connection);;
-               array_push($this->_puts, '("' . $token . '", "' . $count . '")');
-       }
-
-       /**
-        * Update an existing token.
-        *
-        * @access protected
-        * @param string $token
-        * @param string $count
-        * @return void
-        */
-
-       protected function _update($token, $count)
-       {
-               $token = mysql_real_escape_string($token, $this->_connection);
-               $count = mysql_real_escape_string($count, $this->_connection);
-               array_push($this->_updates, '("' . $token . '", "' . $count . '")');
-       }
-
-       /**
-        * Remove a token from the database.
-        *
-        * @access protected
-        * @param string $token
-        * @return void
-        */
-
-       protected function _del($token)
-       {
-               $token = mysql_real_escape_string($token, $this->_connection);
-               array_push($this->_deletes, $token);
-       }
-
-       /**
-        * Commits any modification queries.
-        *
-        * @access protected
-        * @return void
-        */
-
-       protected function _commit()
-       {
-
-               if(count($this->_deletes) > 0) {
-
-                       $result = mysql_query('
-                               DELETE FROM ' . $this->config['table_name'] . '
-                               WHERE token IN ("' . implode('", "', $this->_deletes) . '");
-                       ', $this->_connection);
-
-                       if(is_resource($result) === TRUE)
-                               mysql_free_result($result);
-
-                       $this->_deletes = array();
-
-               }
-
-               if(count($this->_puts) > 0) {
-
-                       $result = mysql_query('
-                               INSERT INTO ' . $this->config['table_name'] . '(token, count)
-                               VALUES ' . implode(', ', $this->_puts) . ';', $this->_connection);
-
-                       if(is_resource($result) === TRUE)
-                               mysql_free_result($result);
-
-                       $this->_puts = array();
-
-               }
-
-               if(count($this->_updates) > 0) {
-
-                       $result = mysql_query('
-                               INSERT INTO ' . $this->config['table_name'] . '(token, count)
-                               VALUES ' . implode(', ', $this->_updates) . '
-                               ON DUPLICATE KEY UPDATE ' . $this->config['table_name'] . '.count = VALUES(count);', $this->_connection);
-
-                       if(is_resource($result) === TRUE)
-                               mysql_free_result($result);
-
-                       $this->_updates = array();
-
-               }
-
-       }
-
-}
-
-?>
\ No newline at end of file
diff --git a/library/spam/doc/COPYING b/library/spam/doc/COPYING
deleted file mode 100644 (file)
index 8add30a..0000000
+++ /dev/null
@@ -1,504 +0,0 @@
-                 GNU LESSER GENERAL PUBLIC LICENSE
-                      Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
-     51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL.  It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
-                           Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
-  This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it.  You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
-  When we speak of free software, we are referring to freedom of use,
-not price.  Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
-  To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights.  These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  To protect each distributor, we want to make it very clear that
-there is no warranty for the free library.  Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-\f
-  Finally, software patents pose a constant threat to the existence of
-any free program.  We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder.  Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
-  Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License.  This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License.  We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
-  When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library.  The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom.  The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
-  We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License.  It also provides other free software developers Less
-of an advantage over competing non-free programs.  These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries.  However, the Lesser license provides advantages in certain
-special circumstances.
-
-  For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard.  To achieve this, non-free programs must be
-allowed to use the library.  A more frequent case is that a free
-library does the same job as widely used non-free libraries.  In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
-  In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software.  For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
-  Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-\f
-                 GNU LESSER GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
-  A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The "Library", below, refers to any such software library or work
-which has been distributed under these terms.  A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term "modification".)
-
-  "Source code" for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-  
-  1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-\f
-  2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-\f
-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library".  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library".  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-\f
-  6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable "work that
-    uses the Library", as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Use a suitable shared library mechanism for linking with the
-    Library.  A suitable mechanism is one that (1) uses at run time a
-    copy of the library already present on the user's computer system,
-    rather than copying library functions into the executable, and (2)
-    will operate properly with a modified version of the library, if
-    the user installs one, as long as the modified version is
-    interface-compatible with the version that the work was made with.
-
-    c) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    d) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    e) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-\f
-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-  9. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-\f
-  11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-\f
-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-                           NO WARRANTY
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
-                    END OF TERMS AND CONDITIONS
-\f
-           How to Apply These Terms to Your New Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  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 library's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-  <signature of Ty Coon>, 1 April 1990
-  Ty Coon, President of Vice
-
-That's all there is to it!
-
-
diff --git a/library/spam/doc/ChangeLog b/library/spam/doc/ChangeLog
deleted file mode 100644 (file)
index 78a4fc7..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-2010-12-30 Tobias Leupold <tobias.leupold@web.de>
-
-       * Release: Version 0.5.1
-
-       * Bigger changes:
-               - Fixed some issues with the scope of variables leading to problems when multiple instances of b8 are created. Thanks to Mike Creuzer for the bug report :-)
-               - Centralized the loading of class definition files in the b8 constructor and created a function to handle the inclusion.
-
-       * b8.php: Return a lexer error code instead of a rating if the lexer failed. The lexer never returned FALSE but b8 checked only for this value to validate the lexer didn't fail. Thanks to Matt Friedman for the bug report :-)
-
-       * lexer/lexer_default.php: A bit of code cleanup: less useless nesting.
-
-       * doc/readme.*: Updated the documentation, added a FAQ.
-
-2010-06-27 Tobias Leupold <tobias.leupold@web.de>
-
-       * Release: Version 0.5-r1
-
-       * doc/readme.*: Updated the documentation; forgot the newly introduced b8::HAM and b8::SPAM variables. Added some additional information about the storage model.
-
-2010-06-02 Tobias Leupold <tobias.leupold@web.de>
-
-       * Release: Version 0.5
-
-       * 100.000 Changes (new major release!), at a glance:
-               - No PHP 4 compatibility anymore. Much cleaner code base with less hacks.
-               - Completely reworked storage model. The SQL performance increased dramatically, the Berkeley DB performance remains as fast as it always has been.
-               - Better lexer which can also handle non-latin1 texts in a nice way, so that e. g. Cyrillic or Chinese texts can be classified more performant.
-               - No config files anymore, multiple instances of b8 can be now created in the same script with different configuration, databases and no problems.
-               - No spooky administration interface anymore that needs an SQL database, even if Berkeley DB is used (anybody who actually used this?! I never did ;-).
-               - No "install" scripts and routines and a less end-user compatible documentation. Anybody integrating b8 in his homepage won't be an end-user, will he?
-
-2009-02-03 Oliver Lillie (aka buggedcom)
-
-       * Revision: 221 (the original PHP 5 port)
-
-       * Rewrote Tobias' original class for optimisation and PHP 5 functionality.
-
-       * Improved database mysql query useage by over ~820%
-
-       * Class is faster, ~20%.
-
-       * Slight increase in memory usage, but it's small and given the advantages of the speed increase and query reduction it's worth it.
-
-       * Removed install code from mysql class and added a sql file. Anyone who wants to use this is generally going to be more advanced anyway and see the sql to install.
-
-2009-02-03 Tobias Leupold <tobias.leupold@web.de>
-
-       * Release: Version 0.4.4 -- changed the license type from GPL to LGPL
-
-2008-06-27 Tobias Leupold <tobias.leupold@web.de>
-
-       * Release: Version 0.4.3 -- no bugs found ... so let's make a release with only small changes ;-)
-
-       * b8.php: Removed debugging messages that were commented out anyway
-
-       * storage/storage_mysql.php: Made it possible to pass both a MySQL-link resource and a table name to b8. This makes b8 useable in the Redaxo CMS (and probably others)
-
-       * doc/readme.htm: Updated documentation accordingly
-
-2008-02-17 Tobias Leupold <tobias.leupold@web.de>
-
-       * Release: Version 0.4.2
-
-       * interface/backup.php: the bayes*dbversion tag is now written to a database emptied by drop(), so that it will be useable without an error message even if no backup is recovered afterwards.
-
-       * doc/readme.htm: added a security note to the configuration section (htaccess should be used to avoid everybody to be able to see the configuration)
-
-2007-09-17 Tobias Leupold <tobias.leupold@web.de>
-
-       * Release: Version 0.4.1
-
-       * storage/storage_mysql.php: fixed b8 crashing when getting passed a persistent MySQL resource link. Thanks to Paul Chapman for the bug report :-)
-
-2007-06-08 Tobias Leupold <tobias.leupold@web.de>
-
-       * Release: Version 0.4
-
-       * Let's go the whole hog. b8's class is now "b8" and no more "bayes", and all internal variables have now according names.
-
-       * Reworked the whole (surprisingly crappy) implementation of b8. No more global() calls, everything happens inside the classes now. Made that whole stuff really object oriented (as good as possible with PHP's poor OOP model ;-).
-
-       * No more PHP code in the configuration files.
-
-       * Created an extra lexer class. This is now also configurable.
-
-       * Storage classes now can create their own databases when this is requested by the configuration.
-
-       * MySQL calls are no random shots anymore: either, a MySQL-link resource is passed to b8 on startup which will be used for the queries, or the class sets up it's own link. Same for SQLite.
-
-       * The interface now uses a separate storage backend capable of SQL. In this way, we _really_ can query the database for e. g. an ordered list of tokens. After doing what we wanted with this work database, the b8 database can be synced with it.
-
-       * Added a lot of verbose error handling.
-
-       * Fixed a dumb error: all tokens from a text were used for the spamminess calculation, because two for() loops both used $i as their counter. D'oh!!! Now, the filter's performance is way better.
-
-       * Catched on the way how that whole math stuff works a little more ;-) Now, the calculation of the single probabilities proposed by Mr. Robinson does a little more the stuff it was intended to do, because ...
-
-       * Made some calculation constants parameters: the number of tokens to use, the default rating for unknown tokens and Gary Robinson's s constant.
-
-       * Introduced an optional minimum deviation that a token's rating must have to be considered in the spamminess calculation.
-
-       * The default extreme ratings for tokens only in ham or spam are now optional. One can also choose to calculate all ratings by Mr. Robinson's method.
-
-       * Noticed that text primary keys are not case sensitive by default in MySQL, which has a noticeable impact on the filter's performance. Informed the MySQL users about that.
-
-       * The whole code sucks much less ;-) b8 should be way more user friendly now.
-
-       * Re-wrote the whole documentation.
-
-       * Fixed the ChangeLog :-)
-
-2007-02-08 Tobias Leupold <tobias.leupold@web.de>
-
-       * Release: Version 0.3.3 again ;-)
-
-       * bayes-php is now b8. See http://www.nasauber.de/blog/text.php?text=58 for details :-) Thanks to Tobias Lang (http://langt.net/) for this cool new name!
-
-2007-01-05 Tobias Leupold <tobias.leupold@web.de>
-
-       * Release: Version 0.3.3
-
-       * Renamed the internal BerkeleyDB handle from "$db" to the less general name "$bayes_php_db" due to an collision with phpwcms's (http://www.phpwcms.de/) global $db variable and potentially other php programs.
-
-       * Commented out Laurent Goussard's SQLite storage class by default, as it's try { } catch { } calls break PHP 4
-
-2006-09-03 Tobias Leupold <tobias.leupold@web.de>
-
-       * Release: Version 0.3.2
-
-       * Laurent Goussard (loranger@free.fr) contributed an SQLite storage class(which needs PHP 5).
-
-       * I finally added my eMail address to the sources ;-)
-
-2006-07-24 Tobias Leupold <tobias.leupold@web.de>
-
-       * Release: Version 0.3.1
-
-       * Fixed a problem in the unlearn() function: If a text was unlearned that wasn't learned before (accidentaly), it could happen that the count parameter for this text was smaller than 0, breaking the spamminess calulation
-
-2006-07-02 Tobias Leupold <tobias.leupold@web.de>
-
-       * Release: Version 0.3
-
-       * Improved the get_tokens() function; the filter should now be a lot more performant, especially with short texts
-
-       * Added the "lastseen" parameter for each token to make the database maintainable (outdated tokens can be deleted)
-
-       * Added a real database maintainance interface
-
-2006-06-12 Tobias Leupold <tobias.leupold@web.de>
-
-       * Release: Version 0.2.1
-
-       * Fixed a problem in get_tokens() (if it was called more than once, tokens were counted more often than they appeared in the text)
-
-       * Slightly enhanced the default index.php interface: after learning a text as Ham or Spam, the rating before and after it is displayed to inform the user about it
-
-2006-05-21 Tobias Leupold <tobias.leupold@web.de>
-
-       * Release: Version 0.2
-
-       * Comments now in English (to pretend international success of bayes-php ;-)
-
-       * Recommendations of Paul Graham's article "Better Bayesian Filtering" ( http://www.paulgraham.com/better.html ) are now considered: Tokens that only appear in Ham or Spam and not in the other category are rated with 0.9998 or 0.0002 if they were less than 10 times in Ham or Spam and with 0.9999 or 0.0001 if they appeared more that 10 times. This should allow the filter to differentiate spam texts more sharp from ham texts. Also, token "degeneration" as described in the article is performed for unknown tokens to estimate their spamminess.
-
-       * The database connect is now swapped in a separate configuration file, so only this file has to be preserved if bayes-php is updated and only this file has to be changed to configure the script.
-
-2006-03-29 Tobias Leupold <tobias.leupold@web.de>
-
-       * Release: Version 0.1.1
-
-       * get_tokens() beachtet jetzt auch HTML-Tags und Wörter mit Akzenten und Apostrophen
-
-       * Verschiedene Kleinigkeiten "sauber" gemacht :-)
-
-2006-03-05 Tobias Leupold <tobias.leupold@web.de>
-
-       * Added 2007-06-08: Initial release (Version 0.1)
diff --git a/library/spam/doc/readme.htm b/library/spam/doc/readme.htm
deleted file mode 100644 (file)
index 727d5ae..0000000
+++ /dev/null
@@ -1,707 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="generator" content="Docutils 0.7: http://docutils.sourceforge.net/" />
-<title>b8: readme</title>
-<meta name="author" content="Tobias Leupold" />
-<meta name="date" content="2010-12-23" />
-<style type="text/css">
-
-/*
-:Author: David Goodger (goodger@python.org)
-:Id: $Id: html4css1.css 6253 2010-03-02 00:24:53Z milde $
-:Copyright: This stylesheet has been placed in the public domain.
-
-Default cascading style sheet for the HTML output of Docutils.
-
-See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
-customize this style sheet.
-*/
-
-/* used to remove borders from tables and images */
-.borderless, table.borderless td, table.borderless th {
-  border: 0 }
-
-table.borderless td, table.borderless th {
-  /* Override padding for "table.docutils td" with "! important".
-     The right padding separates the table cells. */
-  padding: 0 0.5em 0 0 ! important }
-
-.first {
-  /* Override more specific margin styles with "! important". */
-  margin-top: 0 ! important }
-
-.last, .with-subtitle {
-  margin-bottom: 0 ! important }
-
-.hidden {
-  display: none }
-
-a.toc-backref {
-  text-decoration: none ;
-  color: black }
-
-blockquote.epigraph {
-  margin: 2em 5em ; }
-
-dl.docutils dd {
-  margin-bottom: 0.5em }
-
-/* Uncomment (and remove this text!) to get bold-faced definition list terms
-dl.docutils dt {
-  font-weight: bold }
-*/
-
-div.abstract {
-  margin: 2em 5em }
-
-div.abstract p.topic-title {
-  font-weight: bold ;
-  text-align: center }
-
-div.admonition, div.attention, div.caution, div.danger, div.error,
-div.hint, div.important, div.note, div.tip, div.warning {
-  margin: 2em ;
-  border: medium outset ;
-  padding: 1em }
-
-div.admonition p.admonition-title, div.hint p.admonition-title,
-div.important p.admonition-title, div.note p.admonition-title,
-div.tip p.admonition-title {
-  font-weight: bold ;
-  font-family: sans-serif }
-
-div.attention p.admonition-title, div.caution p.admonition-title,
-div.danger p.admonition-title, div.error p.admonition-title,
-div.warning p.admonition-title {
-  color: red ;
-  font-weight: bold ;
-  font-family: sans-serif }
-
-/* Uncomment (and remove this text!) to get reduced vertical space in
-   compound paragraphs.
-div.compound .compound-first, div.compound .compound-middle {
-  margin-bottom: 0.5em }
-
-div.compound .compound-last, div.compound .compound-middle {
-  margin-top: 0.5em }
-*/
-
-div.dedication {
-  margin: 2em 5em ;
-  text-align: center ;
-  font-style: italic }
-
-div.dedication p.topic-title {
-  font-weight: bold ;
-  font-style: normal }
-
-div.figure {
-  margin-left: 2em ;
-  margin-right: 2em }
-
-div.footer, div.header {
-  clear: both;
-  font-size: smaller }
-
-div.line-block {
-  display: block ;
-  margin-top: 1em ;
-  margin-bottom: 1em }
-
-div.line-block div.line-block {
-  margin-top: 0 ;
-  margin-bottom: 0 ;
-  margin-left: 1.5em }
-
-div.sidebar {
-  margin: 0 0 0.5em 1em ;
-  border: medium outset ;
-  padding: 1em ;
-  background-color: #ffffee ;
-  width: 40% ;
-  float: right ;
-  clear: right }
-
-div.sidebar p.rubric {
-  font-family: sans-serif ;
-  font-size: medium }
-
-div.system-messages {
-  margin: 5em }
-
-div.system-messages h1 {
-  color: red }
-
-div.system-message {
-  border: medium outset ;
-  padding: 1em }
-
-div.system-message p.system-message-title {
-  color: red ;
-  font-weight: bold }
-
-div.topic {
-  margin: 2em }
-
-h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
-h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
-  margin-top: 0.4em }
-
-h1.title {
-  text-align: center }
-
-h2.subtitle {
-  text-align: center }
-
-hr.docutils {
-  width: 75% }
-
-img.align-left, .figure.align-left, object.align-left {
-  clear: left ;
-  float: left ;
-  margin-right: 1em }
-
-img.align-right, .figure.align-right, object.align-right {
-  clear: right ;
-  float: right ;
-  margin-left: 1em }
-
-img.align-center, .figure.align-center, object.align-center {
-  display: block;
-  margin-left: auto;
-  margin-right: auto;
-}
-
-.align-left {
-  text-align: left }
-
-.align-center {
-  clear: both ;
-  text-align: center }
-
-.align-right {
-  text-align: right }
-
-/* reset inner alignment in figures */
-div.align-right {
-  text-align: left }
-
-/* div.align-center * { */
-/*   text-align: left } */
-
-ol.simple, ul.simple {
-  margin-bottom: 1em }
-
-ol.arabic {
-  list-style: decimal }
-
-ol.loweralpha {
-  list-style: lower-alpha }
-
-ol.upperalpha {
-  list-style: upper-alpha }
-
-ol.lowerroman {
-  list-style: lower-roman }
-
-ol.upperroman {
-  list-style: upper-roman }
-
-p.attribution {
-  text-align: right ;
-  margin-left: 50% }
-
-p.caption {
-  font-style: italic }
-
-p.credits {
-  font-style: italic ;
-  font-size: smaller }
-
-p.label {
-  white-space: nowrap }
-
-p.rubric {
-  font-weight: bold ;
-  font-size: larger ;
-  color: maroon ;
-  text-align: center }
-
-p.sidebar-title {
-  font-family: sans-serif ;
-  font-weight: bold ;
-  font-size: larger }
-
-p.sidebar-subtitle {
-  font-family: sans-serif ;
-  font-weight: bold }
-
-p.topic-title {
-  font-weight: bold }
-
-pre.address {
-  margin-bottom: 0 ;
-  margin-top: 0 ;
-  font: inherit }
-
-pre.literal-block, pre.doctest-block {
-  margin-left: 2em ;
-  margin-right: 2em }
-
-span.classifier {
-  font-family: sans-serif ;
-  font-style: oblique }
-
-span.classifier-delimiter {
-  font-family: sans-serif ;
-  font-weight: bold }
-
-span.interpreted {
-  font-family: sans-serif }
-
-span.option {
-  white-space: nowrap }
-
-span.pre {
-  white-space: pre }
-
-span.problematic {
-  color: red }
-
-span.section-subtitle {
-  /* font-size relative to parent (h1..h6 element) */
-  font-size: 80% }
-
-table.citation {
-  border-left: solid 1px gray;
-  margin-left: 1px }
-
-table.docinfo {
-  margin: 2em 4em }
-
-table.docutils {
-  margin-top: 0.5em ;
-  margin-bottom: 0.5em }
-
-table.footnote {
-  border-left: solid 1px black;
-  margin-left: 1px }
-
-table.docutils td, table.docutils th,
-table.docinfo td, table.docinfo th {
-  padding-left: 0.5em ;
-  padding-right: 0.5em ;
-  vertical-align: top }
-
-table.docutils th.field-name, table.docinfo th.docinfo-name {
-  font-weight: bold ;
-  text-align: left ;
-  white-space: nowrap ;
-  padding-left: 0 }
-
-h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
-h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
-  font-size: 100% }
-
-ul.auto-toc {
-  list-style-type: none }
-
-</style>
-</head>
-<body>
-<div class="document" id="b8-readme">
-<h1 class="title">b8: readme</h1>
-<table class="docinfo" frame="void" rules="none">
-<col class="docinfo-name" />
-<col class="docinfo-content" />
-<tbody valign="top">
-<tr><th class="docinfo-name">Author:</th>
-<td>Tobias Leupold</td></tr>
-<tr class="field"><th class="docinfo-name">Homepage:</th><td class="field-body"><a class="reference external" href="http://nasauber.de/">http://nasauber.de/</a></td>
-</tr>
-<tr><th class="docinfo-name">Contact:</th>
-<td><a class="first last reference external" href="mailto:tobias.leupold&#64;web.de">tobias.leupold&#64;web.de</a></td></tr>
-<tr><th class="docinfo-name">Date:</th>
-<td>2010-12-23</td></tr>
-</tbody>
-</table>
-<div class="contents topic" id="table-of-contents">
-<p class="topic-title first">Table of Contents</p>
-<ul class="auto-toc simple">
-<li><a class="reference internal" href="#description-of-b8" id="id18">1&nbsp;&nbsp;&nbsp;Description of b8</a><ul class="auto-toc">
-<li><a class="reference internal" href="#what-is-b8" id="id19">1.1&nbsp;&nbsp;&nbsp;What is b8?</a></li>
-<li><a class="reference internal" href="#how-does-it-work" id="id20">1.2&nbsp;&nbsp;&nbsp;How does it work?</a></li>
-<li><a class="reference internal" href="#what-do-i-need-for-it" id="id21">1.3&nbsp;&nbsp;&nbsp;What do I need for it?</a></li>
-<li><a class="reference internal" href="#what-s-different" id="id22">1.4&nbsp;&nbsp;&nbsp;What's different?</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#update-from-prior-versions" id="id23">2&nbsp;&nbsp;&nbsp;Update from prior versions</a><ul class="auto-toc">
-<li><a class="reference internal" href="#update-from-bayes-php-version-0-2-1-or-earlier" id="id24">2.1&nbsp;&nbsp;&nbsp;Update from bayes-php version 0.2.1 or earlier</a></li>
-<li><a class="reference internal" href="#update-from-bayes-php-version-0-3-or-later" id="id25">2.2&nbsp;&nbsp;&nbsp;Update from bayes-php version 0.3 or later</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#installation" id="id26">3&nbsp;&nbsp;&nbsp;Installation</a></li>
-<li><a class="reference internal" href="#configuration" id="id27">4&nbsp;&nbsp;&nbsp;Configuration</a><ul class="auto-toc">
-<li><a class="reference internal" href="#b8-s-base-configuration" id="id28">4.1&nbsp;&nbsp;&nbsp;b8's base configuration</a></li>
-<li><a class="reference internal" href="#configuration-of-the-storage-backend" id="id29">4.2&nbsp;&nbsp;&nbsp;Configuration of the storage backend</a><ul class="auto-toc">
-<li><a class="reference internal" href="#settings-for-the-berkeley-db-dba-backend" id="id30">4.2.1&nbsp;&nbsp;&nbsp;Settings for the Berkeley DB (DBA) backend</a></li>
-<li><a class="reference internal" href="#settings-for-the-mysql-backend" id="id31">4.2.2&nbsp;&nbsp;&nbsp;Settings for the MySQL backend</a></li>
-</ul>
-</li>
-</ul>
-</li>
-<li><a class="reference internal" href="#using-b8" id="id32">5&nbsp;&nbsp;&nbsp;Using b8</a><ul class="auto-toc">
-<li><a class="reference internal" href="#setting-up-a-new-database" id="id33">5.1&nbsp;&nbsp;&nbsp;Setting up a new database</a><ul class="auto-toc">
-<li><a class="reference internal" href="#setting-up-a-new-berkeley-db" id="id34">5.1.1&nbsp;&nbsp;&nbsp;Setting up a new Berkeley DB</a></li>
-<li><a class="reference internal" href="#setting-up-a-new-mysql-table" id="id35">5.1.2&nbsp;&nbsp;&nbsp;Setting up a new MySQL table</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#using-b8-in-your-scripts" id="id36">5.2&nbsp;&nbsp;&nbsp;Using b8 in your scripts</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#tips-on-operation" id="id37">6&nbsp;&nbsp;&nbsp;Tips on operation</a></li>
-<li><a class="reference internal" href="#closing" id="id38">7&nbsp;&nbsp;&nbsp;Closing</a></li>
-<li><a class="reference internal" href="#references" id="id39">8&nbsp;&nbsp;&nbsp;References</a></li>
-<li><a class="reference internal" href="#appendix" id="id40">9&nbsp;&nbsp;&nbsp;Appendix</a><ul class="auto-toc">
-<li><a class="reference internal" href="#faq" id="id41">9.1&nbsp;&nbsp;&nbsp;FAQ</a><ul class="auto-toc">
-<li><a class="reference internal" href="#what-about-more-than-two-categories" id="id42">9.1.1&nbsp;&nbsp;&nbsp;What about more than two categories?</a></li>
-<li><a class="reference internal" href="#what-about-a-list-with-words-to-ignore" id="id43">9.1.2&nbsp;&nbsp;&nbsp;What about a list with words to ignore?</a></li>
-<li><a class="reference internal" href="#why-is-it-called-b8" id="id44">9.1.3&nbsp;&nbsp;&nbsp;Why is it called &quot;b8&quot;?</a></li>
-</ul>
-</li>
-<li><a class="reference internal" href="#about-the-database" id="id45">9.2&nbsp;&nbsp;&nbsp;About the database</a><ul class="auto-toc">
-<li><a class="reference internal" href="#the-database-layout" id="id46">9.2.1&nbsp;&nbsp;&nbsp;The database layout</a></li>
-<li><a class="reference internal" href="#the-lastseen-parameter" id="id47">9.2.2&nbsp;&nbsp;&nbsp;The &quot;lastseen&quot; parameter</a></li>
-</ul>
-</li>
-</ul>
-</li>
-</ul>
-</div>
-<div class="section" id="description-of-b8">
-<h1><a class="toc-backref" href="#id18">1&nbsp;&nbsp;&nbsp;Description of b8</a></h1>
-<div class="section" id="what-is-b8">
-<h2><a class="toc-backref" href="#id19">1.1&nbsp;&nbsp;&nbsp;What is b8?</a></h2>
-<p>b8 is a spam filter implemented in <a class="reference external" href="http://www.php.net/">PHP</a>. It is intended to keep your weblog or guestbook spam-free. The filter can be used anywhere in your PHP code and tells you whether a text is spam or not, using statistical text analysis. See <a class="reference internal" href="#how-does-it-work">How does it work?</a> for details about this. To be able to do this, b8 first has to learn some spam and some ham example texts to decide what's good and what's not. If it makes mistakes classifying unknown texts, they can be corrected and b8 learns from the corrections, getting better with each learned text.</p>
-<p>At the moment of this writing, b8 has classified 14411 guestbook entries and weblog comments on my homepage since december 2006. 131 were ham. 39 spam texts (0.27 %) have been rated as ham (false negatives), with not even one false positive (ham message classified as spam). This results in a sensitivity of 99.73 % (the probability that a spam text will actually be rated as spam) and a specifity of 100 % (the probability that a ham text will actually be rated as ham) for me. I hope, you'll get the same good results :-)</p>
-<p>Basically, b8 is a statistical (&quot;Bayesian&quot;<a class="footnote-reference" href="#id2" id="id1">[1]</a>) spam filter like <a class="reference external" href="http://bogofilter.sourceforge.net/">Bogofilter</a> or <a class="reference external" href="http://spambayes.sourceforge.net/">SpamBayes</a>, but it is not intended to classify e-mails. When I started to write b8, I didn't find a good PHP spam filter (or any spam filter that wasn't just some example code how one <em>could</em> implement a Bayesian spam filter in PHP) that was intended to filter weblog or guestbook entries. That's why I had to write my own ;-) <br />
-Caused by it's purpose, the way b8 works is slightly different from most of the Bayesian email spam filters out there. See <a class="reference internal" href="#what-s-different">What's different?</a> if you're interested in the details.</p>
-<table class="docutils footnote" frame="void" id="id2" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>A mathematician told me that the math in b8 actually does not use Bayes' theorem but some derived algorithms that are just related to it. So … let's simply believe that and stop claiming b8 was a <em>Bayesian</em> spam filter ;-)</td></tr>
-</tbody>
-</table>
-</div>
-<div class="section" id="how-does-it-work">
-<h2><a class="toc-backref" href="#id20">1.2&nbsp;&nbsp;&nbsp;How does it work?</a></h2>
-<p>b8  basically uses the math and technique described in Paul Graham's article &quot;A Plan For Spam&quot; <a class="footnote-reference" href="#planforspam" id="id3">[2]</a> to distinguish ham and spam. The improvements proposed in Graham's article &quot;Better Bayesian Filtering&quot; <a class="footnote-reference" href="#betterbayesian" id="id4">[3]</a> and Gary Robinson's article &quot;Spam Detection&quot; <a class="footnote-reference" href="#spamdetection" id="id5">[4]</a> have also been considered. See also the article &quot;A Statistical Approach to the Spam Problem&quot; <a class="footnote-reference" href="#statisticalapproach" id="id6">[5]</a>.</p>
-<p>b8 cuts the text to classify to pieces, extracting stuff like e-mail addresses, links and HTML tags. For each such token, it calculates a single probability for a text containing it being spam, based on what the filter has learned so far. When the token was not seen before, b8 tries to find similar ones using the &quot;degeneration&quot; described in <a class="footnote-reference" href="#betterbayesian" id="id7">[3]</a> and uses the most relevant value found. If really nothing is found, b8 assumes a default rating for this token for the further calculations. <br />
-Then, b8 takes the most relevant values (which have a rating far from 0.5, which would mean we don't know what it is) and calculates the probability that the whole text is spam by the inverse chi-square function described in <a class="footnote-reference" href="#spamdetection" id="id8">[4]</a>.
-There are some parameters that can be set which influence the filter's behaviour (see below).</p>
-<p>In short words: you give b8 a text and it returns a value between 0 and 1, saying it's ham when it's near 0 and saying it's spam when it's near 1.</p>
-</div>
-<div class="section" id="what-do-i-need-for-it">
-<h2><a class="toc-backref" href="#id21">1.3&nbsp;&nbsp;&nbsp;What do I need for it?</a></h2>
-<p>Not much! You just need PHP 5 on the server where b8 will be used (b8 version 0.5 finally dropped PHP 4 compatibility – thankfully ;-) and a proper storage possibility for the wordlists. I strongly recommend using <a class="reference external" href="http://www.oracle.com/database/berkeley-db/index.html">Berkeley DB</a>. See below how you can check if you can use it and why you should use it. If the server's PHP wasn't compiled with Berkeley DB support, a <a class="reference external" href="http://mysql.com/">MySQL</a> table can be used alternatively.</p>
-</div>
-<div class="section" id="what-s-different">
-<h2><a class="toc-backref" href="#id22">1.4&nbsp;&nbsp;&nbsp;What's different?</a></h2>
-<p>b8 is designed to classify weblog or guestbook entries, not e-mails. For this reason, it uses a slightly different technique than most of the other statistical spam filters out there use.</p>
-<p>My experience was that spam entries on my weblog or guestbook were often quite short, sometimes just something like &quot;123abc&quot; as text and a link to a suspect homepage. Some spam bots don't even made a difference between e. g. the &quot;name&quot; and &quot;text&quot; fields and posted their text as email address, for example. Considering this, b8 just takes one string to classify, making no difference between &quot;headers&quot; and &quot;text&quot;. <br />
-The other thing is that most statistical spam filters count one token one time, no matter how often it appears in the text (as Graham describes it in <a class="footnote-reference" href="#planforspam" id="id9">[2]</a>). b8 does count how often a token was seen and learns or considers this. Additionally, the number of learned ham and spam texts are saved and used as the calculation base for the single probabilities. Why this? Because a text containing one link (no matter where it points to, just indicated by a &quot;http://&quot; or a &quot;www.&quot;) might not be spam, but a text containing 20 links might be.</p>
-<p>This means that b8 might be good for classifying weblog or guestbook entries (I really think it is ;-) – but very likely, it will work quite poor when being used for something else (like classifying e-mails). But as said above, for this task, there are a lot of very good filters out there to choose from.</p>
-</div>
-</div>
-<div class="section" id="update-from-prior-versions">
-<h1><a class="toc-backref" href="#id23">2&nbsp;&nbsp;&nbsp;Update from prior versions</a></h1>
-<p>If this is a new b8 installation, read on at the <a class="reference internal" href="#installation">Installation</a> section!</p>
-<div class="section" id="update-from-bayes-php-version-0-2-1-or-earlier">
-<h2><a class="toc-backref" href="#id24">2.1&nbsp;&nbsp;&nbsp;Update from bayes-php version 0.2.1 or earlier</a></h2>
-<p>Please first follow the database update instructions of the bayes-php-0.3 release if you update from a version prior to bayes-php-0.3 and then read the following paragraph about updating from a version &lt;0.3.3.</p>
-</div>
-<div class="section" id="update-from-bayes-php-version-0-3-or-later">
-<h2><a class="toc-backref" href="#id25">2.2&nbsp;&nbsp;&nbsp;Update from bayes-php version 0.3 or later</a></h2>
-<dl class="docutils">
-<dt><strong>You use Berkeley DB?</strong></dt>
-<dd>Everything's fine, you can simply continue using your database.</dd>
-<dt><strong>You use MySQL?</strong></dt>
-<dd>The <tt class="docutils literal">CREATE</tt> statement of b8's wordlist has changed. The best is probably to create a dump via your favorite administration tool or script, create the new table and re-insert all data. The layout is still the same: there's one &quot;token&quot; column and one &quot;data&quot; column. Having done that, you can keep using your data.</dd>
-<dt><strong>You use SQLite?</strong></dt>
-<dd>Sorry, at the moment, there's no SQLite backend for b8. But we're working on it :-)</dd>
-</dl>
-<p>The configuration model of b8 has changed.  Please read through the <a class="reference internal" href="#configuration">Configuration</a> section and update your configuration accordingly.</p>
-<p>b8's lexer has been partially re-written. It should now be able to handle all kind of non-latin-1 input, like cyrillic, chinese or japanese texts. Caused by this fact, much more tokens will be recognized when classifying such texts. Therefore, you could get different results in b8's ratings, even if the same database is used and although the math is still the same.</p>
-<p>b8 0.5 introduced two constants that can be used in the <tt class="docutils literal">learn()</tt> and <tt class="docutils literal">unlearn()</tt> functions: <tt class="docutils literal"><span class="pre">b8::HAM</span></tt> and <tt class="docutils literal"><span class="pre">b8::SPAM</span></tt>. The literal values &quot;ham&quot; and &quot;spam&quot; can still be used anyway.</p>
-</div>
-</div>
-<div class="section" id="installation">
-<h1><a class="toc-backref" href="#id26">3&nbsp;&nbsp;&nbsp;Installation</a></h1>
-<p>Installing b8 on your server is quite easy. You just have to provide the needed files. To do this, you could just upload the whole <tt class="docutils literal">b8</tt> subdirectory to the base directory of your homepage. It contains the filter itself and all needed backend classes. The other directories (<tt class="docutils literal">doc</tt>, <tt class="docutils literal">example</tt> and <tt class="docutils literal">install</tt>) are not used by b8.</p>
-<p>That's it ;-)</p>
-</div>
-<div class="section" id="configuration">
-<h1><a class="toc-backref" href="#id27">4&nbsp;&nbsp;&nbsp;Configuration</a></h1>
-<p>The configuration is passed as arrays when instantiating a new b8 object. Two arrays can be passed to b8, one containing b8's base configuration and some settings for the lexer (which should be common for all lexer classes, in case some other lexer than the default one will be written one day) and one for the storage backend. <br />
-You can have a look at <tt class="docutils literal">example/index.php</tt> to see how this can be done. <a class="reference internal" href="#using-b8-in-your-scripts">Using b8 in your scripts</a> also shows example code showing how b8 can be included in a PHP script.</p>
-<p>Not all values have to be set. When some values are missing, the default ones will be used. If you do use the default settings, you don't have to pass them to b8.</p>
-<div class="section" id="b8-s-base-configuration">
-<h2><a class="toc-backref" href="#id28">4.1&nbsp;&nbsp;&nbsp;b8's base configuration</a></h2>
-<p>All these values can be set in the &quot;config_b8&quot; array (the first parameter) passed to b8. The name of the array doesn't matter (of course), it just has to be the first argument.</p>
-<p>These are some basic settings telling b8 which backend classes to use:</p>
-<blockquote>
-<dl class="docutils">
-<dt><strong>storage</strong></dt>
-<dd><p class="first">This defines which storage backend will be used to save b8's wordlist. Currently, two backends are available: <a class="reference external" href="http://www.oracle.com/database/berkeley-db/index.html">Berkeley DB</a> (<tt class="docutils literal">dba</tt>) and <a class="reference external" href="http://mysql.com/">MySQL</a> (<tt class="docutils literal">mysql</tt>). At the moment, b8 does not support <a class="reference external" href="http://sqlite.org/">SQLite</a> (as the previous version did), but it will be (hopefully) re-added in one of the next releases. The default is <tt class="docutils literal">dba</tt> (string).</p>
-<dl class="docutils">
-<dt><em>Berkeley DB</em></dt>
-<dd>This is the preferred storage backend. It was the original backend for the filter and remains the most performant. b8's storage model is optimized for this database, as it is really fast and fits perfectly to what the filter needs to do the job. All content is saved in a single file, you don't need special user rights or a database server. <br />
-If you don't know whether your server's PHP can use a Berkeley DB, simply run the script <tt class="docutils literal">install/setup_berkeleydb.php</tt>. If it shows a Berkeley DB handler, please use this backend.</dd>
-<dt><em>MySQL</em></dt>
-<dd>As some webspace hosters don't allow using a Berkeley DB (but please be sure to check if you can use it!), but most do provide a MySQL server, using a MySQL table for the wordlist is provided as an alternative storage method. As said above, b8 was always intended to use a Berkeley DB. It doesn't use or need SQL to query the database. So, very likely, this will work less performant, produce a lot of unnecessary overhead and waste computing power. But it will do fine anyway!</dd>
-</dl>
-<p class="last">See <a class="reference internal" href="#configuration-of-the-storage-backend">Configuration of the storage backend</a> for the settings of the chosen backend.</p>
-</dd>
-<dt><strong>degenerator</strong></dt>
-<dd>The degenerator class to be used. See <a class="reference internal" href="#how-does-it-work">How does it work?</a> and <a class="footnote-reference" href="#betterbayesian" id="id12">[3]</a> if you're interested in what &quot;degeneration&quot; is. Defaults to <tt class="docutils literal">default</tt> (string). At the moment, only one degenerator exists, so you probably don't want to change this unless you have written your own degenerator.</dd>
-<dt><strong>lexer</strong></dt>
-<dd><p class="first">The lexer class to be used. Defaults to <tt class="docutils literal">default</tt> (string). At the moment, only one lexer exists, so you probably don't want to change this unless you have written your own lexer.</p>
-<p>The behaviour of the lexer can be additionally configured with the following variables:</p>
-<blockquote class="last">
-<dl class="docutils">
-<dt><strong>min_size</strong></dt>
-<dd>The minimal length for a token to be considered when calculating the rating of a text. Defaults to <tt class="docutils literal">3</tt> (integer).</dd>
-<dt><strong>max_size</strong></dt>
-<dd>The maximal length for a token to be considered when calculating the rating of a text. Defaults to <tt class="docutils literal">30</tt> (integer).</dd>
-<dt><strong>allow_numbers</strong></dt>
-<dd>Should pure numbers also be considered? Defaults to <tt class="docutils literal">FALSE</tt> (boolean).</dd>
-</dl>
-</blockquote>
-</dd>
-</dl>
-</blockquote>
-<p>The following settings influence the mathematical internals of b8. If you want to experiment, feel free to play around with them; but be warned: wrong settings of these values will result in poor performance or could even &quot;short-circuit&quot; the filter. <br />
-Leave these values as they are unless you know what you are doing!</p>
-<p>The &quot;Statistical discussion about b8&quot; <a class="footnote-reference" href="#b8statistic" id="id13">[6]</a> shows why the default values are the default ones.</p>
-<blockquote>
-<dl class="docutils">
-<dt><strong>use_relevant</strong></dt>
-<dd>This tells b8 how many tokens should be used when calculating the spamminess of a text. The default setting is <tt class="docutils literal">15</tt> (integer). This seems to be a quite reasonable value. When using to many tokens, the filter will fail on texts filled with useless stuff or with passages from a newspaper, etc. not being very spammish. <br />
-The tokens counted multiple times (see above) are added in addition to this value. They don't replace other ratings.</dd>
-<dt><strong>min_dev</strong></dt>
-<dd>This defines a minimum deviation from 0.5 that a token's rating must have to be considered when calculating the spamminess. Tokens with a rating closer to 0.5 than this value will simply be skipped. <br />
-If you don't want to use this feature, set this to <tt class="docutils literal">0</tt>. Defaults to <tt class="docutils literal">0.2</tt> (float). Read <a class="footnote-reference" href="#b8statistic" id="id14">[6]</a> before increasing this.</dd>
-<dt><strong>rob_x</strong></dt>
-<dd>This is Gary Robinson's <em>x</em> constant (cf. <a class="footnote-reference" href="#spamdetection" id="id15">[4]</a>). A completely unknown token will be rated with the value of <tt class="docutils literal">rob_x</tt>. The default <tt class="docutils literal">0.5</tt> (float) seems to be quite reasonable, as we can't say if a token that also can't be rated by degeneration is good or bad. <br />
-If you receive much more spam than ham or vice versa, you could change this setting accordingly.</dd>
-<dt><strong>rob_s</strong></dt>
-<dd>This is Gary Robinson's <em>s</em> constant. This is essentially the probability that the <em>rob_x</em> value is correct for a completely unknown token. It will also shift the probability of rarely seen tokens towards this value. The default is <tt class="docutils literal">0.3</tt> (float) <br />
-See <a class="footnote-reference" href="#spamdetection" id="id16">[4]</a> for a closer description of the <em>s</em> constant and read <a class="footnote-reference" href="#b8statistic" id="id17">[6]</a> for specific information about this constant in b8's algorithms.</dd>
-</dl>
-</blockquote>
-</div>
-<div class="section" id="configuration-of-the-storage-backend">
-<h2><a class="toc-backref" href="#id29">4.2&nbsp;&nbsp;&nbsp;Configuration of the storage backend</a></h2>
-<p>All the following values can be set in the &quot;config_database&quot; array (the second parameter) passed to b8. The name of the array doesn't matter (of course), it just has to be the second argument.</p>
-<div class="section" id="settings-for-the-berkeley-db-dba-backend">
-<h3><a class="toc-backref" href="#id30">4.2.1&nbsp;&nbsp;&nbsp;Settings for the Berkeley DB (DBA) backend</a></h3>
-<dl class="docutils">
-<dt><strong>database</strong></dt>
-<dd>The filename of the database file, relative to the location of <tt class="docutils literal">b8.php</tt>. Defaults to <tt class="docutils literal">wordlist.db</tt> (string).</dd>
-<dt><strong>handler</strong></dt>
-<dd>The DBA handler to use (cf. <a class="reference external" href="http://php.net/manual/en/dba.requirements.php">the PHP documentation</a> and <a class="reference internal" href="#setting-up-a-new-berkeley-db">Setting up a new Berkeley DB</a>). Defaults to <tt class="docutils literal">db4</tt> (string).</dd>
-</dl>
-</div>
-<div class="section" id="settings-for-the-mysql-backend">
-<h3><a class="toc-backref" href="#id31">4.2.2&nbsp;&nbsp;&nbsp;Settings for the MySQL backend</a></h3>
-<dl class="docutils">
-<dt><strong>database</strong></dt>
-<dd>The database containing b8's wordlist table. Defaults to <tt class="docutils literal">b8_wordlist</tt> (string).</dd>
-<dt><strong>table_name</strong></dt>
-<dd>The table containing b8's wordlist. Defaults to <tt class="docutils literal">b8_wordlist</tt> (string).</dd>
-<dt><strong>host</strong></dt>
-<dd>The host of the MySQL server. Defaults to <tt class="docutils literal">localhost</tt> (string).</dd>
-<dt><strong>user</strong></dt>
-<dd>The user name used to open the database connection. Defaults to <tt class="docutils literal">FALSE</tt> (boolean).</dd>
-<dt><strong>pass</strong></dt>
-<dd>The password required to open the database connection. Defaults to <tt class="docutils literal">FALSE</tt> (boolean).</dd>
-<dt><strong>connection</strong></dt>
-<dd>An existing MySQL link-resource that can be used by b8. Defaults to <tt class="docutils literal">NULL</tt> (NULL).</dd>
-</dl>
-</div>
-</div>
-</div>
-<div class="section" id="using-b8">
-<h1><a class="toc-backref" href="#id32">5&nbsp;&nbsp;&nbsp;Using b8</a></h1>
-<p>Now, that everything is configured, you can start to use b8. A sample script that shows what can be done with the filter exists in <tt class="docutils literal">example/index.php</tt>. The best thing for testing how all this works is to use this script before using b8 in your own scripts.</p>
-<p>Before you can start, you have to setup a database so that b8 can store a wordlist.</p>
-<div class="section" id="setting-up-a-new-database">
-<h2><a class="toc-backref" href="#id33">5.1&nbsp;&nbsp;&nbsp;Setting up a new database</a></h2>
-<div class="section" id="setting-up-a-new-berkeley-db">
-<h3><a class="toc-backref" href="#id34">5.1.1&nbsp;&nbsp;&nbsp;Setting up a new Berkeley DB</a></h3>
-<p>I wrote a script to setup a new Berkeley DB for b8. It is located in <tt class="docutils literal">install/setup_berkeleydb.php</tt>. Just run this script on your server and be sure that the directory containing it has the proper access rights set so that the server's HTTP server user or PHP user can create a new file in it (probably <tt class="docutils literal">0777</tt>). The script is quite self-explaining, just run it.</p>
-<p>Of course, you can also create a Berkeley DB by hand. In this case, you just have to insert three keys:</p>
-<pre class="literal-block">
-bayes*dbversion  =&gt; 2
-bayes*texts.ham  =&gt; 0
-bayes*texts.spam =&gt; 0
-</pre>
-<p>Be sure to set the right DBA handler in the storage backend configuration if it's not <tt class="docutils literal">db4</tt>.</p>
-</div>
-<div class="section" id="setting-up-a-new-mysql-table">
-<h3><a class="toc-backref" href="#id35">5.1.2&nbsp;&nbsp;&nbsp;Setting up a new MySQL table</a></h3>
-<p>The SQL file <tt class="docutils literal">install/setup_mysql.sql</tt> contains both the create statement for the wordlist table of b8 and the <tt class="docutils literal">INSERT</tt> statements for adding the necessary internal variables.</p>
-<p>Simply change the table name according to your needs (or leave it as it is ;-) and run the SQL to setup a b8 wordlist MySQL table.</p>
-</div>
-</div>
-<div class="section" id="using-b8-in-your-scripts">
-<h2><a class="toc-backref" href="#id36">5.2&nbsp;&nbsp;&nbsp;Using b8 in your scripts</a></h2>
-<p>Just have a look at the example script located in <tt class="docutils literal">example/index.php</tt> to see how you can include b8 in your scripts. Essentially, this strips down to:</p>
-<pre class="literal-block">
-# Include the b8 code
-require &quot;{$_SERVER['DOCUMENT_ROOT']}/b8/b8.php&quot;;
-
-# Do some configuration
-
-$config_b8 = array(
-        'some_key' =&gt; 'some_value',
-        'foo' =&gt; 'bar'
-);
-
-$config_database = array(
-        'some_key' =&gt; 'some_value',
-        'foo' =&gt; 'bar'
-);
-
-# Create a new b8 instance
-$b8 = new b8($config_b8, $config_database);
-</pre>
-<p>b8 provides three functions in an object oriented way (called e. g. via <tt class="docutils literal"><span class="pre">$b8-&gt;classify($text)</span></tt>):</p>
-<dl class="docutils">
-<dt><strong>learn($text, $category)</strong></dt>
-<dd>This saves the reference text <tt class="docutils literal">$text</tt> (string) in the category <tt class="docutils literal">$category</tt> (b8 constant). <br />
-b8 0.5 introduced two constants that can be used as <tt class="docutils literal">$category</tt>: <tt class="docutils literal"><span class="pre">b8::HAM</span></tt> and <tt class="docutils literal"><span class="pre">b8::SPAM</span></tt>. To be downward compatible with older versions of b8, the literal values &quot;ham&quot; and &quot;spam&quot; (case-sensitive strings) can still be used here.</dd>
-<dt><strong>unlearn($text, $category)</strong></dt>
-<dd>This function just exists to delete a text from a category in which is has been stored accidentally before. It deletes the reference text <tt class="docutils literal">$text</tt> (string) from the category <tt class="docutils literal">$category</tt> (either the constants <tt class="docutils literal"><span class="pre">b8::HAM</span></tt> or <tt class="docutils literal"><span class="pre">b8::SPAM</span></tt> or the literal case-sensitive strings &quot;ham&quot; or &quot;spam&quot; – cf. above). <br />
-<strong>Don't delete a spam text from ham after saving it in spam or vice versa, as long you don't have stored it accidentally in the wrong category before!</strong> This will not improve performance, quite the opposite: it will actually break the filter after a time, as the counter for saved ham or spam texts will reach 0, although you have ham or spam tokens stored: the filter will try to remove texts from the ham or spam data which have never been stored there, decrease the counter for tokens which are found just skip the non-existing words.</dd>
-<dt><strong>classify($text)</strong></dt>
-<dd>This function takes the text <tt class="docutils literal">$text</tt> (string), calculates it's probability for being spam it and returns a value between 0 and 1 (float). <br />
-A value close to 0 says the text is more likely ham and a value close to 1 says the text is more likely spam. What to do with this value is <em>your</em> business ;-) See also <a class="reference internal" href="#tips-on-operation">Tips on operation</a> below.</dd>
-</dl>
-</div>
-</div>
-<div class="section" id="tips-on-operation">
-<h1><a class="toc-backref" href="#id37">6&nbsp;&nbsp;&nbsp;Tips on operation</a></h1>
-<p>Before b8 can decide whether a text is spam or ham, you have to tell it what you consider as spam or ham. At least one learned spam or one learned ham text is needed to calculate anything. To get good ratings, you need both learned ham and learned spam texts, the more the better. <br />
-What's considered as &quot;ham&quot; or &quot;spam&quot; can be very different, depending on the operation site. On my homepage, practically each and every text posted in English or using cyrillic letters is spam. On an English or Russian homepage, this will be not the case. So I think it's not really meaningful to provide some &quot;spam data&quot; to start. Just train b8 with &quot;your&quot; spam and ham.</p>
-<p>For the practical use, I advise to give the filter all data availible. E. g. name, email address, homepage, IP address und of course the text itself should be stored in a variable (e. g. separated with an <tt class="docutils literal">\n</tt> or just a space or tab after each block) and then be classified. The learning should also be done with all data availible. <br />
-Saving the IP address is probably only meaningful for spam entries, because spammers often use the same IP address multiple times. In principle, you can leave out the IP of ham entries.</p>
-<p>You can use b8 e. g. in a guestbook script and let it classify the text before saving it. Everyone has to decide which rating is necessary to classify a text as &quot;spam&quot;, but a rating of &gt;= 0.8 seems to be reasonable for me. If one expects the spam to be in another language that the ham entries or the spams are very short normally, one could also think about a limit of 0.7. <br />
-The email filters out there mostly use &gt; 0.9 or even &gt; 0.99; but keep in mind that they have way more data to analyze in most of the cases. A guestbook entry may be quite short, especially when it's spam.</p>
-<p>In my opinion, a autolearn function is very handy. I save spam messages with a rating higher than 0.7 but less than 0.9 automatically as spam. I don't do this with ham messages in an automated way to prevent the filter from saving a false negative as ham and then classifying and learning all the spam as ham when I'm on holidays ;-)</p>
-</div>
-<div class="section" id="closing">
-<h1><a class="toc-backref" href="#id38">7&nbsp;&nbsp;&nbsp;Closing</a></h1>
-<p>So … that's it. Thanks for using b8! If you find a bug or have an idea how to make b8 better, let me know. I'm also always looking forward to get e-mails from people using b8 on their homepages :-)</p>
-</div>
-<div class="section" id="references">
-<h1><a class="toc-backref" href="#id39">8&nbsp;&nbsp;&nbsp;References</a></h1>
-<table class="docutils footnote" frame="void" id="planforspam" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label">[2]</td><td><em>(<a class="fn-backref" href="#id3">1</a>, <a class="fn-backref" href="#id9">2</a>)</em> Paul Graham, <em>A Plan For Spam</em> (<a class="reference external" href="http://paulgraham.com/spam.html">http://paulgraham.com/spam.html</a>)</td></tr>
-</tbody>
-</table>
-<table class="docutils footnote" frame="void" id="betterbayesian" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label">[3]</td><td><em>(<a class="fn-backref" href="#id4">1</a>, <a class="fn-backref" href="#id7">2</a>, <a class="fn-backref" href="#id12">3</a>)</em> Paul Graham, <em>Better Bayesian Filtering</em> (<a class="reference external" href="http://paulgraham.com/better.html">http://paulgraham.com/better.html</a>)</td></tr>
-</tbody>
-</table>
-<table class="docutils footnote" frame="void" id="spamdetection" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label">[4]</td><td><em>(<a class="fn-backref" href="#id5">1</a>, <a class="fn-backref" href="#id8">2</a>, <a class="fn-backref" href="#id15">3</a>, <a class="fn-backref" href="#id16">4</a>)</em> Gary Robinson, <em>Spam Detection</em> (<a class="reference external" href="http://radio.weblogs.com/0101454/stories/2002/09/16/spamDetection.html">http://radio.weblogs.com/0101454/stories/2002/09/16/spamDetection.html</a>)</td></tr>
-</tbody>
-</table>
-<table class="docutils footnote" frame="void" id="statisticalapproach" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id6">[5]</a></td><td><em>A Statistical Approach to the Spam Problem</em> (<a class="reference external" href="http://linuxjournal.com/article/6467">http://linuxjournal.com/article/6467</a>)</td></tr>
-</tbody>
-</table>
-<table class="docutils footnote" frame="void" id="b8statistic" rules="none">
-<colgroup><col class="label" /><col /></colgroup>
-<tbody valign="top">
-<tr><td class="label">[6]</td><td><em>(<a class="fn-backref" href="#id13">1</a>, <a class="fn-backref" href="#id14">2</a>, <a class="fn-backref" href="#id17">3</a>)</em> Tobias Leupold, <em>Statistical discussion about b8</em> (<a class="reference external" href="http://nasauber.de/opensource/b8/discussion/">http://nasauber.de/opensource/b8/discussion/</a>)</td></tr>
-</tbody>
-</table>
-</div>
-<div class="section" id="appendix">
-<h1><a class="toc-backref" href="#id40">9&nbsp;&nbsp;&nbsp;Appendix</a></h1>
-<div class="section" id="faq">
-<h2><a class="toc-backref" href="#id41">9.1&nbsp;&nbsp;&nbsp;FAQ</a></h2>
-<div class="section" id="what-about-more-than-two-categories">
-<h3><a class="toc-backref" href="#id42">9.1.1&nbsp;&nbsp;&nbsp;What about more than two categories?</a></h3>
-<p>I wrote b8 with the <a class="reference external" href="http://en.wikipedia.org/wiki/KISS_principle">KISS principle</a> in mind. For the &quot;end-user&quot;, we have a class with almost no setup to do that can do three things: classify a text, learn a text and un-learn a text. Normally, there's no need to un-learn a text, so essentially, there are only two functions we need. <br />
-This simplicity is only possible because b8 only knows two categories (normally &quot;Ham&quot; and &quot;Spam&quot; or some other category pair) and tells you, in one float number between 0 and 1, if a given texts rather fits in the first or the second category. If we would support multiple categories, more work would have to be done and things would become more complicated. One would have to setup the categories, have another database layout (perhaps making it mandatory to have SQL) and one float number would not be sufficient to describe b8's output, so more code would be needed – even outside of b8.</p>
-<p>All the code, the database layout and particularly the math is intended to do exactly one thing: distinguish between two categories. I think it would be a lot of work to change b8 so that it would support more than two categories. Probably, this is possible to do, but don't ask me in which way we would have to change the math to get multiple-category support – I'm a dentist, not a mathematician ;-) <br />
-Apart from this I do believe that most people using b8 don't want or need multiple categories. They just want to know if a text is spam or not, don't they? I do, at least ;-)</p>
-<p>But let's think about the multiple-category thing. How would we calculate a rating for more than two categories? If we had a third one, let's call it &quot;<a class="reference external" href="http://en.wikipedia.org/wiki/Treet">Treet</a>&quot;, how would we calculate a rating? We could calculate three different ratings. One for &quot;Ham&quot;, one for &quot;Spam&quot; and one for &quot;Treet&quot; and choose the highest one to tell the user what category fits best for the text. This could be done by using a small wrapper script using three instances of b8 as-is and three different databases, each containing texts being &quot;Ham&quot;, &quot;Spam&quot;, &quot;Treet&quot; and the respective counterparts. <br />
-But here's the problem: if we have &quot;Ham&quot; and &quot;Spam&quot;, &quot;Spam&quot; is the counterpart of &quot;Ham&quot;. But what's the counterpart of &quot;Spam&quot; if we have more than one additional category? Where do the &quot;Non-Ham&quot;, &quot;Non-Spam&quot; and &quot;Non-Treet&quot; texts come from?</p>
-<p>Another approach, a direct calculation of more than two probabilities (the &quot;Ham&quot; probability is simply 1 minus the &quot;Spam&quot; probability, so we actually get two probabilities with the return value of b8) out of one database would require big changes in b8's structure and math.</p>
-<p>There's a project called <a class="reference external" href="http://xhtml.net/scripts/PHPNaiveBayesianFilter">PHPNaiveBayesianFilter</a> which supports multiple categories by default. The author calls his software &quot;Version 1.0&quot;, but I think this is the very first release, not a stable or mature one. The most recent change of that release dates back to 2003 according to the &quot;changed&quot; date of the files inside the zip archive, so probably, this project is dead or has never been alive and under active development at all. <br />
-Actually, I played around with that code but the results weren't really good, so I decided to write my own spam filter from scratch back in early 2006 ;-)</p>
-<p>All in all, there seems to be no easy way to implement multiple (meaning more than two) categories using b8's current code base and probably, b8 will never support more than two categories. Perhaps, a fork or a complete re-write would  be better than implementing such a feature. Anyway, I don't close my mind to multiple categories in b8. Feel free to tell me how multiple categories could be implementented in b8 or how a multiple-category version using the same code base (sharing a common abstract class?) could be written.</p>
-</div>
-<div class="section" id="what-about-a-list-with-words-to-ignore">
-<h3><a class="toc-backref" href="#id43">9.1.2&nbsp;&nbsp;&nbsp;What about a list with words to ignore?</a></h3>
-<p>Some people suggested to introduce a list with words that b8 will simply ignore. Like &quot;and&quot;, &quot;or&quot;, &quot;the&quot;, and so on. I don't think this is very meaningful.</p>
-<p>First, it would just work for the particular language that has been stored in the list. Speaking of my homepage, most of my spam is English, almost all my ham is German. So I would have to maintain a list with the probably less interesting words for at least two languages. Additionally, I get spam in Chinese, Japanese and Cyrillic writing or something else I can't read as well. What word should be ignored in those texts?  <br />
-Second, why should we ever exclude words? Who tells us those words are <em>actually</em> meaningless? If a word appears both in ham and spam, it's rating will be near 0.5 and so, it won't be used for the final calculation if a appropriate minimum deviation was set. So b8 will exclude it anyway without any blacklist. And think of this: if we excluded a word of which we only <em>think</em> it doesn't mean anything but it actually does appear more often in ham or spam, the results will get even worse.</p>
-<p>So why should we care about things we do not have to care about? ;-)</p>
-</div>
-<div class="section" id="why-is-it-called-b8">
-<h3><a class="toc-backref" href="#id44">9.1.3&nbsp;&nbsp;&nbsp;Why is it called &quot;b8&quot;?</a></h3>
-<p>The initial name for the filter was (damn creative!) &quot;bayes-php&quot;. There were two main reasons for searching another name: 1. &quot;bayes-php&quot; sucks. 2. the <a class="reference external" href="http://php.net/license/3_01.txt">PHP License</a> says the PHP guys do not like when the name of a script written in PHP contains the word &quot;PHP&quot;. Read the <a class="reference external" href="http://www.php.net/license/index.php#faq-lic">License FAQ</a> for a reasonable argumentation about this.</p>
-<p>Luckily, <a class="reference external" href="http://langt.net/">Tobias Lang</a> proposed the new name &quot;b8&quot;. And these are the reasons why I chose this name:</p>
-<ul class="simple">
-<li>&quot;bayes-php&quot; is a &quot;b&quot; followed by 8 letters.</li>
-<li>&quot;b8&quot; is short and handy. Additionally, there was no program with the name &quot;b8&quot; or &quot;bate&quot;</li>
-<li>The English verb &quot;to bate&quot; means &quot;to decrease&quot; – and that's what b8 does: it decreases the number of spam entries in your weblog or guestbook!</li>
-<li>&quot;b8&quot; just sounds way cooler than &quot;bayes-php&quot; ;-)</li>
-</ul>
-</div>
-</div>
-<div class="section" id="about-the-database">
-<h2><a class="toc-backref" href="#id45">9.2&nbsp;&nbsp;&nbsp;About the database</a></h2>
-<div class="section" id="the-database-layout">
-<h3><a class="toc-backref" href="#id46">9.2.1&nbsp;&nbsp;&nbsp;The database layout</a></h3>
-<p>The database layout is quite simple. It's just key:value for everything stored. There are three &quot;internal&quot; variables stored as normal tokens (but all containing a <tt class="docutils literal">*</tt> which is always used as a split character by the lexer, so we can't get collisions):</p>
-<dl class="docutils">
-<dt><strong>bayes*dbversion</strong></dt>
-<dd>This indicates the database's &quot;version&quot;. The first versions of b8 did not set this. Version &quot;2&quot; indicates that we have a database created by a b8 version already storing <a class="reference internal" href="#the-lastseen-parameter">the &quot;lastseen&quot; parameter</a>.</dd>
-<dt><strong>bayes*texts.ham</strong></dt>
-<dd>The number of ham texts learned.</dd>
-<dt><strong>bayes*texts.spam</strong></dt>
-<dd>The number of spam texts learned.</dd>
-</dl>
-<p>Each &quot;normal&quot; token is stored with it's literal name as the key and it's data as the value. The data consists of the count of the token in all ham and spam texts and the date when the token was used the last time, all in one string and separated by spaces. So we have the following scheme:</p>
-<pre class="literal-block">
-&quot;token&quot; =&gt; &quot;count_ham count_spam lastseen&quot;
-</pre>
-</div>
-<div class="section" id="the-lastseen-parameter">
-<h3><a class="toc-backref" href="#id47">9.2.2&nbsp;&nbsp;&nbsp;The &quot;lastseen&quot; parameter</a></h3>
-<p>Somebody looking at the code might be wondering why b8 stores this &quot;lastseen&quot; parameter. This value is not used for any calculation at the moment. Initially, it was intended to keep the database maintainable in a way that &quot;old&quot; data could be removed. When e. g. a token only appeared once in ham or spam and has not been seen for a year, one could simply delete it from the database. <br />
-I actually never used this feature (does anybody?). So probably, some changes will be done to this one day. Perhaps, I find a way to include this data in the spamminess calculation in a meaningful way, or at least for some statistics. One could also make this optional to keep the calculation effort small if this is needed.</p>
-<p>Feel free to send me any suggestions about this!</p>
-</div>
-</div>
-</div>
-</div>
-</body>
-</html>
diff --git a/library/spam/doc/readme.rst b/library/spam/doc/readme.rst
deleted file mode 100644 (file)
index 451b283..0000000
+++ /dev/null
@@ -1,371 +0,0 @@
-==========
-b8: readme
-==========
-
-:Author: Tobias Leupold
-:Homepage: http://nasauber.de/
-:Contact: tobias.leupold@web.de
-:Date: |date|
-
-.. contents:: Table of Contents
-
-Description of b8
-=================
-
-What is b8?
------------
-
-b8 is a spam filter implemented in `PHP <http://www.php.net/>`__. It is intended to keep your weblog or guestbook spam-free. The filter can be used anywhere in your PHP code and tells you whether a text is spam or not, using statistical text analysis. See `How does it work?`_ for details about this. To be able to do this, b8 first has to learn some spam and some ham example texts to decide what's good and what's not. If it makes mistakes classifying unknown texts, they can be corrected and b8 learns from the corrections, getting better with each learned text.
-
-At the moment of this writing, b8 has classified 14411 guestbook entries and weblog comments on my homepage since december 2006. 131 were ham. 39 spam texts (0.27 %) have been rated as ham (false negatives), with not even one false positive (ham message classified as spam). This results in a sensitivity of 99.73 % (the probability that a spam text will actually be rated as spam) and a specifity of 100 % (the probability that a ham text will actually be rated as ham) for me. I hope, you'll get the same good results :-)
-
-Basically, b8 is a statistical ("Bayesian"[#]_) spam filter like `Bogofilter <http://bogofilter.sourceforge.net/>`__ or `SpamBayes <http://spambayes.sourceforge.net/>`__, but it is not intended to classify e-mails. When I started to write b8, I didn't find a good PHP spam filter (or any spam filter that wasn't just some example code how one *could* implement a Bayesian spam filter in PHP) that was intended to filter weblog or guestbook entries. That's why I had to write my own ;-) |br|
-Caused by it's purpose, the way b8 works is slightly different from most of the Bayesian email spam filters out there. See `What's different?`_ if you're interested in the details.
-
-.. [#] A mathematician told me that the math in b8 actually does not use Bayes' theorem but some derived algorithms that are just related to it. So … let's simply believe that and stop claiming b8 was a *Bayesian* spam filter ;-)
-
-How does it work?
------------------
-
-b8  basically uses the math and technique described in Paul Graham's article "A Plan For Spam" [#planforspam]_ to distinguish ham and spam. The improvements proposed in Graham's article "Better Bayesian Filtering" [#betterbayesian]_ and Gary Robinson's article "Spam Detection" [#spamdetection]_ have also been considered. See also the article "A Statistical Approach to the Spam Problem" [#statisticalapproach]_.
-
-b8 cuts the text to classify to pieces, extracting stuff like e-mail addresses, links and HTML tags. For each such token, it calculates a single probability for a text containing it being spam, based on what the filter has learned so far. When the token was not seen before, b8 tries to find similar ones using the "degeneration" described in [#betterbayesian]_ and uses the most relevant value found. If really nothing is found, b8 assumes a default rating for this token for the further calculations. |br|
-Then, b8 takes the most relevant values (which have a rating far from 0.5, which would mean we don't know what it is) and calculates the probability that the whole text is spam by the inverse chi-square function described in [#spamdetection]_.
-There are some parameters that can be set which influence the filter's behaviour (see below).
-
-In short words: you give b8 a text and it returns a value between 0 and 1, saying it's ham when it's near 0 and saying it's spam when it's near 1.
-
-What do I need for it?
-----------------------
-
-Not much! You just need PHP 5 on the server where b8 will be used (b8 version 0.5 finally dropped PHP 4 compatibility – thankfully ;-) and a proper storage possibility for the wordlists. I strongly recommend using `Berkeley DB <http://www.oracle.com/database/berkeley-db/index.html>`_. See below how you can check if you can use it and why you should use it. If the server's PHP wasn't compiled with Berkeley DB support, a `MySQL <http://mysql.com/>`_ table can be used alternatively.
-
-What's different?
------------------
-
-b8 is designed to classify weblog or guestbook entries, not e-mails. For this reason, it uses a slightly different technique than most of the other statistical spam filters out there use.
-
-My experience was that spam entries on my weblog or guestbook were often quite short, sometimes just something like "123abc" as text and a link to a suspect homepage. Some spam bots don't even made a difference between e. g. the "name" and "text" fields and posted their text as email address, for example. Considering this, b8 just takes one string to classify, making no difference between "headers" and "text". |br|
-The other thing is that most statistical spam filters count one token one time, no matter how often it appears in the text (as Graham describes it in [#planforspam]_). b8 does count how often a token was seen and learns or considers this. Additionally, the number of learned ham and spam texts are saved and used as the calculation base for the single probabilities. Why this? Because a text containing one link (no matter where it points to, just indicated by a "\h\t\t\p\:\/\/" or a "www.") might not be spam, but a text containing 20 links might be.
-
-This means that b8 might be good for classifying weblog or guestbook entries (I really think it is ;-) – but very likely, it will work quite poor when being used for something else (like classifying e-mails). But as said above, for this task, there are a lot of very good filters out there to choose from.
-
-Update from prior versions
-==========================
-
-If this is a new b8 installation, read on at the `Installation`_ section!
-
-Update from bayes-php version 0.2.1 or earlier
-----------------------------------------------
-
-Please first follow the database update instructions of the bayes-php-0.3 release if you update from a version prior to bayes-php-0.3 and then read the following paragraph about updating from a version <0.3.3.
-
-Update from bayes-php version 0.3 or later
-------------------------------------------
-
-**You use Berkeley DB?**
-       Everything's fine, you can simply continue using your database.
-
-**You use MySQL?**
-       The ``CREATE`` statement of b8's wordlist has changed. The best is probably to create a dump via your favorite administration tool or script, create the new table and re-insert all data. The layout is still the same: there's one "token" column and one "data" column. Having done that, you can keep using your data.
-
-**You use SQLite?**
-       Sorry, at the moment, there's no SQLite backend for b8. But we're working on it :-)
-
-The configuration model of b8 has changed.  Please read through the `Configuration`_ section and update your configuration accordingly.
-
-b8's lexer has been partially re-written. It should now be able to handle all kind of non-latin-1 input, like cyrillic, chinese or japanese texts. Caused by this fact, much more tokens will be recognized when classifying such texts. Therefore, you could get different results in b8's ratings, even if the same database is used and although the math is still the same.
-
-b8 0.5 introduced two constants that can be used in the ``learn()`` and ``unlearn()`` functions: ``b8::HAM`` and ``b8::SPAM``. The literal values "ham" and "spam" can still be used anyway.
-
-Installation
-============
-
-Installing b8 on your server is quite easy. You just have to provide the needed files. To do this, you could just upload the whole ``b8`` subdirectory to the base directory of your homepage. It contains the filter itself and all needed backend classes. The other directories (``doc``, ``example`` and ``install``) are not used by b8.
-
-That's it ;-)
-
-Configuration
-=============
-
-The configuration is passed as arrays when instantiating a new b8 object. Two arrays can be passed to b8, one containing b8's base configuration and some settings for the lexer (which should be common for all lexer classes, in case some other lexer than the default one will be written one day) and one for the storage backend. |br|
-You can have a look at ``example/index.php`` to see how this can be done. `Using b8 in your scripts`_ also shows example code showing how b8 can be included in a PHP script.
-
-Not all values have to be set. When some values are missing, the default ones will be used. If you do use the default settings, you don't have to pass them to b8.
-
-b8's base configuration
------------------------
-
-All these values can be set in the "config_b8" array (the first parameter) passed to b8. The name of the array doesn't matter (of course), it just has to be the first argument.
-
-These are some basic settings telling b8 which backend classes to use:
-
-       **storage**
-               This defines which storage backend will be used to save b8's wordlist. Currently, two backends are available: `Berkeley DB <http://www.oracle.com/database/berkeley-db/index.html>`_ (``dba``) and `MySQL <http://mysql.com/>`_ (``mysql``). At the moment, b8 does not support `SQLite <http://sqlite.org/>`_ (as the previous version did), but it will be (hopefully) re-added in one of the next releases. The default is ``dba`` (string).
-
-               *Berkeley DB*
-                       This is the preferred storage backend. It was the original backend for the filter and remains the most performant. b8's storage model is optimized for this database, as it is really fast and fits perfectly to what the filter needs to do the job. All content is saved in a single file, you don't need special user rights or a database server. |br|
-                       If you don't know whether your server's PHP can use a Berkeley DB, simply run the script ``install/setup_berkeleydb.php``. If it shows a Berkeley DB handler, please use this backend.
-
-               *MySQL*
-                       As some webspace hosters don't allow using a Berkeley DB (but please be sure to check if you can use it!), but most do provide a MySQL server, using a MySQL table for the wordlist is provided as an alternative storage method. As said above, b8 was always intended to use a Berkeley DB. It doesn't use or need SQL to query the database. So, very likely, this will work less performant, produce a lot of unnecessary overhead and waste computing power. But it will do fine anyway!
-
-               See `Configuration of the storage backend`_ for the settings of the chosen backend.
-
-       **degenerator**
-               The degenerator class to be used. See `How does it work?`_ and [#betterbayesian]_ if you're interested in what "degeneration" is. Defaults to ``default`` (string). At the moment, only one degenerator exists, so you probably don't want to change this unless you have written your own degenerator.
-
-       **lexer**
-               The lexer class to be used. Defaults to ``default`` (string). At the moment, only one lexer exists, so you probably don't want to change this unless you have written your own lexer.
-
-               The behaviour of the lexer can be additionally configured with the following variables:
-
-                       **min_size**
-                               The minimal length for a token to be considered when calculating the rating of a text. Defaults to ``3`` (integer).
-
-                       **max_size**
-                               The maximal length for a token to be considered when calculating the rating of a text. Defaults to ``30`` (integer).
-
-                       **allow_numbers**
-                               Should pure numbers also be considered? Defaults to ``FALSE`` (boolean).
-
-The following settings influence the mathematical internals of b8. If you want to experiment, feel free to play around with them; but be warned: wrong settings of these values will result in poor performance or could even "short-circuit" the filter. |br|
-Leave these values as they are unless you know what you are doing!
-
-The "Statistical discussion about b8" [#b8statistic]_ shows why the default values are the default ones.
-
-       **use_relevant**
-               This tells b8 how many tokens should be used when calculating the spamminess of a text. The default setting is ``15`` (integer). This seems to be a quite reasonable value. When using to many tokens, the filter will fail on texts filled with useless stuff or with passages from a newspaper, etc. not being very spammish. |br|
-               The tokens counted multiple times (see above) are added in addition to this value. They don't replace other ratings.
-
-       **min_dev**
-               This defines a minimum deviation from 0.5 that a token's rating must have to be considered when calculating the spamminess. Tokens with a rating closer to 0.5 than this value will simply be skipped. |br|
-               If you don't want to use this feature, set this to ``0``. Defaults to ``0.2`` (float). Read [#b8statistic]_ before increasing this.
-
-       **rob_x**
-               This is Gary Robinson's *x* constant (cf. [#spamdetection]_). A completely unknown token will be rated with the value of ``rob_x``. The default ``0.5`` (float) seems to be quite reasonable, as we can't say if a token that also can't be rated by degeneration is good or bad. |br|
-               If you receive much more spam than ham or vice versa, you could change this setting accordingly.
-
-       **rob_s**
-               This is Gary Robinson's *s* constant. This is essentially the probability that the *rob_x* value is correct for a completely unknown token. It will also shift the probability of rarely seen tokens towards this value. The default is ``0.3`` (float) |br|
-               See [#spamdetection]_ for a closer description of the *s* constant and read [#b8statistic]_ for specific information about this constant in b8's algorithms.
-
-Configuration of the storage backend
-------------------------------------
-
-All the following values can be set in the "config_database" array (the second parameter) passed to b8. The name of the array doesn't matter (of course), it just has to be the second argument.
-
-Settings for the Berkeley DB (DBA) backend
-``````````````````````````````````````````
-**database**
-       The filename of the database file, relative to the location of ``b8.php``. Defaults to ``wordlist.db`` (string).
-
-**handler**
-       The DBA handler to use (cf. `the PHP documentation <http://php.net/manual/en/dba.requirements.php>`_ and `Setting up a new Berkeley DB`_). Defaults to ``db4`` (string).
-
-Settings for the MySQL backend
-``````````````````````````````
-
-**database**
-       The database containing b8's wordlist table. Defaults to ``b8_wordlist`` (string).
-
-**table_name**
-       The table containing b8's wordlist. Defaults to ``b8_wordlist`` (string).
-
-**host**
-       The host of the MySQL server. Defaults to ``localhost`` (string).
-
-**user**
-       The user name used to open the database connection. Defaults to ``FALSE`` (boolean).
-
-**pass**
-       The password required to open the database connection. Defaults to ``FALSE`` (boolean).
-
-**connection**
-       An existing MySQL link-resource that can be used by b8. Defaults to ``NULL`` (NULL).
-
-Using b8
-========
-
-Now, that everything is configured, you can start to use b8. A sample script that shows what can be done with the filter exists in ``example/index.php``. The best thing for testing how all this works is to use this script before using b8 in your own scripts.
-
-Before you can start, you have to setup a database so that b8 can store a wordlist.
-
-Setting up a new database
--------------------------
-
-Setting up a new Berkeley DB
-````````````````````````````
-
-I wrote a script to setup a new Berkeley DB for b8. It is located in ``install/setup_berkeleydb.php``. Just run this script on your server and be sure that the directory containing it has the proper access rights set so that the server's HTTP server user or PHP user can create a new file in it (probably ``0777``). The script is quite self-explaining, just run it.
-
-Of course, you can also create a Berkeley DB by hand. In this case, you just have to insert three keys:
-
-::
-
-       bayes*dbversion  => 2
-       bayes*texts.ham  => 0
-       bayes*texts.spam => 0
-
-Be sure to set the right DBA handler in the storage backend configuration if it's not ``db4``.
-
-Setting up a new MySQL table
-````````````````````````````
-
-The SQL file ``install/setup_mysql.sql`` contains both the create statement for the wordlist table of b8 and the ``INSERT`` statements for adding the necessary internal variables.
-
-Simply change the table name according to your needs (or leave it as it is ;-) and run the SQL to setup a b8 wordlist MySQL table.
-
-Using b8 in your scripts
-------------------------
-
-Just have a look at the example script located in ``example/index.php`` to see how you can include b8 in your scripts. Essentially, this strips down to:
-
-::
-
-       # Include the b8 code
-       require "{$_SERVER['DOCUMENT_ROOT']}/b8/b8.php";
-
-       # Do some configuration
-
-       $config_b8 = array(
-               'some_key' => 'some_value',
-               'foo' => 'bar'
-       );
-
-       $config_database = array(
-               'some_key' => 'some_value',
-               'foo' => 'bar'
-       );
-
-       # Create a new b8 instance
-       $b8 = new b8($config_b8, $config_database);
-
-b8 provides three functions in an object oriented way (called e. g. via ``$b8->classify($text)``):
-
-**learn($text, $category)**
-       This saves the reference text ``$text`` (string) in the category ``$category`` (b8 constant). |br|
-       b8 0.5 introduced two constants that can be used as ``$category``: ``b8::HAM`` and ``b8::SPAM``. To be downward compatible with older versions of b8, the literal values "ham" and "spam" (case-sensitive strings) can still be used here.
-
-**unlearn($text, $category)**
-       This function just exists to delete a text from a category in which is has been stored accidentally before. It deletes the reference text ``$text`` (string) from the category ``$category`` (either the constants ``b8::HAM`` or ``b8::SPAM`` or the literal case-sensitive strings "ham" or "spam" – cf. above). |br|
-       **Don't delete a spam text from ham after saving it in spam or vice versa, as long you don't have stored it accidentally in the wrong category before!** This will not improve performance, quite the opposite: it will actually break the filter after a time, as the counter for saved ham or spam texts will reach 0, although you have ham or spam tokens stored: the filter will try to remove texts from the ham or spam data which have never been stored there, decrease the counter for tokens which are found just skip the non-existing words.
-
-**classify($text)**
-       This function takes the text ``$text`` (string), calculates it's probability for being spam it and returns a value between 0 and 1 (float). |br|
-       A value close to 0 says the text is more likely ham and a value close to 1 says the text is more likely spam. What to do with this value is *your* business ;-) See also `Tips on operation`_ below.
-
-Tips on operation
-=================
-
-Before b8 can decide whether a text is spam or ham, you have to tell it what you consider as spam or ham. At least one learned spam or one learned ham text is needed to calculate anything. To get good ratings, you need both learned ham and learned spam texts, the more the better. |br|
-What's considered as "ham" or "spam" can be very different, depending on the operation site. On my homepage, practically each and every text posted in English or using cyrillic letters is spam. On an English or Russian homepage, this will be not the case. So I think it's not really meaningful to provide some "spam data" to start. Just train b8 with "your" spam and ham.
-
-For the practical use, I advise to give the filter all data availible. E. g. name, email address, homepage, IP address und of course the text itself should be stored in a variable (e. g. separated with an ``\n`` or just a space or tab after each block) and then be classified. The learning should also be done with all data availible. |br|
-Saving the IP address is probably only meaningful for spam entries, because spammers often use the same IP address multiple times. In principle, you can leave out the IP of ham entries.
-
-You can use b8 e. g. in a guestbook script and let it classify the text before saving it. Everyone has to decide which rating is necessary to classify a text as "spam", but a rating of >= 0.8 seems to be reasonable for me. If one expects the spam to be in another language that the ham entries or the spams are very short normally, one could also think about a limit of 0.7. |br|
-The email filters out there mostly use > 0.9 or even > 0.99; but keep in mind that they have way more data to analyze in most of the cases. A guestbook entry may be quite short, especially when it's spam.
-
-In my opinion, a autolearn function is very handy. I save spam messages with a rating higher than 0.7 but less than 0.9 automatically as spam. I don't do this with ham messages in an automated way to prevent the filter from saving a false negative as ham and then classifying and learning all the spam as ham when I'm on holidays ;-)
-
-Closing
-=======
-
-So … that's it. Thanks for using b8! If you find a bug or have an idea how to make b8 better, let me know. I'm also always looking forward to get e-mails from people using b8 on their homepages :-)
-
-References
-==========
-
-.. [#planforspam] Paul Graham, *A Plan For Spam* (http://paulgraham.com/spam.html)
-.. [#betterbayesian] Paul Graham, *Better Bayesian Filtering* (http://paulgraham.com/better.html)
-.. [#spamdetection] Gary Robinson, *Spam Detection* (http://radio.weblogs.com/0101454/stories/2002/09/16/spamDetection.html)
-.. [#statisticalapproach] *A Statistical Approach to the Spam Problem* (http://linuxjournal.com/article/6467)
-.. [#b8statistic] Tobias Leupold, *Statistical discussion about b8* (http://nasauber.de/opensource/b8/discussion/)
-
-Appendix
-========
-
-FAQ
----
-
-What about more than two categories?
-````````````````````````````````````
-
-I wrote b8 with the `KISS principle <http://en.wikipedia.org/wiki/KISS_principle>`__ in mind. For the "end-user", we have a class with almost no setup to do that can do three things: classify a text, learn a text and un-learn a text. Normally, there's no need to un-learn a text, so essentially, there are only two functions we need. |br|
-This simplicity is only possible because b8 only knows two categories (normally "Ham" and "Spam" or some other category pair) and tells you, in one float number between 0 and 1, if a given texts rather fits in the first or the second category. If we would support multiple categories, more work would have to be done and things would become more complicated. One would have to setup the categories, have another database layout (perhaps making it mandatory to have SQL) and one float number would not be sufficient to describe b8's output, so more code would be needed – even outside of b8.
-
-All the code, the database layout and particularly the math is intended to do exactly one thing: distinguish between two categories. I think it would be a lot of work to change b8 so that it would support more than two categories. Probably, this is possible to do, but don't ask me in which way we would have to change the math to get multiple-category support – I'm a dentist, not a mathematician ;-) |br|
-Apart from this I do believe that most people using b8 don't want or need multiple categories. They just want to know if a text is spam or not, don't they? I do, at least ;-)
-
-But let's think about the multiple-category thing. How would we calculate a rating for more than two categories? If we had a third one, let's call it "`Treet <http://en.wikipedia.org/wiki/Treet>`__", how would we calculate a rating? We could calculate three different ratings. One for "Ham", one for "Spam" and one for "Treet" and choose the highest one to tell the user what category fits best for the text. This could be done by using a small wrapper script using three instances of b8 as-is and three different databases, each containing texts being "Ham", "Spam", "Treet" and the respective counterparts. |br|
-But here's the problem: if we have "Ham" and "Spam", "Spam" is the counterpart of "Ham". But what's the counterpart of "Spam" if we have more than one additional category? Where do the "Non-Ham", "Non-Spam" and "Non-Treet" texts come from?
-
-Another approach, a direct calculation of more than two probabilities (the "Ham" probability is simply 1 minus the "Spam" probability, so we actually get two probabilities with the return value of b8) out of one database would require big changes in b8's structure and math.
-
-There's a project called `PHPNaiveBayesianFilter <http://xhtml.net/scripts/PHPNaiveBayesianFilter>`__ which supports multiple categories by default. The author calls his software "Version 1.0", but I think this is the very first release, not a stable or mature one. The most recent change of that release dates back to 2003 according to the "changed" date of the files inside the zip archive, so probably, this project is dead or has never been alive and under active development at all. |br|
-Actually, I played around with that code but the results weren't really good, so I decided to write my own spam filter from scratch back in early 2006 ;-)
-
-All in all, there seems to be no easy way to implement multiple (meaning more than two) categories using b8's current code base and probably, b8 will never support more than two categories. Perhaps, a fork or a complete re-write would  be better than implementing such a feature. Anyway, I don't close my mind to multiple categories in b8. Feel free to tell me how multiple categories could be implementented in b8 or how a multiple-category version using the same code base (sharing a common abstract class?) could be written.
-
-What about a list with words to ignore?
-```````````````````````````````````````
-
-Some people suggested to introduce a list with words that b8 will simply ignore. Like "and", "or", "the", and so on. I don't think this is very meaningful.
-
-First, it would just work for the particular language that has been stored in the list. Speaking of my homepage, most of my spam is English, almost all my ham is German. So I would have to maintain a list with the probably less interesting words for at least two languages. Additionally, I get spam in Chinese, Japanese and Cyrillic writing or something else I can't read as well. What word should be ignored in those texts?  |br|
-Second, why should we ever exclude words? Who tells us those words are *actually* meaningless? If a word appears both in ham and spam, it's rating will be near 0.5 and so, it won't be used for the final calculation if a appropriate minimum deviation was set. So b8 will exclude it anyway without any blacklist. And think of this: if we excluded a word of which we only *think* it doesn't mean anything but it actually does appear more often in ham or spam, the results will get even worse.
-
-So why should we care about things we do not have to care about? ;-)
-
-
-Why is it called "b8"?
-``````````````````````
-
-The initial name for the filter was (damn creative!) "bayes-php". There were two main reasons for searching another name: 1. "bayes-php" sucks. 2. the `PHP License <http://php.net/license/3_01.txt>`_ says the PHP guys do not like when the name of a script written in PHP contains the word "PHP". Read the `License FAQ <http://www.php.net/license/index.php#faq-lic>`_ for a reasonable argumentation about this.
-
-Luckily, `Tobias Lang <http://langt.net/>`_ proposed the new name "b8". And these are the reasons why I chose this name:
-
-- "bayes-php" is a "b" followed by 8 letters.
-- "b8" is short and handy. Additionally, there was no program with the name "b8" or "bate"
-- The English verb "to bate" means "to decrease" – and that's what b8 does: it decreases the number of spam entries in your weblog or guestbook!
-- "b8" just sounds way cooler than "bayes-php" ;-)
-
-About the database
-------------------
-
-The database layout
-```````````````````
-
-The database layout is quite simple. It's just key:value for everything stored. There are three "internal" variables stored as normal tokens (but all containing a ``*`` which is always used as a split character by the lexer, so we can't get collisions):
-
-**bayes*dbversion**
-       This indicates the database's "version". The first versions of b8 did not set this. Version "2" indicates that we have a database created by a b8 version already storing `the "lastseen" parameter`_.
-
-**bayes*texts.ham**
-       The number of ham texts learned.
-
-**bayes*texts.spam**
-       The number of spam texts learned.
-
-Each "normal" token is stored with it's literal name as the key and it's data as the value. The data consists of the count of the token in all ham and spam texts and the date when the token was used the last time, all in one string and separated by spaces. So we have the following scheme:
-
-::
-
-       "token" => "count_ham count_spam lastseen"
-
-The "lastseen" parameter
-````````````````````````
-
-Somebody looking at the code might be wondering why b8 stores this "lastseen" parameter. This value is not used for any calculation at the moment. Initially, it was intended to keep the database maintainable in a way that "old" data could be removed. When e. g. a token only appeared once in ham or spam and has not been seen for a year, one could simply delete it from the database. |br|
-I actually never used this feature (does anybody?). So probably, some changes will be done to this one day. Perhaps, I find a way to include this data in the spamminess calculation in a meaningful way, or at least for some statistics. One could also make this optional to keep the calculation effort small if this is needed.
-
-Feel free to send me any suggestions about this!
-
-.. |br| raw:: html
-
-   <br />
-
-.. section-numbering::
-
-.. |date| date::
diff --git a/library/spam/example/index.php b/library/spam/example/index.php
deleted file mode 100644 (file)
index 6d3c142..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-<?php
-
-#   Copyright (C) 2006-2010 Tobias Leupold <tobias.leupold@web.de>
-#
-#   This file is part of the b8 package
-#
-#   This program is free software; you can redistribute it and/or modify it
-#   under the terms of the GNU Lesser General Public License as published by
-#   the Free Software Foundation in version 2.1 of the License.
-#
-#   This program is distributed in the hope that it will be useful, but
-#   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-#   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-#   License for more details.
-#
-#   You should have received a copy of the GNU Lesser General Public License
-#   along with this program; if not, write to the Free Software Foundation,
-#   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-
-
-### This is an example script demonstrating how b8 can be used. ###
-
-#/*
-
-# Use this code block if you want to use Berkeley DB.
-
-# The database filename is interpreted relative to the b8.php script location.
-
-$config_b8 = array(
-       'storage' => 'dba'
-);
-
-$config_database = array(
-       'database' => 'wordlist.db',
-       'handler'  => 'db4'
-);
-
-#*/
-
-/*
-
-# Use this code block if you want to use MySQL.
-
-# An existing link resource can be passed to b8 by setting
-# $config_database['connection'] to this link resource.
-# Be sure to set your database access data otherwise!
-
-$config_b8 = array(
-       'storage' => 'mysql'
-);
-
-$config_database = array(
-       'database'   => 'test',
-       'table_name' => 'b8_wordlist',
-       'host'       => 'localhost',
-       'user'       => '',
-       'pass'       => ''
-);
-
-*/
-
-# To be able to calculate the time the classification took
-
-$time_start = NULL;
-
-function microtimeFloat()
-{
-       list($usec, $sec) = explode(" ", microtime());
-       return ((float) $usec + (float) $sec);
-}
-
-# Output a nicely colored rating
-
-function formatRating($rating)
-{
-
-       if($rating === FALSE)
-               return "<span style=\"color:red\">could not calculate spaminess</span>";
-
-       $red   = floor(255 * $rating);
-       $green = floor(255 * (1 - $rating));
-
-       return "<span style=\"color:rgb($red, $green, 0);\"><b>" . sprintf("%5f", $rating) . "</b></span>";
-
-}
-
-echo <<<END
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
-   "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
-
-<head>
-
-<title>example b8 interface</title>
-
-<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
-
-<meta name="dc.creator" content="Tobias Leupold" />
-<meta name="dc.rights" content="Copyright (c) by Tobias Leupold" />
-
-</head>
-
-<body>
-
-<div>
-
-<h1>example b8 interface</h1>
-
-
-END;
-
-$postedText = "";
-
-if(isset($_POST['action']) and $_POST['text'] ==  "")
-       echo "<p style=\"color:red;\"><b>Please type in a text!</b></p>\n\n";
-
-elseif(isset($_POST['action']) and $_POST['text'] !=  "") {
-
-       $time_start = microtimeFloat();
-
-       # Include the b8 code
-       require dirname(__FILE__) . "/../b8/b8.php";
-
-       # Create a new b8 instance
-       $b8 = new b8($config_b8, $config_database);
-
-       # Check if everything worked smoothly
-
-       $started_up = $b8->validate();
-
-       if($started_up !== TRUE) {
-               echo "<b>example:</b> Could not initialize b8. error code: $started_up";
-               exit;
-       }
-
-       $text = stripslashes($_POST['text']);
-       $postedText = htmlentities($text, ENT_QUOTES, 'UTF-8');
-
-       switch($_POST['action']) {
-
-               case "Classify":
-                       echo "<p><b>Spaminess: " . formatRating($b8->classify($text)) . "</b></p>\n";
-                       break;
-
-               case "Save as Spam":
-
-                       $ratingBefore = $b8->classify($text);
-                       $b8->learn($text, b8::SPAM);
-                       $ratingAfter = $b8->classify($text);
-
-                       echo "<p>Saved the text as Spam</p>\n\n";
-
-                       echo "<div><table>\n";
-                       echo "<tr><td>Classification before learning:</td><td>" . formatRating($ratingBefore) . "</td></tr>\n";
-                       echo "<tr><td>Classification after learning:</td><td>"  . formatRating($ratingAfter)  . "</td></tr>\n";
-                       echo "</table></div>\n\n";
-
-                       break;
-
-               case "Save as Ham":
-
-                       $ratingBefore = $b8->classify($text);
-                       $b8->learn($text, b8::HAM);
-                       $ratingAfter = $b8->classify($text);
-
-                       echo "<p>Saved the text as Ham</p>\n\n";
-
-                       echo "<div><table>\n";
-                       echo "<tr><td>Classification before learning:</td><td>" . formatRating($ratingBefore) . "</td></tr>\n";
-                       echo "<tr><td>Classification after learning:</td><td>"  . formatRating($ratingAfter)  . "</td></tr>\n";
-                       echo "</table></div>\n\n";
-
-                       break;
-
-               case "Delete from Spam":
-                       $b8->unlearn($text, b8::SPAM);
-                       echo "<p style=\"color:green\">Deleted the text from Spam</p>\n\n";
-                       break;
-
-               case "Delete from Ham":
-                       $b8->unlearn($text, b8::HAM);
-                       echo "<p style=\"color:green\">Deleted the text from Ham</p>\n\n";
-                       break;
-
-       }
-
-       $mem_used      = round(memory_get_usage() / 1048576, 5);
-       $peak_mem_used = round(memory_get_peak_usage() / 1048576, 5);
-       $time_taken    = round(microtimeFloat() - $time_start, 5);
-
-}
-
-echo <<<END
-<div>
-<form action="{$_SERVER['PHP_SELF']}" method="post">
-<div>
-<textarea name="text" cols="50" rows="16">$postedText</textarea>
-</div>
-<table>
-<tr>
-<td><input type="submit" name="action" value="Classify" /></td>
-</tr>
-<tr>
-<td><input type="submit" name="action" value="Save as Spam" /></td>
-<td><input type="submit" name="action" value="Save as Ham" /></td>
-</tr>
-<tr>
-<td><input type="submit" name="action" value="Delete from Spam" /></td>
-<td><input type="submit" name="action" value="Delete from Ham" /></td>
-</tr>
-</table>
-</form>
-</div>
-
-</div>
-
-END;
-
-if($time_start !== NULL) {
-
-echo <<<END
-<div>
-<table border="0">
-<tr><td>Memory used:     </td><td>$mem_used&thinsp;MB</td></tr>
-<tr><td>Peak memory used:</td><td>$peak_mem_used&thinsp;MB</td></tr>
-<tr><td>Time taken:      </td><td>$time_taken&thinsp;sec</td></tr>
-</table>
-</div>
-
-END;
-
-}
-
-?>
-
-</body>
-
-</html>
diff --git a/library/spam/install/setup_berkeleydb.php b/library/spam/install/setup_berkeleydb.php
deleted file mode 100644 (file)
index 81e1d5a..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-<?php
-
-#   Copyright (C) 2010 Tobias Leupold <tobias.leupold@web.de>
-#
-#   This file is part of the b8 package
-#
-#   This program is free software; you can redistribute it and/or modify it
-#   under the terms of the GNU Lesser General Public License as published by
-#   the Free Software Foundation in version 2.1 of the License.
-#
-#   This program is distributed in the hope that it will be useful, but
-#   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-#   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-#   License for more details.
-#
-#   You should have received a copy of the GNU Lesser General Public License
-#   along with this program; if not, write to the Free Software Foundation,
-#   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-
-echo <<<END
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
-   "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
-
-<head>
-
-<title>b8 Berkeley DB setup</title>
-
-<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
-
-<meta name="dc.creator" content="Tobias Leupold" />
-<meta name="dc.rights" content="Copyright (c) by Tobias Leupold" />
-
-</head>
-
-<body>
-
-<div>
-
-<h1>b8 Berkeley DB setup</h1>
-
-
-END;
-
-$failed = FALSE;
-
-if(isset($_POST['handler'])) {
-
-       $dbfile = $_POST['dbfile'];
-       $dbfile_directory = $_SERVER['DOCUMENT_ROOT'] . dirname($_SERVER['PHP_SELF']);
-
-       echo "<h2>Creating database</h2>\n\n";
-
-       echo "<p>\n";
-
-       echo "Checking database file name &hellip; ";
-
-       if($dbfile == "") {
-               echo "<span style=\"color:red;\">Please provide the name of the database file!</span><br />\n";
-               $failed = TRUE;
-       }
-       else
-               echo "$dbfile<br />\n";
-
-       if(!$failed) {
-
-               echo "Touching/Creating " . htmlentities($dbfile) . " &hellip; ";
-
-               if(touch($dbfile) === FALSE) {
-                       echo "<span style=\"color:red;\">Failed to touch the database file. Please check the given filename and/or fix the permissions of $dbfile_directory.</span><br />\n";
-                       $failed = TRUE;
-               }
-               else
-                       echo "done<br />\n";
-
-       }
-
-       if(!$failed) {
-
-               echo "Setting file permissions to 0666 &hellip ";
-
-               if(chmod($dbfile, 0666) === FALSE) {
-                       echo "<span style=\"color:red;\">Failed to change the permissions of $dbfile_directory/$dbfile. Please adjust them manually.</span><br />\n";
-                       $failed = TRUE;
-               }
-               else
-                       echo "done<br />\n";
-
-       }
-
-       if(!$failed) {
-
-               echo "Checking if the given file is empty &hellip ";
-
-               if(filesize($dbfile) > 0) {
-                       echo "<span style=\"color:red;\">$dbfile_directory/$dbfile is not empty. Can't create a new database. Please delete/empty this file or give another filename.</span><br />\n";
-                       $failed = TRUE;
-               }
-               else
-                       echo "it is<br />\n";
-
-       }
-
-       if(!$failed) {
-
-               echo "Connecting to $dbfile &hellip; ";
-
-               $db = dba_open($dbfile, "c", $_POST['handler']);
-
-               if($db === FALSE) {
-                       echo "<span style=\"color:red;\">Could not connect to the database!</span><br />\n";
-                       $failed = TRUE;
-               }
-               else
-                       echo "done<br />\n";
-
-       }
-
-       if(!$failed) {
-
-               echo "Storing necessary internal variables &hellip ";
-
-               $internals = array(
-                       "bayes*dbversion" => "2",
-                       "bayes*texts.ham" => "0",
-                       "bayes*texts.spam" => "0"
-               );
-
-               foreach($internals as $key => $value) {
-                       if(dba_insert($key, $value, $db) === FALSE) {
-                               echo "<span style=\"color:red;\">Failed to insert data!</span><br />\n";
-                               $failed = TRUE;
-                               break;
-                       }
-               }
-
-               if(!$failed)
-                       echo "done<br />\n";
-
-       }
-
-       if(!$failed) {
-
-               echo "Trying to read data from the database &hellip ";
-
-               $dbversion = dba_fetch("bayes*dbversion", $db);
-
-               if($dbversion != "2") {
-                       echo "<span style=\"color:red;\">Failed to read data!</span><br />\n";
-                       $failed = TRUE;
-               }
-               else
-                       echo "success<br />\n";
-       }
-
-       if(!$failed) {
-
-               dba_close($db);
-
-               echo "</p>\n\n";
-               echo "<p style=\"color:green;\">Successfully created a new b8 database!</p>\n\n";
-               echo "<table>\n";
-               echo "<tr><td>Filename:</td><td>$dbfile_directory/$dbfile</td></tr>\n";
-               echo "<tr><td>DBA handler:</td><td>{$_POST['handler']}</td><tr>\n";
-               echo "</table>\n\n";
-               echo "<p>Move this file to it's destination directory (default: the base directory of b8) to use it with b8. Be sure to use the right DBA handler in b8's configuration.";
-
-       }
-
-       echo "</p>\n\n";
-
-}
-
-if($failed === TRUE or !isset($_POST['handler'])) {
-
-echo <<<END
-<form action="{$_SERVER['PHP_SELF']}" method="post">
-
-<h2>DBA Handler</h2>
-
-<p>
-The following table shows all available DBA handlers. Please choose the "Berkeley DB" one.
-</p>
-
-<table>
-<tr><td></td><td><b>Handler</b></td><td><b>Description</b></td></tr>
-
-END;
-
-foreach(dba_handlers(TRUE) as $name => $version) {
-
-       $checked = "";
-
-       if(!isset($_POST['handler'])) {
-               if(strpos($version, "Berkeley") !== FALSE )
-                       $checked = " checked=\"checked\"";
-       }
-       else {
-               if($_POST['handler'] == $name)
-                       $checked = " checked=\"checked\"";
-       }
-
-       echo "<tr><td><input type=\"radio\" name=\"handler\" value=\"$name\"$checked /></td><td>$name</td><td>$version</td></tr>\n";
-
-}
-
-echo <<<END
-</table>
-
-<h2>Database file</h2>
-
-<p>
-Please the name of the desired database file. It will be created in the directory where this script is located.
-</p>
-
-<p>
-<input type="text" name="dbfile" value="wordlist.db" />
-</p>
-
-<p>
-<input type="submit" value="Create the database" />
-</p>
-
-</form>
-
-
-END;
-
-}
-
-?>
-
-</div>
-
-</body>
-
-</html>
diff --git a/library/spam/install/setup_mysql.sql b/library/spam/install/setup_mysql.sql
deleted file mode 100644 (file)
index ac43274..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-
---   Copyright (C) 2010 Tobias Leupold <tobias.leupold@web.de>
---
---   This file is part of the b8 package
---
---   This program is free software; you can redistribute it and/or modify it
---   under the terms of the GNU Lesser General Public License as published by
---   the Free Software Foundation in version 2.1 of the License.
---
---   This program is distributed in the hope that it will be useful, but
---   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
---   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
---   License for more details.
---
---   You should have received a copy of the GNU Lesser General Public License
---   along with this program; if not, write to the Free Software Foundation,
---   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-
-CREATE TABLE `b8_wordlist` (
-  `token` varchar(255) character set utf8 collate utf8_bin NOT NULL,
-  `count` varchar(255) default NULL,
-  PRIMARY KEY  (`token`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-
-INSERT INTO `b8_wordlist` VALUES ('bayes*dbversion', '2');
-INSERT INTO `b8_wordlist` VALUES ('bayes*texts.ham', '0');
-INSERT INTO `b8_wordlist` VALUES ('bayes*texts.spam', '0');
index 79fcebf47be52f072a24e157a28eed04c2393fb9..3ca8ea49359cff8e7c8d41fe34331b2dfe283314 100644 (file)
@@ -629,7 +629,6 @@ function admin_page_site_post(App $a) {
        $no_multi_reg           =       ((x($_POST,'no_multi_reg'))             ? True                                          : False);
        $no_openid              =       !((x($_POST,'no_openid'))               ? True                                          : False);
        $no_regfullname         =       !((x($_POST,'no_regfullname'))          ? True                                          : False);
-       $no_utf                 =       !((x($_POST,'no_utf'))                  ? True                                          : False);
        $community_page_style   =       ((x($_POST,'community_page_style'))     ? intval(trim($_POST['community_page_style']))  : 0);
        $max_author_posts_community_page        =       ((x($_POST,'max_author_posts_community_page'))  ? intval(trim($_POST['max_author_posts_community_page']))       : 0);
 
@@ -666,7 +665,6 @@ function admin_page_site_post(App $a) {
        $proxy_disabled         =       ((x($_POST,'proxy_disabled'))           ? True                                          : False);
        $only_tag_search        =       ((x($_POST,'only_tag_search'))          ? True                                          : False);
        $rino                   =       ((x($_POST,'rino'))                     ? intval($_POST['rino'])                        : 0);
-       $embedly                =       ((x($_POST,'embedly'))                  ? notags(trim($_POST['embedly']))               : '');
        $worker_queues          =       ((x($_POST,'worker_queues'))            ? intval($_POST['worker_queues'])               : 4);
        $worker_dont_fork       =       ((x($_POST,'worker_dont_fork'))         ? True                                          : False);
        $worker_fastlane        =       ((x($_POST,'worker_fastlane'))          ? True                                          : False);
@@ -763,66 +761,57 @@ function admin_page_site_post(App $a) {
                } else {
                        set_config('system','singleuser', $singleuser);
                }
-       set_config('system','maximagesize', $maximagesize);
-       set_config('system','max_image_length', $maximagelength);
-       set_config('system','jpeg_quality', $jpegimagequality);
-
-       set_config('config','register_policy', $register_policy);
-       set_config('system','max_daily_registrations', $daily_registrations);
-       set_config('system','account_abandon_days', $abandon_days);
-       set_config('config','register_text', $register_text);
-       set_config('system','allowed_sites', $allowed_sites);
-       set_config('system','allowed_email', $allowed_email);
-       set_config('system','block_public', $block_public);
-       set_config('system','publish_all', $force_publish);
-       set_config('system','directory', $global_directory);
-       set_config('system','thread_allow', $thread_allow);
-       set_config('system','newuser_private', $newuser_private);
-       set_config('system','enotify_no_content', $enotify_no_content);
-       set_config('system','disable_embedded', $disable_embedded);
-       set_config('system','allow_users_remote_self', $allow_users_remote_self);
-
-       set_config('system','block_extended_register', $no_multi_reg);
-       set_config('system','no_openid', $no_openid);
-       set_config('system','no_regfullname', $no_regfullname);
-       set_config('system','community_page_style', $community_page_style);
-       set_config('system','max_author_posts_community_page', $max_author_posts_community_page);
-       set_config('system','no_utf', $no_utf);
-       set_config('system','verifyssl', $verifyssl);
-       set_config('system','proxyuser', $proxyuser);
-       set_config('system','proxy', $proxy);
-       set_config('system','curl_timeout', $timeout);
-       set_config('system','dfrn_only', $dfrn_only);
-       set_config('system','ostatus_disabled', $ostatus_disabled);
-       set_config('system','ostatus_poll_interval', $ostatus_poll_interval);
-       set_config('system','ostatus_full_threads', $ostatus_full_threads);
-       set_config('system','diaspora_enabled', $diaspora_enabled);
-
-       set_config('config','private_addons', $private_addons);
-
-       set_config('system','force_ssl', $force_ssl);
-       set_config('system','hide_help', $hide_help);
-       set_config('system','use_fulltext_engine', $use_fulltext_engine);
-       set_config('system','itemcache', $itemcache);
-       set_config('system','itemcache_duration', $itemcache_duration);
-       set_config('system','max_comments', $max_comments);
-       set_config('system','temppath', $temppath);
-       set_config('system','basepath', $basepath);
-       set_config('system','proxy_disabled', $proxy_disabled);
-       set_config('system','only_tag_search', $only_tag_search);
-       set_config('system','worker_queues', $worker_queues);
-       set_config('system','worker_dont_fork', $worker_dont_fork);
-       set_config('system','worker_fastlane', $worker_fastlane);
-       set_config('system','frontend_worker', $worker_frontend);
-
-       if (($rino == 2) and !function_exists('mcrypt_create_iv')) {
-               notice(t("RINO2 needs mcrypt php extension to work."));
-       } else {
-               set_config('system','rino_encrypt', $rino);
-       }
-
-       set_config('system','embedly', $embedly);
-
+       set_config('system', 'maximagesize', $maximagesize);
+       set_config('system', 'max_image_length', $maximagelength);
+       set_config('system', 'jpeg_quality', $jpegimagequality);
+
+       set_config('config', 'register_policy', $register_policy);
+       set_config('system', 'max_daily_registrations', $daily_registrations);
+       set_config('system', 'account_abandon_days', $abandon_days);
+       set_config('config', 'register_text', $register_text);
+       set_config('system', 'allowed_sites', $allowed_sites);
+       set_config('system', 'allowed_email', $allowed_email);
+       set_config('system', 'block_public', $block_public);
+       set_config('system', 'publish_all', $force_publish);
+       set_config('system', 'directory', $global_directory);
+       set_config('system', 'thread_allow', $thread_allow);
+       set_config('system', 'newuser_private', $newuser_private);
+       set_config('system', 'enotify_no_content', $enotify_no_content);
+       set_config('system', 'disable_embedded', $disable_embedded);
+       set_config('system', 'allow_users_remote_self', $allow_users_remote_self);
+
+       set_config('system', 'block_extended_register', $no_multi_reg);
+       set_config('system', 'no_openid', $no_openid);
+       set_config('system', 'no_regfullname', $no_regfullname);
+       set_config('system', 'community_page_style', $community_page_style);
+       set_config('system', 'max_author_posts_community_page', $max_author_posts_community_page);
+       set_config('system', 'verifyssl', $verifyssl);
+       set_config('system', 'proxyuser', $proxyuser);
+       set_config('system', 'proxy', $proxy);
+       set_config('system', 'curl_timeout', $timeout);
+       set_config('system', 'dfrn_only', $dfrn_only);
+       set_config('system', 'ostatus_disabled', $ostatus_disabled);
+       set_config('system', 'ostatus_poll_interval', $ostatus_poll_interval);
+       set_config('system', 'ostatus_full_threads', $ostatus_full_threads);
+       set_config('system', 'diaspora_enabled', $diaspora_enabled);
+
+       set_config('config', 'private_addons', $private_addons);
+
+       set_config('system', 'force_ssl', $force_ssl);
+       set_config('system', 'hide_help', $hide_help);
+       set_config('system', 'use_fulltext_engine', $use_fulltext_engine);
+       set_config('system', 'itemcache', $itemcache);
+       set_config('system', 'itemcache_duration', $itemcache_duration);
+       set_config('system', 'max_comments', $max_comments);
+       set_config('system', 'temppath', $temppath);
+       set_config('system', 'basepath', $basepath);
+       set_config('system', 'proxy_disabled', $proxy_disabled);
+       set_config('system', 'only_tag_search', $only_tag_search);
+       set_config('system', 'worker_queues', $worker_queues);
+       set_config('system', 'worker_dont_fork', $worker_dont_fork);
+       set_config('system', 'worker_fastlane', $worker_fastlane);
+       set_config('system', 'frontend_worker', $worker_frontend);
+       set_config('system', 'rino_encrypt', $rino);
 
        info(t('Site settings updated.').EOL);
        goaway('admin/site');
@@ -1012,7 +1001,6 @@ function admin_page_site(App $a) {
                '$no_multi_reg'         => array('no_multi_reg', t("Block multiple registrations"),  get_config('system','block_extended_register'), t("Disallow users to register additional accounts for use as pages.")),
                '$no_openid'            => array('no_openid', t("OpenID support"), !get_config('system','no_openid'), t("OpenID support for registration and logins.")),
                '$no_regfullname'       => array('no_regfullname', t("Fullname check"), !get_config('system','no_regfullname'), t("Force users to register with a space between firstname and lastname in Full name, as an antispam measure")),
-               '$no_utf'               => array('no_utf', t("UTF-8 Regular expressions"), !get_config('system','no_utf'), t("Use PHP UTF8 regular expressions")),
                '$community_page_style' => array('community_page_style', t("Community Page Style"), get_config('system','community_page_style'), t("Type of community page to show. 'Global community' shows every public posting from an open distributed network that arrived on this server."), $community_page_style_choices),
                '$max_author_posts_community_page' => array('max_author_posts_community_page', t("Posts per user on community page"), get_config('system','max_author_posts_community_page'), t("The maximum number of posts per user on the community page. (Not valid for 'Global Community')")),
                '$ostatus_disabled'     => array('ostatus_disabled', t("Enable OStatus support"), !get_config('system','ostatus_disabled'), t("Provide built-in OStatus \x28StatusNet, GNU Social etc.\x29 compatibility. All communications in OStatus are public, so privacy warnings will be occasionally displayed.")),
@@ -1053,7 +1041,6 @@ function admin_page_site(App $a) {
                '$relocate_url'         => array('relocate_url', t("New base url"), App::get_baseurl(), t("Change base url for this server. Sends relocate message to all DFRN contacts of all users.")),
 
                '$rino'                 => array('rino', t("RINO Encryption"), intval(get_config('system','rino_encrypt')), t("Encryption layer between nodes."), array("Disabled", "RINO1 (deprecated)", "RINO2")),
-               '$embedly'              => array('embedly', t("Embedly API key"), get_config('system','embedly'), t("<a href='http://embed.ly'>Embedly</a> is used to fetch additional data for web pages. This is an optional parameter.")),
 
                '$worker_queues'        => array('worker_queues', t("Maximum number of parallel workers"), get_config('system','worker_queues'), t("On shared hosters set this to 2. On larger systems, values of 10 are great. Default value is 4.")),
                '$worker_dont_fork'     => array('worker_dont_fork', t("Don't use 'proc_open' with the worker"), get_config('system','worker_dont_fork'), t("Enable this if your system doesn't allow the use of 'proc_open'. This can happen on shared hosters. If this is enabled you should increase the frequency of poller calls in your crontab.")),
index e8ea11c94e904305d6d89985c5ab730e6cfcabb6..f71863bdedaf2253720fb6b3d90ac8aeb8957ac0 100644 (file)
@@ -1,78 +1,73 @@
 <?php
 
-require_once('include/bbcode.php');
-require_once('library/markdown.php');
-require_once('include/bb2diaspora.php');
-require_once('include/html2bbcode.php');
+require_once 'include/bbcode.php';
+require_once 'library/markdown.php';
+require_once 'include/bb2diaspora.php';
+require_once 'include/html2bbcode.php';
 
 function visible_lf($s) {
-       return str_replace("\n",'<br />', $s);
+       return str_replace("\n", '<br />', $s);
 }
 
 function babel_content(App $a) {
-
        $o .= '<h1>Babel Diagnostic</h1>';
 
        $o .= '<form action="babel" method="post">';
-       $o .= t('Source (bbcode) text:') . EOL . '<textarea name="text" >' . htmlspecialchars($_REQUEST['text']) .'</textarea>' . EOL;
+       $o .= t('Source (bbcode) text:') . EOL;
+       $o .= '<textarea name="text" cols="80" rows="10">' . htmlspecialchars($_REQUEST['text']) .'</textarea>' . EOL;
        $o .= '<input type="submit" name="submit" value="Submit" /></form>';
 
        $o .= '<br /><br />';
 
        $o .= '<form action="babel" method="post">';
-       $o .= t('Source (Diaspora) text to convert to BBcode:') . EOL . '<textarea name="d2bbtext" >' . htmlspecialchars($_REQUEST['d2bbtext']) .'</textarea>' . EOL;
+       $o .= t('Source (Diaspora) text to convert to BBcode:') . EOL;
+       $o .= '<textarea name="d2bbtext" cols="80" rows="10">' . htmlspecialchars($_REQUEST['d2bbtext']) .'</textarea>' . EOL;
        $o .= '<input type="submit" name="submit" value="Submit" /></form>';
 
        $o .= '<br /><br />';
 
-       if(x($_REQUEST,'text')) {
-
+       if (x($_REQUEST, 'text')) {
                $text = trim($_REQUEST['text']);
-               $o .= "<h2>" . t("Source input: ") . "</h2>" . EOL. EOL;
+               $o .= '<h2>' . t('Source input: ') . '</h2>' . EOL. EOL;
                $o .= visible_lf($text) . EOL. EOL;
 
                $html = bbcode($text);
-               $o .= "<h2>" . t("bb2html (raw HTML): ") . "</h2>" . EOL. EOL;
+               $o .= '<h2>' . t('bb2html (raw HTML): ') . '</h2>' . EOL. EOL;
                $o .= htmlspecialchars($html). EOL. EOL;
 
                //$html = bbcode($text);
-               $o .= "<h2>" . t("bb2html: ") . "</h2>" . EOL. EOL;
+               $o .= '<h2>' . t('bb2html: ') . '</h2>' . EOL. EOL;
                $o .= $html. EOL. EOL;
 
                $bbcode = html2bbcode($html);
-               $o .= "<h2>" . t("bb2html2bb: ") . "</h2>" . EOL. EOL;
+               $o .= '<h2>' . t('bb2html2bb: ') . '</h2>' . EOL. EOL;
                $o .= visible_lf($bbcode) . EOL. EOL;
 
                $diaspora = bb2diaspora($text);
-               $o .= "<h2>" . t("bb2md: ") . "</h2>" . EOL. EOL;
+               $o .= '<h2>' . t('bb2md: ') . '</h2>' . EOL. EOL;
                $o .= visible_lf($diaspora) . EOL. EOL;
 
                $html = Markdown($diaspora);
-               $o .= "<h2>" . t("bb2md2html: ") . "</h2>" . EOL. EOL;
+               $o .= '<h2>' . t('bb2md2html: ') . '</h2>' . EOL. EOL;
                $o .= $html. EOL. EOL;
 
                $bbcode = diaspora2bb($diaspora);
-               $o .= "<h2>" . t("bb2dia2bb: ") . "</h2>" . EOL. EOL;
+               $o .= '<h2>' . t('bb2dia2bb: ') . '</h2>' . EOL. EOL;
                $o .= visible_lf($bbcode) . EOL. EOL;
 
                $bbcode = html2bbcode($html);
-               $o .= "<h2>" . t("bb2md2html2bb: ") . "</h2>" . EOL. EOL;
+               $o .= '<h2>' . t('bb2md2html2bb: ') . '</h2>' . EOL. EOL;
                $o .= visible_lf($bbcode) . EOL. EOL;
-
-
-
        }
 
-       if(x($_REQUEST,'d2bbtext')) {
-
+       if (x($_REQUEST, 'd2bbtext')) {
                $d2bbtext = trim($_REQUEST['d2bbtext']);
-               $o .= "<h2>" . t("Source input (Diaspora format): ") . "</h2>" . EOL. EOL;
-               $o .= visible_lf($d2bbtext) . EOL. EOL;
-
+               $o .= '<h2>' . t('Source input (Diaspora format): ') . '</h2>' . EOL. EOL;
+               $o .= '<pre>' . $d2bbtext . '</pre>' . EOL. EOL;
 
                $bb = diaspora2bb($d2bbtext);
-               $o .= "<h2>" . t("diaspora2bb: ") . "</h2>" . EOL. EOL;
-               $o .= visible_lf($bb) . EOL. EOL;
+               $o .= '<h2>' . t('diaspora2bb: ') . '</h2>' . EOL. EOL;
+               $o .= '<pre>' . $bb . '</pre>' . EOL. EOL;
        }
 
        return $o;
index 174330401019dd544af812de5101bdb42bc1bbfe..45326e291d01236b304b53e5614cefe8591e2778 100644 (file)
@@ -1,12 +1,12 @@
 <?php
 
+use \Friendica\Core\Config;
+
 function community_init(App $a) {
        if (! local_user()) {
                unset($_SESSION['theme']);
                unset($_SESSION['mobile-theme']);
        }
-
-
 }
 
 
@@ -14,16 +14,12 @@ function community_content(App $a, $update = 0) {
 
        $o = '';
 
-       // Currently the community page isn't able to handle update requests
-       if ($update)
-               return;
-
-       if((get_config('system','block_public')) && (! local_user()) && (! remote_user())) {
+       if ((Config::get('system','block_public')) && (! local_user()) && (! remote_user())) {
                notice( t('Public access denied.') . EOL);
                return;
        }
 
-       if(get_config('system','community_page_style') == CP_NO_COMMUNITY_PAGE) {
+       if (Config::get('system','community_page_style') == CP_NO_COMMUNITY_PAGE) {
                notice( t('Not available.') . EOL);
                return;
        }
@@ -34,15 +30,15 @@ function community_content(App $a, $update = 0) {
 
 
        $o .= '<h3>' . t('Community') . '</h3>';
-       if(! $update) {
+       if (! $update) {
                nav_set_selected('community');
        }
 
-       if(x($a->data,'search'))
+       if (x($a->data,'search')) {
                $search = notags(trim($a->data['search']));
-       else
+       } else {
                $search = ((x($_GET,'search')) ? notags(trim(rawurldecode($_GET['search']))) : '');
-
+       }
 
        // Here is the way permissions work in this module...
        // Only public posts can be shown
@@ -55,7 +51,7 @@ function community_content(App $a, $update = 0) {
                return $o;
        }
 
-       $maxpostperauthor = get_config('system','max_author_posts_community_page');
+       $maxpostperauthor = Config::get('system','max_author_posts_community_page');
 
        if ($maxpostperauthor != 0) {
                $count = 1;
@@ -65,23 +61,24 @@ function community_content(App $a, $update = 0) {
 
                do {
                        foreach ($r AS $row=>$item) {
-                               if ($previousauthor == $item["author-link"])
+                               if ($previousauthor == $item["author-link"]) {
                                        ++$numposts;
-                               else
+                               } else {
                                        $numposts = 0;
-
+                               }
                                $previousauthor = $item["author-link"];
 
-                               if (($numposts < $maxpostperauthor) AND (sizeof($s) < $a->pager['itemspage']))
+                               if (($numposts < $maxpostperauthor) AND (sizeof($s) < $a->pager['itemspage'])) {
                                        $s[] = $item;
+                               }
                        }
-                       if ((sizeof($s) < $a->pager['itemspage']))
+                       if ((sizeof($s) < $a->pager['itemspage'])) {
                                $r = community_getitems($a->pager['start'] + ($count * $a->pager['itemspage']), $a->pager['itemspage']);
-
+                       }
                } while ((sizeof($s) < $a->pager['itemspage']) AND (++$count < 50) AND (sizeof($r) > 0));
-       } else
+       } else {
                $s = $r;
-
+       }
        // we behave the same in message lists as the search module
 
        $o .= conversation($a, $s, 'community', $update);
@@ -92,9 +89,9 @@ function community_content(App $a, $update = 0) {
 }
 
 function community_getitems($start, $itemspage) {
-       if (get_config('system','community_page_style') == CP_GLOBAL_COMMUNITY)
+       if (Config::get('system','community_page_style') == CP_GLOBAL_COMMUNITY) {
                return(community_getpublicitems($start, $itemspage));
-
+       }
        $r = qu("SELECT %s
                FROM `thread`
                INNER JOIN `user` ON `user`.`uid` = `thread`.`uid` AND NOT `user`.`hidewall`
index 7e14610e3397c15106a28caa5e586d44df154bb4..001fa446891b28eaf205b763d8168dff26005a1f 100644 (file)
@@ -185,10 +185,10 @@ function dfrn_confirm_post(App $a, $handsfree = null) {
                         *
                         */
 
-                       $src_aes_key = random_string();
+                       $src_aes_key = openssl_random_pseudo_bytes(64);
 
                        $result = '';
-                       openssl_private_encrypt($dfrn_id,$result,$user[0]['prvkey']);
+                       openssl_private_encrypt($dfrn_id, $result, $user[0]['prvkey']);
 
                        $params['dfrn_id'] = bin2hex($result);
                        $params['public_key'] = $public_key;
index ddbc9219b1d209d14b609a9feb8d38b2b1702c19..b42ef9b70a82cee1bc669945d2bd8c3c9fba0a27 100644 (file)
@@ -138,10 +138,6 @@ function dfrn_notify_post(App $a) {
 
        $rino = get_config('system', 'rino_encrypt');
        $rino = intval($rino);
-       // use RINO1 if mcrypt isn't installed and RINO2 was selected
-       if ($rino == 2 && !function_exists('mcrypt_create_iv')) {
-               $rino = 1;
-       }
 
        logger("Local rino version: " .  $rino, LOGGER_DEBUG);
 
@@ -178,10 +174,10 @@ function dfrn_notify_post(App $a) {
                        case 0:
                        case 1:
                                /*
-                                * we got a key. old code send only the key, without RINO version.
+                                *we got a key. old code send only the key, without RINO version.
                                 * we assume RINO 1 if key and no RINO version
                                 */
-                               $data = aes_decrypt(hex2bin($data), $final_key);
+                               $data = dfrn::aes_decrypt(hex2bin($data), $final_key);
                                break;
                        case 2:
                                try {
@@ -316,10 +312,6 @@ function dfrn_notify_content(App $a) {
 
                $rino = get_config('system', 'rino_encrypt');
                $rino = intval($rino);
-               // use RINO1 if mcrypt isn't installed and RINO2 was selected
-               if ($rino == 2 && !function_exists('mcrypt_create_iv')) {
-                       $rino = 1;
-               }
 
                logger("Local rino version: ". $rino, LOGGER_DEBUG);
 
index 1b19ad92c459e6bad268224fbf2819fc53a7681d..c5844d13dfa742689c0e202a7a9cd92a9772fd68 100644 (file)
@@ -73,9 +73,9 @@ function dirfind_content(App $a, $prefix = "") {
                        $j->results[] = $objresult;
 
                        // Add the contact to the global contacts if it isn't already in our system
-                       if (($contact["cid"] == 0) AND ($contact["zid"] == 0) AND ($contact["gid"] == 0))
-                               poco_check($user_data["url"], $user_data["name"], $user_data["network"], $user_data["photo"],
-                                       "", "", "", "", "", datetime_convert(), 0);
+                       if (($contact["cid"] == 0) AND ($contact["zid"] == 0) AND ($contact["gid"] == 0)) {
+                               update_gcontact($user_data);
+                       }
                } elseif ($local) {
 
                        if ($community)
index 6db79dca286b6b25aba7a3bcb706e58ca93e7149..fbd296a9da565b5b09f45a1349ae2ee12dfa2af6 100755 (executable)
@@ -78,14 +78,7 @@ function install_post(App $a) {
                        $timezone = notags(trim($_POST['timezone']));
                        $language = notags(trim($_POST['language']));
                        $adminmail = notags(trim($_POST['adminmail']));
-                       // In step 4 of the installer, we passed the  check for mcrypt
-                       // already, so we can activate RINO, make RINO2 the default
-                       // and only fall back if the mcrypt_create_iv function is
-                       // not available on the system.
                        $rino = 2;
-                       if (! function_exists('mcrypt_create_iv')) {
-                               $rino = 1;
-                       }
 
                        // connect to db
                        $db = new dba($dbhost, $dbuser, $dbpass, $dbdata, true);
@@ -422,7 +415,6 @@ function check_funcs(&$checks) {
        check_add($ck_funcs, t('OpenSSL PHP module'), true, true, "");
        check_add($ck_funcs, t('mysqli PHP module'), true, true, "");
        check_add($ck_funcs, t('mb_string PHP module'), true, true, "");
-       check_add($ck_funcs, t('mcrypt PHP module'), true, true, "");
        check_add($ck_funcs, t('XML PHP module'), true, true, "");
        check_add($ck_funcs, t('iconv module'), true, true, "");
 
@@ -454,10 +446,6 @@ function check_funcs(&$checks) {
                $ck_funcs[4]['status']= false;
                $ck_funcs[4]['help']= t('Error: mb_string PHP module required but not installed.');
        }
-       if (! function_exists('mcrypt_create_iv')){
-               $ck_funcs[5]['status']= false;
-               $ck_funcs[5]['help']= t('Error: mcrypt PHP module required but not installed.');
-       }
        if (! function_exists('iconv_strlen')){
                $ck_funcs[7]['status']= false;
                $ck_funcs[7]['help']= t('Error: iconv PHP module required but not installed.');
@@ -465,18 +453,6 @@ function check_funcs(&$checks) {
 
        $checks = array_merge($checks, $ck_funcs);
 
-       // check for 'mcrypt_create_iv()', needed for RINO2
-       if ($ck_funcs[5]['status']) {
-               if (function_exists('mcrypt_create_iv')) {
-                       $__status = true;
-                       $__help = t("If you are using php_cli, please make sure that mcrypt module is enabled in its config file");
-               } else {
-                       $__status = false;
-                       $__help = t('Function mcrypt_create_iv() is not defined. This is needed to enable RINO2 encryption layer.');
-               }
-               check_add($checks, t('mcrypt_create_iv() function'), $__status, false, $__help);
-       }
-
        // check for XML DOM Documents being able to be generated
        try {
                $xml = new DOMDocument();
index 6f204947579bfafd263019709422f62e1ef40add..7f010cee416afbf5e75b8b63ead69ccb51a2b7b5 100644 (file)
@@ -5,15 +5,13 @@
  * Documentation: http://nodeinfo.diaspora.software/schema.html
 */
 
-require_once("include/plugin.php");
+use \Friendica\Core\Config;
+
+require_once 'include/plugin.php';
 
 function nodeinfo_wellknown(App $a) {
-       if (!get_config("system", "nodeinfo")) {
-               http_status_exit(404);
-               killme();
-       }
-       $nodeinfo = array("links" => array(array("rel" => "http://nodeinfo.diaspora.software/ns/schema/1.0",
-                                       "href" => App::get_baseurl()."/nodeinfo/1.0")));
+       $nodeinfo = array('links' => array(array('rel' => 'http://nodeinfo.diaspora.software/ns/schema/1.0',
+                                       'href' => App::get_baseurl().'/nodeinfo/1.0')));
 
        header('Content-type: application/json; charset=utf-8');
        echo json_encode($nodeinfo, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
@@ -21,124 +19,127 @@ function nodeinfo_wellknown(App $a) {
 }
 
 function nodeinfo_init(App $a) {
-       if (!get_config("system", "nodeinfo")) {
+       if (!Config::get('system', 'nodeinfo')) {
                http_status_exit(404);
                killme();
        }
 
-       if (($a->argc != 2) OR ($a->argv[1] != "1.0")) {
+       if (($a->argc != 2) OR ($a->argv[1] != '1.0')) {
                http_status_exit(404);
                killme();
        }
 
-       $smtp = (function_exists("imap_open") AND !get_config("system","imap_disabled") AND !get_config("system","dfrn_only"));
+       $smtp = (function_exists('imap_open') AND !Config::get('system', 'imap_disabled') AND !Config::get('system', 'dfrn_only'));
 
        $nodeinfo = array();
-       $nodeinfo["version"] = "1.0";
-       $nodeinfo["software"] = array("name" => "friendica", "version" => FRIENDICA_VERSION."-".DB_UPDATE_VERSION);
+       $nodeinfo['version'] = '1.0';
+       $nodeinfo['software'] = array('name' => 'friendica', 'version' => FRIENDICA_VERSION.'-'.DB_UPDATE_VERSION);
 
-       $nodeinfo["protocols"] = array();
-       $nodeinfo["protocols"]["inbound"] = array();
-       $nodeinfo["protocols"]["outbound"] = array();
+       $nodeinfo['protocols'] = array();
+       $nodeinfo['protocols']['inbound'] = array();
+       $nodeinfo['protocols']['outbound'] = array();
 
-       if (get_config("system","diaspora_enabled")) {
-               $nodeinfo["protocols"]["inbound"][] = "diaspora";
-               $nodeinfo["protocols"]["outbound"][] = "diaspora";
+       if (Config::get('system', 'diaspora_enabled')) {
+               $nodeinfo['protocols']['inbound'][] = 'diaspora';
+               $nodeinfo['protocols']['outbound'][] = 'diaspora';
        }
 
-       $nodeinfo["protocols"]["inbound"][] = "friendica";
-       $nodeinfo["protocols"]["outbound"][] = "friendica";
+       $nodeinfo['protocols']['inbound'][] = 'friendica';
+       $nodeinfo['protocols']['outbound'][] = 'friendica';
 
-       if (!get_config("system","ostatus_disabled")) {
-               $nodeinfo["protocols"]["inbound"][] = "gnusocial";
-               $nodeinfo["protocols"]["outbound"][] = "gnusocial";
+       if (!Config::get('system', 'ostatus_disabled')) {
+               $nodeinfo['protocols']['inbound'][] = 'gnusocial';
+               $nodeinfo['protocols']['outbound'][] = 'gnusocial';
        }
 
-       $nodeinfo["services"] = array();
-       $nodeinfo["services"]["inbound"] = array();
-       $nodeinfo["services"]["outbound"] = array();
-
-       $nodeinfo["openRegistrations"] = ($a->config['register_policy'] != 0);
-
-       $nodeinfo["usage"] = array();
-       $nodeinfo["usage"]["users"] = array("total" => (int)get_config("nodeinfo","total_users"),
-                               "activeHalfyear" => (int)get_config("nodeinfo","active_users_halfyear"),
-                               "activeMonth" => (int)get_config("nodeinfo","active_users_monthly"));
-       $nodeinfo["usage"]["localPosts"] = (int)get_config("nodeinfo","local_posts");
-       $nodeinfo["usage"]["localComments"] = (int)get_config("nodeinfo","local_comments");
+       $nodeinfo['services'] = array();
+       $nodeinfo['services']['inbound'] = array();
+       $nodeinfo['services']['outbound'] = array();
 
-       $nodeinfo["metadata"] = array("nodeName" => $a->config["sitename"]);
+       $nodeinfo['usage'] = array();
 
-       if (plugin_enabled("appnet"))
-               $nodeinfo["services"]["inbound"][] = "appnet";
-
-       if (plugin_enabled("appnet") OR plugin_enabled("buffer"))
-               $nodeinfo["services"]["outbound"][] = "appnet";
-
-       if (plugin_enabled("blogger"))
-               $nodeinfo["services"]["outbound"][] = "blogger";
-
-       if (plugin_enabled("dwpost"))
-               $nodeinfo["services"]["outbound"][] = "dreamwidth";
-
-       if (plugin_enabled("fbpost") OR plugin_enabled("buffer"))
-               $nodeinfo["services"]["outbound"][] = "facebook";
-
-       if (plugin_enabled("statusnet")) {
-               $nodeinfo["services"]["inbound"][] = "gnusocial";
-               $nodeinfo["services"]["outbound"][] = "gnusocial";
-       }
+       $nodeinfo['openRegistrations'] = ($a->config['register_policy'] != 0);
 
-       if (plugin_enabled("gpluspost") OR plugin_enabled("buffer"))
-               $nodeinfo["services"]["outbound"][] = "google";
+       $nodeinfo['metadata'] = array('nodeName' => $a->config['sitename']);
 
-       if (plugin_enabled("ijpost"))
-               $nodeinfo["services"]["outbound"][] = "insanejournal";
+       if (Config::get('system', 'nodeinfo')) {
 
-       if (plugin_enabled("libertree"))
-               $nodeinfo["services"]["outbound"][] = "libertree";
+               $nodeinfo['usage']['users'] = array('total' => (int)Config::get('nodeinfo', 'total_users'),
+                                       'activeHalfyear' => (int)Config::get('nodeinfo', 'active_users_halfyear'),
+                                       'activeMonth' => (int)Config::get('nodeinfo', 'active_users_monthly'));
+               $nodeinfo['usage']['localPosts'] = (int)Config::get('nodeinfo', 'local_posts');
+               $nodeinfo['usage']['localComments'] = (int)Config::get('nodeinfo', 'local_comments');
 
-       if (plugin_enabled("buffer"))
-               $nodeinfo["services"]["outbound"][] = "linkedin";
+               if (plugin_enabled('appnet')) {
+                       $nodeinfo['services']['inbound'][] = 'appnet';
+               }
+               if (plugin_enabled('appnet') OR plugin_enabled('buffer')) {
+                       $nodeinfo['services']['outbound'][] = 'appnet';
+               }
+               if (plugin_enabled('blogger')) {
+                       $nodeinfo['services']['outbound'][] = 'blogger';
+               }
+               if (plugin_enabled('dwpost')) {
+                       $nodeinfo['services']['outbound'][] = 'dreamwidth';
+               }
+               if (plugin_enabled('fbpost') OR plugin_enabled('buffer')) {
+                       $nodeinfo['services']['outbound'][] = 'facebook';
+               }
+               if (plugin_enabled('statusnet')) {
+                       $nodeinfo['services']['inbound'][] = 'gnusocial';
+                       $nodeinfo['services']['outbound'][] = 'gnusocial';
+               }
 
-       if (plugin_enabled("ljpost"))
-               $nodeinfo["services"]["outbound"][] = "livejournal";
+               if (plugin_enabled('gpluspost') OR plugin_enabled('buffer')) {
+                       $nodeinfo['services']['outbound'][] = 'google';
+               }
+               if (plugin_enabled('ijpost')) {
+                       $nodeinfo['services']['outbound'][] = 'insanejournal';
+               }
+               if (plugin_enabled('libertree')) {
+                       $nodeinfo['services']['outbound'][] = 'libertree';
+               }
+               if (plugin_enabled('buffer')) {
+                       $nodeinfo['services']['outbound'][] = 'linkedin';
+               }
+               if (plugin_enabled('ljpost')) {
+                       $nodeinfo['services']['outbound'][] = 'livejournal';
+               }
+               if (plugin_enabled('buffer')) {
+                       $nodeinfo['services']['outbound'][] = 'pinterest';
+               }
+               if (plugin_enabled('posterous')) {
+                       $nodeinfo['services']['outbound'][] = 'posterous';
+               }
+               if (plugin_enabled('pumpio')) {
+                       $nodeinfo['services']['inbound'][] = 'pumpio';
+                       $nodeinfo['services']['outbound'][] = 'pumpio';
+               }
 
-       if (plugin_enabled("buffer"))
-               $nodeinfo["services"]["outbound"][] = "pinterest";
+               if ($smtp) {
+                       $nodeinfo['services']['outbound'][] = 'smtp';
+               }
+               if (plugin_enabled('tumblr')) {
+                       $nodeinfo['services']['outbound'][] = 'tumblr';
+               }
+               if (plugin_enabled('twitter') OR plugin_enabled('buffer')) {
+                       $nodeinfo['services']['outbound'][] = 'twitter';
+               }
+               if (plugin_enabled('wppost')) {
+                       $nodeinfo['services']['outbound'][] = 'wordpress';
+               }
+               $nodeinfo['metadata']['protocols'] = $nodeinfo['protocols'];
+               $nodeinfo['metadata']['protocols']['outbound'][] = 'atom1.0';
+               $nodeinfo['metadata']['protocols']['inbound'][] = 'atom1.0';
+               $nodeinfo['metadata']['protocols']['inbound'][] = 'rss2.0';
 
-       if (plugin_enabled("posterous"))
-               $nodeinfo["services"]["outbound"][] = "posterous";
+               $nodeinfo['metadata']['services'] = $nodeinfo['services'];
 
-       if (plugin_enabled("pumpio")) {
-               $nodeinfo["services"]["inbound"][] = "pumpio";
-               $nodeinfo["services"]["outbound"][] = "pumpio";
+               if (plugin_enabled('twitter')) {
+                       $nodeinfo['metadata']['services']['inbound'][] = 'twitter';
+               }
        }
 
-       // redmatrix
-
-       if ($smtp)
-               $nodeinfo["services"]["outbound"][] = "smtp";
-
-       if (plugin_enabled("tumblr"))
-               $nodeinfo["services"]["outbound"][] = "tumblr";
-
-       if (plugin_enabled("twitter") OR plugin_enabled("buffer"))
-               $nodeinfo["services"]["outbound"][] = "twitter";
-
-       if (plugin_enabled("wppost"))
-               $nodeinfo["services"]["outbound"][] = "wordpress";
-
-       $nodeinfo["metadata"]["protocols"] = $nodeinfo["protocols"];
-       $nodeinfo["metadata"]["protocols"]["outbound"][] = "atom1.0";
-       $nodeinfo["metadata"]["protocols"]["inbound"][] = "atom1.0";
-       $nodeinfo["metadata"]["protocols"]["inbound"][] = "rss2.0";
-
-       $nodeinfo["metadata"]["services"] = $nodeinfo["services"];
-
-       if (plugin_enabled("twitter"))
-               $nodeinfo["metadata"]["services"]["inbound"][] = "twitter";
-
        header('Content-type: application/json; charset=utf-8');
        echo json_encode($nodeinfo, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
        exit;
@@ -150,40 +151,40 @@ function nodeinfo_cron() {
 
        $a = get_app();
 
-       // If the plugin "statistics_json" is enabled then disable it and actrivate nodeinfo.
-       if (plugin_enabled("statistics_json")) {
-               set_config("system", "nodeinfo", true);
+       // If the plugin 'statistics_json' is enabled then disable it and actrivate nodeinfo.
+       if (plugin_enabled('statistics_json')) {
+               Config::set('system', 'nodeinfo', true);
 
-               $plugin = "statistics_json";
-               $plugins = get_config("system","addon");
+               $plugin = 'statistics_json';
+               $plugins = Config::get('system', 'addon');
                $plugins_arr = array();
 
-               if($plugins) {
-                       $plugins_arr = explode(",",str_replace(" ", "",$plugins));
+               if ($plugins) {
+                       $plugins_arr = explode(',',str_replace(' ', '',$plugins));
 
                        $idx = array_search($plugin, $plugins_arr);
-                       if ($idx !== false){
+                       if ($idx !== false) {
                                unset($plugins_arr[$idx]);
                                uninstall_plugin($plugin);
-                               set_config("system","addon", implode(", ",$plugins_arr));
+                               Config::set('system', 'addon', implode(', ',$plugins_arr));
                        }
                }
        }
 
-       if (!get_config("system", "nodeinfo"))
+       if (!Config::get('system', 'nodeinfo')) {
                return;
+       }
+       $last = Config::get('nodeinfo', 'last_calucation');
 
-       $last = get_config('nodeinfo','last_calucation');
-
-       if($last) {
+       if ($last) {
                // Calculate every 24 hours
                $next = $last + (24 * 60 * 60);
-               if($next > time()) {
-                       logger("calculation intervall not reached");
+               if ($next > time()) {
+                       logger('calculation intervall not reached');
                        return;
                }
        }
-        logger("cron_start");
+        logger('cron_start');
 
        $users = qu("SELECT `user`.`uid`, `user`.`login_date`, `contact`.`last-item`
                        FROM `user`
@@ -202,31 +203,31 @@ function nodeinfo_cron() {
 
                        foreach ($users AS $user) {
                                if ((strtotime($user['login_date']) > $halfyear) OR
-                                       (strtotime($user['last-item']) > $halfyear))
+                                       (strtotime($user['last-item']) > $halfyear)) {
                                        ++$active_users_halfyear;
-
+                               }
                                if ((strtotime($user['login_date']) > $month) OR
-                                       (strtotime($user['last-item']) > $month))
+                                       (strtotime($user['last-item']) > $month)) {
                                        ++$active_users_monthly;
-
+                               }
                        }
-                       set_config('nodeinfo','total_users', $total_users);
-                       logger("total_users: ".$total_users, LOGGER_DEBUG);
+                       Config::set('nodeinfo', 'total_users', $total_users);
+                       logger('total_users: '.$total_users, LOGGER_DEBUG);
 
-                       set_config('nodeinfo','active_users_halfyear', $active_users_halfyear);
-                       set_config('nodeinfo','active_users_monthly', $active_users_monthly);
+                       Config::set('nodeinfo', 'active_users_halfyear', $active_users_halfyear);
+                       Config::set('nodeinfo', 'active_users_monthly', $active_users_monthly);
        }
 
        $posts = qu("SELECT COUNT(*) AS local_posts FROM `thread` WHERE `thread`.`wall` AND `thread`.`uid` != 0");
 
-       if (!is_array($posts))
+       if (!is_array($posts)) {
                $local_posts = -1;
-       else
-               $local_posts = $posts[0]["local_posts"];
-
-       set_config('nodeinfo','local_posts', $local_posts);
+       } else {
+               $local_posts = $posts[0]['local_posts'];
+       }
+       Config::set('nodeinfo', 'local_posts', $local_posts);
 
-        logger("local_posts: ".$local_posts, LOGGER_DEBUG);
+        logger('local_posts: '.$local_posts, LOGGER_DEBUG);
 
        $posts = qu("SELECT COUNT(*) FROM `contact`
                        INNER JOIN `item` ON `item`.`contact-id` = `contact`.`id` AND `item`.`uid` = `contact`.`uid` AND
@@ -234,21 +235,21 @@ function nodeinfo_cron() {
                        WHERE `contact`.`self`",
                        dbesc(NETWORK_OSTATUS), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_DFRN));
 
-       if (!is_array($posts))
+       if (!is_array($posts)) {
                $local_comments = -1;
-       else
-               $local_comments = $posts[0]["local_comments"];
-
-       set_config('nodeinfo','local_comments', $local_comments);
+       } else {
+               $local_comments = $posts[0]['local_comments'];
+       }
+       Config::set('nodeinfo', 'local_comments', $local_comments);
 
        // Now trying to register
-       $url = "http://the-federation.info/register/".$a->get_hostname();
+       $url = 'http://the-federation.info/register/'.$a->get_hostname();
         logger('registering url: '.$url, LOGGER_DEBUG);
        $ret = fetch_url($url);
         logger('registering answer: '.$ret, LOGGER_DEBUG);
 
-        logger("cron_end");
-       set_config('nodeinfo','last_calucation', time());
+        logger('cron_end');
+       Config::set('nodeinfo', 'last_calucation', time());
 }
 
 ?>
index ec0480022665ea15e98d834faed6d8d3de8aaf16..3091790cb47d82844cb0e0db504c56b21ba81802 100644 (file)
@@ -3,7 +3,7 @@
 # This file is distributed under the same license as the Friendica package.
 # 
 # Translators:
-# Albert, 2016
+# Albert, 2016-2017
 # Albert, 2016
 # Tobias Diekershoff <tobias.diekershoff@gmx.net>, 2011
 # Manuel Pérez <mpmonis@gmail.com>, 2011
@@ -35,8 +35,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: friendica\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-12-19 07:46+0100\n"
-"PO-Revision-Date: 2016-12-28 11:37+0000\n"
+"POT-Creation-Date: 2017-03-20 08:24+0100\n"
+"PO-Revision-Date: 2017-03-26 15:18+0000\n"
 "Last-Translator: Albert\n"
 "Language-Team: Spanish (http://www.transifex.com/Friendica/friendica/language/es/)\n"
 "MIME-Version: 1.0\n"
@@ -45,356 +45,286 @@ msgstr ""
 "Language: es\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: include/contact_widgets.php:6
-msgid "Add New Contact"
-msgstr "Añadir nuevo contacto"
-
-#: include/contact_widgets.php:7
-msgid "Enter address or web location"
-msgstr "Escribe la dirección o página web"
+#: boot.php:976
+msgid "Delete this item?"
+msgstr "¿Eliminar este elemento?"
 
-#: include/contact_widgets.php:8
-msgid "Example: bob@example.com, http://example.com/barbara"
-msgstr "Ejemplo: miguel@ejemplo.com, http://ejemplo.com/miguel"
+#: boot.php:977 include/ForumManager.php:119 include/contact_widgets.php:253
+#: include/items.php:2254 mod/content.php:624 object/Item.php:420
+#: view/theme/vier/theme.php:255
+msgid "show more"
+msgstr "ver más"
 
-#: include/contact_widgets.php:10 include/identity.php:218
-#: mod/allfriends.php:82 mod/dirfind.php:201 mod/match.php:87
-#: mod/suggest.php:101
-msgid "Connect"
-msgstr "Conectar"
+#: boot.php:978
+msgid "show fewer"
+msgstr "ver menos"
 
-#: include/contact_widgets.php:24
+#: boot.php:1667
 #, php-format
-msgid "%d invitation available"
-msgid_plural "%d invitations available"
-msgstr[0] "%d invitación disponible"
-msgstr[1] "%d invitaviones disponibles"
-
-#: include/contact_widgets.php:30
-msgid "Find People"
-msgstr "Buscar personas"
+msgid "Update %s failed. See error logs."
+msgstr "Falló la actualización de %s. Mira los registros de errores."
 
-#: include/contact_widgets.php:31
-msgid "Enter name or interest"
-msgstr "Introduzce nombre o intereses"
+#: boot.php:1779
+msgid "Create a New Account"
+msgstr "Crear una nueva cuenta"
 
-#: include/contact_widgets.php:32 include/Contact.php:354
-#: include/conversation.php:981 mod/allfriends.php:66 mod/dirfind.php:204
-#: mod/match.php:72 mod/suggest.php:83 mod/contacts.php:602 mod/follow.php:103
-msgid "Connect/Follow"
-msgstr "Conectar/Seguir"
+#: boot.php:1780 include/nav.php:109 mod/register.php:289
+msgid "Register"
+msgstr "Registrarse"
 
-#: include/contact_widgets.php:33
-msgid "Examples: Robert Morgenstein, Fishing"
-msgstr "Ejemplos: Robert Morgenstein, Pesca"
+#: boot.php:1804 include/nav.php:78 view/theme/frio/theme.php:243
+msgid "Logout"
+msgstr "Salir"
 
-#: include/contact_widgets.php:34 mod/directory.php:204 mod/contacts.php:798
-msgid "Find"
-msgstr "Buscar"
+#: boot.php:1805 include/nav.php:95 mod/bookmarklet.php:12
+msgid "Login"
+msgstr "Acceder"
 
-#: include/contact_widgets.php:35 mod/suggest.php:114
-#: view/theme/vier/theme.php:203
-msgid "Friend Suggestions"
-msgstr "Sugerencias de amigos"
+#: boot.php:1807 mod/lostpass.php:161
+msgid "Nickname or Email: "
+msgstr "Apodo o Correo electrónico: "
 
-#: include/contact_widgets.php:36 view/theme/vier/theme.php:202
-msgid "Similar Interests"
-msgstr "Intereses similares"
+#: boot.php:1808
+msgid "Password: "
+msgstr "Contraseña: "
 
-#: include/contact_widgets.php:37
-msgid "Random Profile"
-msgstr "Perfil aleatorio"
+#: boot.php:1809
+msgid "Remember me"
+msgstr "Recordarme"
 
-#: include/contact_widgets.php:38 view/theme/vier/theme.php:204
-msgid "Invite Friends"
-msgstr "Invitar amigos"
+#: boot.php:1812
+msgid "Or login using OpenID: "
+msgstr "O inicia sesión usando OpenID: "
 
-#: include/contact_widgets.php:108
-msgid "Networks"
-msgstr "Redes"
+#: boot.php:1818
+msgid "Forgot your password?"
+msgstr "¿Olvidaste la contraseña?"
 
-#: include/contact_widgets.php:111
-msgid "All Networks"
-msgstr "Todas las redes"
+#: boot.php:1819 mod/lostpass.php:110
+msgid "Password Reset"
+msgstr "Restablecer la contraseña"
 
-#: include/contact_widgets.php:141 include/features.php:110
-msgid "Saved Folders"
-msgstr "Directorios guardados"
+#: boot.php:1821
+msgid "Website Terms of Service"
+msgstr "Términos de uso del sitio"
 
-#: include/contact_widgets.php:144 include/contact_widgets.php:176
-msgid "Everything"
-msgstr "Todo"
+#: boot.php:1822
+msgid "terms of service"
+msgstr "Términos de uso"
 
-#: include/contact_widgets.php:173
-msgid "Categories"
-msgstr "Categorías"
+#: boot.php:1824
+msgid "Website Privacy Policy"
+msgstr "Política de privacidad del sitio"
 
-#: include/contact_widgets.php:237
-#, php-format
-msgid "%d contact in common"
-msgid_plural "%d contacts in common"
-msgstr[0] "%d contacto en común"
-msgstr[1] "%d contactos en común"
+#: boot.php:1825
+msgid "privacy policy"
+msgstr "Política de privacidad"
 
-#: include/contact_widgets.php:242 include/ForumManager.php:119
-#: include/items.php:2245 mod/content.php:624 object/Item.php:432
-#: view/theme/vier/theme.php:260 boot.php:972
-msgid "show more"
-msgstr "ver más"
+#: include/Contact.php:387 include/Contact.php:400 include/Contact.php:445
+#: include/conversation.php:970 include/conversation.php:986
+#: mod/allfriends.php:68 mod/directory.php:157 mod/dirfind.php:209
+#: mod/match.php:73 mod/suggest.php:82
+msgid "View Profile"
+msgstr "Ver perfil"
 
-#: include/ForumManager.php:114 include/nav.php:131 include/text.php:1025
-#: view/theme/vier/theme.php:255
-msgid "Forums"
-msgstr "Foros"
+#: include/Contact.php:401 include/contact_widgets.php:32
+#: include/conversation.php:983 mod/allfriends.php:69 mod/contacts.php:610
+#: mod/dirfind.php:210 mod/follow.php:106 mod/match.php:74 mod/suggest.php:83
+msgid "Connect/Follow"
+msgstr "Conectar/Seguir"
 
-#: include/ForumManager.php:116 view/theme/vier/theme.php:257
-msgid "External link to forum"
-msgstr "Enlace externo al foro"
+#: include/Contact.php:444 include/conversation.php:969
+msgid "View Status"
+msgstr "Ver estado"
 
-#: include/profile_selectors.php:6
-msgid "Male"
-msgstr "Hombre"
+#: include/Contact.php:446 include/conversation.php:971
+msgid "View Photos"
+msgstr "Ver fotos"
 
-#: include/profile_selectors.php:6
-msgid "Female"
-msgstr "Mujer"
+#: include/Contact.php:447 include/conversation.php:972
+msgid "Network Posts"
+msgstr "Publicaciones en la red"
 
-#: include/profile_selectors.php:6
-msgid "Currently Male"
-msgstr "Actualmente Hombre"
+#: include/Contact.php:448 include/conversation.php:973
+msgid "View Contact"
+msgstr "Ver contacto"
 
-#: include/profile_selectors.php:6
-msgid "Currently Female"
-msgstr "Actualmente Mujer"
+#: include/Contact.php:449
+msgid "Drop Contact"
+msgstr "Eliminar contacto"
 
-#: include/profile_selectors.php:6
-msgid "Mostly Male"
-msgstr "Mayormente Hombre"
+#: include/Contact.php:450 include/conversation.php:974
+msgid "Send PM"
+msgstr "Enviar mensaje privado"
 
-#: include/profile_selectors.php:6
-msgid "Mostly Female"
-msgstr "Mayormente Mujer"
+#: include/Contact.php:451 include/conversation.php:978
+msgid "Poke"
+msgstr "Toque"
 
-#: include/profile_selectors.php:6
-msgid "Transgender"
-msgstr "Transgenérico"
+#: include/Contact.php:828
+msgid "Organisation"
+msgstr "Organización"
 
-#: include/profile_selectors.php:6
-msgid "Intersex"
-msgstr "Bisexual"
+#: include/Contact.php:831
+msgid "News"
+msgstr "Noticias"
 
-#: include/profile_selectors.php:6
-msgid "Transsexual"
-msgstr "Transexual"
+#: include/Contact.php:834
+msgid "Forum"
+msgstr "Foro"
 
-#: include/profile_selectors.php:6
-msgid "Hermaphrodite"
-msgstr "Hermafrodita"
+#: include/ForumManager.php:114 include/nav.php:131 include/text.php:1027
+#: view/theme/vier/theme.php:250
+msgid "Forums"
+msgstr "Foros"
 
-#: include/profile_selectors.php:6
-msgid "Neuter"
-msgstr "Neutro"
+#: include/ForumManager.php:116 view/theme/vier/theme.php:252
+msgid "External link to forum"
+msgstr "Enlace externo al foro"
 
-#: include/profile_selectors.php:6
-msgid "Non-specific"
-msgstr "Sin especificar"
+#: include/NotificationsManager.php:153
+msgid "System"
+msgstr "Sistema"
 
-#: include/profile_selectors.php:6
-msgid "Other"
-msgstr "Otro"
+#: include/NotificationsManager.php:160 include/nav.php:158 mod/admin.php:421
+#: view/theme/frio/theme.php:253
+msgid "Network"
+msgstr "Red"
 
-#: include/profile_selectors.php:6 include/conversation.php:1487
-msgid "Undecided"
-msgid_plural "Undecided"
-msgstr[0] "Indeciso"
-msgstr[1] "Indeciso"
+#: include/NotificationsManager.php:167 mod/network.php:829
+#: mod/profiles.php:695
+msgid "Personal"
+msgstr "Personal"
 
-#: include/profile_selectors.php:23
-msgid "Males"
-msgstr "Hombres"
+#: include/NotificationsManager.php:174 include/nav.php:105
+#: include/nav.php:161
+msgid "Home"
+msgstr "Inicio"
 
-#: include/profile_selectors.php:23
-msgid "Females"
-msgstr "Mujeres"
+#: include/NotificationsManager.php:181 include/nav.php:166
+msgid "Introductions"
+msgstr "Presentaciones"
 
-#: include/profile_selectors.php:23
-msgid "Gay"
-msgstr "Gay"
+#: include/NotificationsManager.php:239 include/NotificationsManager.php:251
+#, php-format
+msgid "%s commented on %s's post"
+msgstr "%s comentó la publicación de %s"
 
-#: include/profile_selectors.php:23
-msgid "Lesbian"
-msgstr "Lesbiana"
+#: include/NotificationsManager.php:250
+#, php-format
+msgid "%s created a new post"
+msgstr "%s creó una nueva publicación"
 
-#: include/profile_selectors.php:23
-msgid "No Preference"
-msgstr "Sin preferencias"
+#: include/NotificationsManager.php:265
+#, php-format
+msgid "%s liked %s's post"
+msgstr "A %s le gusta la publicación de %s"
 
-#: include/profile_selectors.php:23
-msgid "Bisexual"
-msgstr "Bisexual"
+#: include/NotificationsManager.php:278
+#, php-format
+msgid "%s disliked %s's post"
+msgstr "A %s no le gusta la publicación de %s"
 
-#: include/profile_selectors.php:23
-msgid "Autosexual"
-msgstr "Autosexual"
+#: include/NotificationsManager.php:291
+#, php-format
+msgid "%s is attending %s's event"
+msgstr "%s está asistiendo al evento %s's"
 
-#: include/profile_selectors.php:23
-msgid "Abstinent"
-msgstr "Célibe"
+#: include/NotificationsManager.php:304
+#, php-format
+msgid "%s is not attending %s's event"
+msgstr "%s no está asistiendo al evento %s's"
 
-#: include/profile_selectors.php:23
-msgid "Virgin"
-msgstr "Virgen"
+#: include/NotificationsManager.php:317
+#, php-format
+msgid "%s may attend %s's event"
+msgstr "%s podría asistir al evento %s's"
 
-#: include/profile_selectors.php:23
-msgid "Deviant"
-msgstr "Desviado"
+#: include/NotificationsManager.php:334
+#, php-format
+msgid "%s is now friends with %s"
+msgstr "%s es ahora es amigo de %s"
 
-#: include/profile_selectors.php:23
-msgid "Fetish"
-msgstr "Fetichista"
+#: include/NotificationsManager.php:770
+msgid "Friend Suggestion"
+msgstr "Propuestas de amistad"
 
-#: include/profile_selectors.php:23
-msgid "Oodles"
-msgstr "Orgiástico"
+#: include/NotificationsManager.php:803
+msgid "Friend/Connect Request"
+msgstr "Solicitud de Amistad/Conexión"
 
-#: include/profile_selectors.php:23
-msgid "Nonsexual"
-msgstr "Asexual"
+#: include/NotificationsManager.php:803
+msgid "New Follower"
+msgstr "Nuevo seguidor"
 
-#: include/profile_selectors.php:42
-msgid "Single"
-msgstr "Soltero"
-
-#: include/profile_selectors.php:42
-msgid "Lonely"
-msgstr "Solitario"
-
-#: include/profile_selectors.php:42
-msgid "Available"
-msgstr "Disponible"
-
-#: include/profile_selectors.php:42
-msgid "Unavailable"
-msgstr "No disponible"
-
-#: include/profile_selectors.php:42
-msgid "Has crush"
-msgstr "Enamorado"
-
-#: include/profile_selectors.php:42
-msgid "Infatuated"
-msgstr "Loco/a por alguien"
-
-#: include/profile_selectors.php:42
-msgid "Dating"
-msgstr "De citas"
-
-#: include/profile_selectors.php:42
-msgid "Unfaithful"
-msgstr "Infiel"
-
-#: include/profile_selectors.php:42
-msgid "Sex Addict"
-msgstr "Adicto al sexo"
-
-#: include/profile_selectors.php:42 include/user.php:280 include/user.php:284
-msgid "Friends"
-msgstr "Amigos"
-
-#: include/profile_selectors.php:42
-msgid "Friends/Benefits"
-msgstr "Amigos con beneficios"
-
-#: include/profile_selectors.php:42
-msgid "Casual"
-msgstr "Casual"
-
-#: include/profile_selectors.php:42
-msgid "Engaged"
-msgstr "Comprometido/a"
-
-#: include/profile_selectors.php:42
-msgid "Married"
-msgstr "Casado/a"
-
-#: include/profile_selectors.php:42
-msgid "Imaginarily married"
-msgstr "Casado imaginario"
-
-#: include/profile_selectors.php:42
-msgid "Partners"
-msgstr "Socios"
-
-#: include/profile_selectors.php:42
-msgid "Cohabiting"
-msgstr "Cohabitando"
-
-#: include/profile_selectors.php:42
-msgid "Common law"
-msgstr "Pareja de hecho"
-
-#: include/profile_selectors.php:42
-msgid "Happy"
-msgstr "Feliz"
+#: include/Photo.php:1038 include/Photo.php:1054 include/Photo.php:1062
+#: include/Photo.php:1087 include/message.php:146 mod/item.php:462
+#: mod/wall_upload.php:216 mod/wall_upload.php:230 mod/wall_upload.php:237
+msgid "Wall Photos"
+msgstr "Foto del Muro"
 
-#: include/profile_selectors.php:42
-msgid "Not looking"
-msgstr "No busca relación"
+#: include/acl_selectors.php:341
+msgid "Post to Email"
+msgstr "Publicar mediante correo electrónico"
 
-#: include/profile_selectors.php:42
-msgid "Swinger"
-msgstr "Swinger"
+#: include/acl_selectors.php:346
+#, php-format
+msgid "Connectors disabled, since \"%s\" is enabled."
+msgstr "Conectores deshabilitados, ya que \"%s\" es habilitado."
 
-#: include/profile_selectors.php:42
-msgid "Betrayed"
-msgstr "Traicionado/a"
+#: include/acl_selectors.php:347 mod/settings.php:1188
+msgid "Hide your profile details from unknown viewers?"
+msgstr "¿Quieres que los detalles de tu perfil permanezcan ocultos a los desconocidos?"
 
-#: include/profile_selectors.php:42
-msgid "Separated"
-msgstr "Separado/a"
+#: include/acl_selectors.php:352
+msgid "Visible to everybody"
+msgstr "Visible para cualquiera"
 
-#: include/profile_selectors.php:42
-msgid "Unstable"
-msgstr "Inestable"
+#: include/acl_selectors.php:353 view/theme/vier/config.php:108
+msgid "show"
+msgstr "mostrar"
 
-#: include/profile_selectors.php:42
-msgid "Divorced"
-msgstr "Divorciado/a"
+#: include/acl_selectors.php:354 view/theme/vier/config.php:108
+msgid "don't show"
+msgstr "no mostrar"
 
-#: include/profile_selectors.php:42
-msgid "Imaginarily divorced"
-msgstr "Divorciado imaginario"
+#: include/acl_selectors.php:360 mod/editpost.php:123
+msgid "CC: email addresses"
+msgstr "CC: dirección de correo electrónico"
 
-#: include/profile_selectors.php:42
-msgid "Widowed"
-msgstr "Viudo/a"
+#: include/acl_selectors.php:361 mod/editpost.php:130
+msgid "Example: bob@example.com, mary@example.com"
+msgstr "Ejemplo: juan@ejemplo.com, sofia@ejemplo.com"
 
-#: include/profile_selectors.php:42
-msgid "Uncertain"
-msgstr "Incierto"
+#: include/acl_selectors.php:363 mod/events.php:516 mod/photos.php:1176
+#: mod/photos.php:1558
+msgid "Permissions"
+msgstr "Permisos"
 
-#: include/profile_selectors.php:42
-msgid "It's complicated"
-msgstr "Es complicado"
+#: include/acl_selectors.php:364
+msgid "Close"
+msgstr "Cerrado"
 
-#: include/profile_selectors.php:42
-msgid "Don't care"
-msgstr "No te importa"
+#: include/api.php:1021
+#, php-format
+msgid "Daily posting limit of %d posts reached. The post was rejected."
+msgstr "Limite diario de publicaciones %d alcanzado. La publicación fue rechazada."
 
-#: include/profile_selectors.php:42
-msgid "Ask me"
-msgstr "Pregúntame"
+#: include/api.php:1041
+#, php-format
+msgid "Weekly posting limit of %d posts reached. The post was rejected."
+msgstr "Limite semanal de publicaciones %d alcanzado. La publicación fue rechazada."
 
-#: include/dba_pdo.php:72 include/dba.php:56
+#: include/api.php:1062
 #, php-format
-msgid "Cannot locate DNS info for database server '%s'"
-msgstr "No se puede encontrar información DNS para la base de datos del servidor '%s'"
+msgid "Monthly posting limit of %d posts reached. The post was rejected."
+msgstr "Limite mensual de publicaciones %d alcanzado. La publicación fue rechazada."
 
 #: include/auth.php:45
 msgid "Logged out."
 msgstr "Sesión finalizada"
 
-#: include/auth.php:116 include/auth.php:178 mod/openid.php:100
+#: include/auth.php:116 include/auth.php:178 mod/openid.php:110
 msgid "Login failed."
 msgstr "Accesso fallido."
 
@@ -408,52 +338,50 @@ msgstr "Se ha encontrado un problema para acceder con el OpenID que has escrito.
 msgid "The error message was:"
 msgstr "El mensaje del error fue:"
 
-#: include/group.php:25
-msgid ""
-"A deleted group with this name was revived. Existing item permissions "
-"<strong>may</strong> apply to this group and any future members. If this is "
-"not what you intended, please create another group with a different name."
-msgstr "Un grupo eliminado con este nombre fue restablecido. Los permisos existentes <strong>pueden</strong> aplicarse a este grupo y a sus futuros miembros. Si esto no es lo que pretendes, por favor, crea otro grupo con un nombre diferente."
-
-#: include/group.php:209
-msgid "Default privacy group for new contacts"
-msgstr "Grupo por defecto para nuevos contactos"
+#: include/bb2diaspora.php:199 include/event.php:16 mod/localtime.php:12
+msgid "l F d, Y \\@ g:i A"
+msgstr "l F d, Y \\@ g:i A"
 
-#: include/group.php:242
-msgid "Everybody"
-msgstr "Todo el mundo"
+#: include/bb2diaspora.php:205 include/event.php:33 include/event.php:51
+#: include/event.php:488
+msgid "Starts:"
+msgstr "Inicio:"
 
-#: include/group.php:265
-msgid "edit"
-msgstr "editar"
+#: include/bb2diaspora.php:213 include/event.php:36 include/event.php:57
+#: include/event.php:489
+msgid "Finishes:"
+msgstr "Final:"
 
-#: include/group.php:286 mod/newmember.php:61
-msgid "Groups"
-msgstr "Grupos"
+#: include/bb2diaspora.php:221 include/event.php:39 include/event.php:63
+#: include/event.php:490 include/identity.php:331 mod/contacts.php:636
+#: mod/directory.php:139 mod/events.php:501 mod/notifications.php:238
+msgid "Location:"
+msgstr "Localización:"
 
-#: include/group.php:288
-msgid "Edit groups"
-msgstr "Editar grupo"
+#: include/bbcode.php:350 include/bbcode.php:1055 include/bbcode.php:1056
+msgid "Image/photo"
+msgstr "Imagen/Foto"
 
-#: include/group.php:290
-msgid "Edit group"
-msgstr "Editar grupo"
+#: include/bbcode.php:467
+#, php-format
+msgid "<a href=\"%1$s\" target=\"_blank\">%2$s</a> %3$s"
+msgstr "<a href=\"%1$s\" target=\"_blank\">%2$s</a> %3$s"
 
-#: include/group.php:291
-msgid "Create a new group"
-msgstr "Crear un nuevo grupo"
+#: include/bbcode.php:1015 include/bbcode.php:1035
+msgid "$1 wrote:"
+msgstr "$1 escribió:"
 
-#: include/group.php:292 mod/group.php:94 mod/group.php:178
-msgid "Group Name: "
-msgstr "Nombre del grupo: "
+#: include/bbcode.php:1064 include/bbcode.php:1065
+msgid "Encrypted content"
+msgstr "Contenido cifrado"
 
-#: include/group.php:294
-msgid "Contacts not in any group"
-msgstr "Contactos sin grupo"
+#: include/bbcode.php:1169
+msgid "Invalid source protocol"
+msgstr "Protocolo de fuente inválido"
 
-#: include/group.php:296 mod/network.php:201
-msgid "add"
-msgstr "añadir"
+#: include/bbcode.php:1179
+msgid "Invalid link protocol"
+msgstr "Protocolo de enlace inválido"
 
 #: include/contact_selectors.php:32
 msgid "Unknown | Not categorised"
@@ -479,19 +407,19 @@ msgstr "OK, probablemente inofensivo"
 msgid "Reputable, has my trust"
 msgstr "Buena reputación, tiene mi confianza"
 
-#: include/contact_selectors.php:56 mod/admin.php:890
+#: include/contact_selectors.php:56 mod/admin.php:893
 msgid "Frequently"
 msgstr "Frequentemente"
 
-#: include/contact_selectors.php:57 mod/admin.php:891
+#: include/contact_selectors.php:57 mod/admin.php:894
 msgid "Hourly"
 msgstr "Cada hora"
 
-#: include/contact_selectors.php:58 mod/admin.php:892
+#: include/contact_selectors.php:58 mod/admin.php:895
 msgid "Twice daily"
 msgstr "Dos veces al día"
 
-#: include/contact_selectors.php:59 mod/admin.php:893
+#: include/contact_selectors.php:59 mod/admin.php:896
 msgid "Daily"
 msgstr "Diariamente"
 
@@ -503,7 +431,7 @@ msgstr "Semanalmente"
 msgid "Monthly"
 msgstr "Mensualmente"
 
-#: include/contact_selectors.php:76 mod/dfrn_request.php:868
+#: include/contact_selectors.php:76 mod/dfrn_request.php:881
 msgid "Friendica"
 msgstr "Friendica"
 
@@ -516,12 +444,12 @@ msgid "RSS/Atom"
 msgstr "RSS/Atom"
 
 #: include/contact_selectors.php:79 include/contact_selectors.php:86
-#: mod/admin.php:1396 mod/admin.php:1409 mod/admin.php:1422 mod/admin.php:1440
+#: mod/admin.php:1405 mod/admin.php:1418 mod/admin.php:1431 mod/admin.php:1449
 msgid "Email"
 msgstr "Correo electrónico"
 
-#: include/contact_selectors.php:80 mod/settings.php:842
-#: mod/dfrn_request.php:870
+#: include/contact_selectors.php:80 mod/dfrn_request.php:883
+#: mod/settings.php:848
 msgid "Diaspora"
 msgstr "Diaspora*"
 
@@ -566,2216 +494,2307 @@ msgid "GNU Social"
 msgstr "GNUsocial (OStatus)"
 
 #: include/contact_selectors.php:92
+msgid "pnut"
+msgstr "pnut"
+
+#: include/contact_selectors.php:93
 msgid "App.net"
 msgstr "App.net"
 
-#: include/contact_selectors.php:103
+#: include/contact_selectors.php:104
 msgid "Hubzilla/Redmatrix"
 msgstr "Hubzilla/Redmatrix"
 
-#: include/acl_selectors.php:327
-msgid "Post to Email"
-msgstr "Publicar mediante correo electrónico"
+#: include/contact_widgets.php:6
+msgid "Add New Contact"
+msgstr "Añadir nuevo contacto"
 
-#: include/acl_selectors.php:332
-#, php-format
-msgid "Connectors disabled, since \"%s\" is enabled."
-msgstr "Conectores deshabilitados, ya que \"%s\" es habilitado."
+#: include/contact_widgets.php:7
+msgid "Enter address or web location"
+msgstr "Escribe la dirección o página web"
 
-#: include/acl_selectors.php:333 mod/settings.php:1181
-msgid "Hide your profile details from unknown viewers?"
-msgstr "¿Quieres que los detalles de tu perfil permanezcan ocultos a los desconocidos?"
+#: include/contact_widgets.php:8
+msgid "Example: bob@example.com, http://example.com/barbara"
+msgstr "Ejemplo: miguel@ejemplo.com, http://ejemplo.com/miguel"
 
-#: include/acl_selectors.php:338
-msgid "Visible to everybody"
-msgstr "Visible para cualquiera"
+#: include/contact_widgets.php:10 include/identity.php:219
+#: mod/allfriends.php:85 mod/dirfind.php:207 mod/match.php:89
+#: mod/suggest.php:101
+msgid "Connect"
+msgstr "Conectar"
 
-#: include/acl_selectors.php:339 view/theme/vier/config.php:103
-msgid "show"
-msgstr "mostrar"
+#: include/contact_widgets.php:24
+#, php-format
+msgid "%d invitation available"
+msgid_plural "%d invitations available"
+msgstr[0] "%d invitación disponible"
+msgstr[1] "%d invitaviones disponibles"
 
-#: include/acl_selectors.php:340 view/theme/vier/config.php:103
-msgid "don't show"
-msgstr "no mostrar"
+#: include/contact_widgets.php:30
+msgid "Find People"
+msgstr "Buscar personas"
 
-#: include/acl_selectors.php:346 mod/editpost.php:133
-msgid "CC: email addresses"
-msgstr "CC: dirección de correo electrónico"
+#: include/contact_widgets.php:31
+msgid "Enter name or interest"
+msgstr "Introduzce nombre o intereses"
 
-#: include/acl_selectors.php:347 mod/editpost.php:140
-msgid "Example: bob@example.com, mary@example.com"
-msgstr "Ejemplo: juan@ejemplo.com, sofia@ejemplo.com"
+#: include/contact_widgets.php:33
+msgid "Examples: Robert Morgenstein, Fishing"
+msgstr "Ejemplos: Robert Morgenstein, Pesca"
 
-#: include/acl_selectors.php:349 mod/events.php:509 mod/photos.php:1156
-#: mod/photos.php:1535
-msgid "Permissions"
-msgstr "Permisos"
+#: include/contact_widgets.php:34 mod/contacts.php:806 mod/directory.php:206
+msgid "Find"
+msgstr "Buscar"
 
-#: include/acl_selectors.php:350
-msgid "Close"
-msgstr "Cerrado"
+#: include/contact_widgets.php:35 mod/suggest.php:114
+#: view/theme/vier/theme.php:198
+msgid "Friend Suggestions"
+msgstr "Sugerencias de amigos"
 
-#: include/like.php:163 include/conversation.php:130
-#: include/conversation.php:266 include/text.php:1804 mod/subthread.php:87
-#: mod/tagger.php:62
-msgid "photo"
-msgstr "foto"
+#: include/contact_widgets.php:36 view/theme/vier/theme.php:197
+msgid "Similar Interests"
+msgstr "Intereses similares"
 
-#: include/like.php:163 include/diaspora.php:1406 include/conversation.php:125
-#: include/conversation.php:134 include/conversation.php:261
-#: include/conversation.php:270 mod/subthread.php:87 mod/tagger.php:62
-msgid "status"
-msgstr "estado"
+#: include/contact_widgets.php:37
+msgid "Random Profile"
+msgstr "Perfil aleatorio"
+
+#: include/contact_widgets.php:38 view/theme/vier/theme.php:199
+msgid "Invite Friends"
+msgstr "Invitar amigos"
+
+#: include/contact_widgets.php:115
+msgid "Networks"
+msgstr "Redes"
+
+#: include/contact_widgets.php:118
+msgid "All Networks"
+msgstr "Todas las redes"
+
+#: include/contact_widgets.php:150 include/features.php:104
+msgid "Saved Folders"
+msgstr "Directorios guardados"
 
-#: include/like.php:165 include/conversation.php:122
-#: include/conversation.php:258 include/text.php:1802
+#: include/contact_widgets.php:153 include/contact_widgets.php:187
+msgid "Everything"
+msgstr "Todo"
+
+#: include/contact_widgets.php:184
+msgid "Categories"
+msgstr "Categorías"
+
+#: include/contact_widgets.php:248
+#, php-format
+msgid "%d contact in common"
+msgid_plural "%d contacts in common"
+msgstr[0] "%d contacto en común"
+msgstr[1] "%d contactos en común"
+
+#: include/conversation.php:122 include/conversation.php:258
+#: include/like.php:180 include/text.php:1804
 msgid "event"
 msgstr "evento"
 
-#: include/like.php:182 include/diaspora.php:1402 include/conversation.php:141
+#: include/conversation.php:125 include/conversation.php:134
+#: include/conversation.php:261 include/conversation.php:270
+#: include/diaspora.php:1530 include/like.php:178 mod/subthread.php:88
+#: mod/tagger.php:62
+msgid "status"
+msgstr "estado"
+
+#: include/conversation.php:130 include/conversation.php:266
+#: include/like.php:178 include/text.php:1806 mod/subthread.php:88
+#: mod/tagger.php:62
+msgid "photo"
+msgstr "foto"
+
+#: include/conversation.php:141 include/diaspora.php:1526 include/like.php:27
 #, php-format
 msgid "%1$s likes %2$s's %3$s"
 msgstr "A %1$s le gusta %3$s de %2$s"
 
-#: include/like.php:184 include/conversation.php:144
+#: include/conversation.php:144 include/like.php:31 include/like.php:36
 #, php-format
 msgid "%1$s doesn't like %2$s's %3$s"
 msgstr "A %1$s no le gusta %3$s de %2$s"
 
-#: include/like.php:186
+#: include/conversation.php:147
 #, php-format
-msgid "%1$s is attending %2$s's %3$s"
+msgid "%1$s attends %2$s's %3$s"
 msgstr "%1$s atenderá %2$s's %3$s"
 
-#: include/like.php:188
+#: include/conversation.php:150
 #, php-format
-msgid "%1$s is not attending %2$s's %3$s"
+msgid "%1$s doesn't attend %2$s's %3$s"
 msgstr "%1$s no atenderá %2$s's %3$s"
 
-#: include/like.php:190
+#: include/conversation.php:153
 #, php-format
-msgid "%1$s may attend %2$s's %3$s"
-msgstr "%1$s puede que atienda %2$s's %3$s"
-
-#: include/message.php:15 include/message.php:173
-msgid "[no subject]"
-msgstr "[sin asunto]"
-
-#: include/message.php:145 include/Photo.php:1040 include/Photo.php:1056
-#: include/Photo.php:1064 include/Photo.php:1089 mod/wall_upload.php:218
-#: mod/wall_upload.php:232 mod/wall_upload.php:239 mod/item.php:478
-msgid "Wall Photos"
-msgstr "Foto del Muro"
-
-#: include/plugin.php:526 include/plugin.php:528
-msgid "Click here to upgrade."
-msgstr "Pulsa aquí para actualizar."
-
-#: include/plugin.php:534
-msgid "This action exceeds the limits set by your subscription plan."
-msgstr "Esta acción excede los límites permitidos por tu subscripción."
-
-#: include/plugin.php:539
-msgid "This action is not available under your subscription plan."
-msgstr "Esta acción no está permitida para tu subscripción."
-
-#: include/uimport.php:94
-msgid "Error decoding account file"
-msgstr "Error decodificando el archivo de cuenta"
-
-#: include/uimport.php:100
-msgid "Error! No version data in file! This is not a Friendica account file?"
-msgstr "Error! No hay datos de versión en el archivo! ¿Es esto de una cuenta friendica? "
-
-#: include/uimport.php:116 include/uimport.php:127
-msgid "Error! Cannot check nickname"
-msgstr "Error! No puedo consultar el apodo"
+msgid "%1$s attends maybe %2$s's %3$s"
+msgstr "%1$s atenderá quizás %2$s's %3$s"
 
-#: include/uimport.php:120 include/uimport.php:131
+#: include/conversation.php:185 mod/dfrn_confirm.php:478
 #, php-format
-msgid "User '%s' already exists on this server!"
-msgstr "La cuenta '%s' ya existe en este servidor!"
-
-#: include/uimport.php:153
-msgid "User creation error"
-msgstr "Error al crear la cuenta"
+msgid "%1$s is now friends with %2$s"
+msgstr "%1$s ahora es amigo de %2$s"
 
-#: include/uimport.php:173
-msgid "User profile creation error"
-msgstr "Error de creación del perfil de la cuenta"
+#: include/conversation.php:219
+#, php-format
+msgid "%1$s poked %2$s"
+msgstr "%1$s le dio un toque a %2$s"
 
-#: include/uimport.php:222
+#: include/conversation.php:239 mod/mood.php:63
 #, php-format
-msgid "%d contact not imported"
-msgid_plural "%d contacts not imported"
-msgstr[0] "%d contactos no encontrado"
-msgstr[1] "%d contactos no importado"
+msgid "%1$s is currently %2$s"
+msgstr "%1$s está actualmente %2$s"
 
-#: include/uimport.php:292
-msgid "Done. You can now login with your username and password"
-msgstr "Hecho. Ahora podes ingresar con tu nombre de cuenta y la contraseña."
+#: include/conversation.php:278 mod/tagger.php:95
+#, php-format
+msgid "%1$s tagged %2$s's %3$s with %4$s"
+msgstr "%1$s ha etiquetado el %3$s de %2$s con %4$s"
 
-#: include/datetime.php:57 include/datetime.php:59 mod/profiles.php:705
-msgid "Miscellaneous"
-msgstr "Varios"
+#: include/conversation.php:303
+msgid "post/item"
+msgstr "publicación/tema"
 
-#: include/datetime.php:183 include/identity.php:629
-msgid "Birthday:"
-msgstr "Fecha de nacimiento:"
+#: include/conversation.php:304
+#, php-format
+msgid "%1$s marked %2$s's %3$s as favorite"
+msgstr "%1$s ha marcado %3$s de %2$s como Favorito"
 
-#: include/datetime.php:185 mod/profiles.php:728
-msgid "Age: "
-msgstr "Edad: "
+#: include/conversation.php:587 mod/content.php:372 mod/photos.php:1629
+#: mod/profiles.php:346
+msgid "Likes"
+msgstr "Me gusta"
 
-#: include/datetime.php:187
-msgid "YYYY-MM-DD or MM-DD"
-msgstr "YYYY-MM-DD o MM-DD"
+#: include/conversation.php:587 mod/content.php:372 mod/photos.php:1629
+#: mod/profiles.php:350
+msgid "Dislikes"
+msgstr "No me gusta"
 
-#: include/datetime.php:341
-msgid "never"
-msgstr "nunca"
+#: include/conversation.php:588 include/conversation.php:1473
+#: mod/content.php:373 mod/photos.php:1630
+msgid "Attending"
+msgid_plural "Attending"
+msgstr[0] "Atendiendo"
+msgstr[1] "Atendiendo"
 
-#: include/datetime.php:347
-msgid "less than a second ago"
-msgstr "hace menos de un segundo"
+#: include/conversation.php:588 mod/content.php:373 mod/photos.php:1630
+msgid "Not attending"
+msgstr "No atendiendo"
 
-#: include/datetime.php:350
-msgid "year"
-msgstr "año"
+#: include/conversation.php:588 mod/content.php:373 mod/photos.php:1630
+msgid "Might attend"
+msgstr "Puede que atienda"
 
-#: include/datetime.php:350
-msgid "years"
-msgstr "años"
+#: include/conversation.php:710 mod/content.php:453 mod/content.php:759
+#: mod/photos.php:1703 object/Item.php:137
+msgid "Select"
+msgstr "Seleccionar"
 
-#: include/datetime.php:351 include/event.php:480 mod/cal.php:284
-#: mod/events.php:389
-msgid "month"
-msgstr "mes"
+#: include/conversation.php:711 mod/admin.php:1423 mod/contacts.php:816
+#: mod/contacts.php:1015 mod/content.php:454 mod/content.php:760
+#: mod/group.php:181 mod/photos.php:1704 mod/settings.php:744
+#: object/Item.php:138
+msgid "Delete"
+msgstr "Eliminar"
 
-#: include/datetime.php:351
-msgid "months"
-msgstr "meses"
+#: include/conversation.php:755 mod/content.php:487 mod/content.php:915
+#: mod/content.php:916 object/Item.php:356 object/Item.php:357
+#, php-format
+msgid "View %s's profile @ %s"
+msgstr "Ver perfil de %s @ %s"
 
-#: include/datetime.php:352 include/event.php:481 mod/cal.php:285
-#: mod/events.php:390
-msgid "week"
-msgstr "semana"
+#: include/conversation.php:767 object/Item.php:344
+msgid "Categories:"
+msgstr "Categorías:"
 
-#: include/datetime.php:352
-msgid "weeks"
-msgstr "semanas"
+#: include/conversation.php:768 object/Item.php:345
+msgid "Filed under:"
+msgstr "Archivado en:"
 
-#: include/datetime.php:353 include/event.php:482 mod/cal.php:286
-#: mod/events.php:391
-msgid "day"
-msgstr "día"
+#: include/conversation.php:775 mod/content.php:497 mod/content.php:928
+#: object/Item.php:370
+#, php-format
+msgid "%s from %s"
+msgstr "%s de %s"
 
-#: include/datetime.php:353
-msgid "days"
-msgstr "días"
+#: include/conversation.php:791 mod/content.php:513
+msgid "View in context"
+msgstr "Verlo en contexto"
 
-#: include/datetime.php:354
-msgid "hour"
-msgstr "hora"
+#: include/conversation.php:793 include/conversation.php:1256
+#: mod/content.php:515 mod/content.php:953 mod/editpost.php:114
+#: mod/message.php:337 mod/message.php:522 mod/photos.php:1592
+#: mod/wallmessage.php:140 object/Item.php:395
+msgid "Please wait"
+msgstr "Por favor, espera"
 
-#: include/datetime.php:354
-msgid "hours"
-msgstr "horas"
+#: include/conversation.php:872
+msgid "remove"
+msgstr "eliminar"
 
-#: include/datetime.php:355
-msgid "minute"
-msgstr "minuto"
+#: include/conversation.php:876
+msgid "Delete Selected Items"
+msgstr "Eliminar el elemento seleccionado"
 
-#: include/datetime.php:355
-msgid "minutes"
-msgstr "minutos"
+#: include/conversation.php:968
+msgid "Follow Thread"
+msgstr "Seguir publicacion"
 
-#: include/datetime.php:356
-msgid "second"
-msgstr "segundo"
+#: include/conversation.php:1100
+#, php-format
+msgid "%s likes this."
+msgstr "A %s le gusta esto."
 
-#: include/datetime.php:356
-msgid "seconds"
-msgstr "segundos"
+#: include/conversation.php:1103
+#, php-format
+msgid "%s doesn't like this."
+msgstr "A %s no le gusta esto."
 
-#: include/datetime.php:365
+#: include/conversation.php:1106
 #, php-format
-msgid "%1$d %2$s ago"
-msgstr "hace %1$d %2$s"
+msgid "%s attends."
+msgstr "%s atiende."
 
-#: include/datetime.php:572
+#: include/conversation.php:1109
 #, php-format
-msgid "%s's birthday"
-msgstr "Cumpleaños de %s"
+msgid "%s doesn't attend."
+msgstr "%s no atenderá."
 
-#: include/datetime.php:573 include/dfrn.php:1109
+#: include/conversation.php:1112
 #, php-format
-msgid "Happy Birthday %s"
-msgstr "Feliz cumpleaños %s"
+msgid "%s attends maybe."
+msgstr "%s quizás atenderá"
 
-#: include/enotify.php:24
-msgid "Friendica Notification"
-msgstr "Notificación de Friendica"
+#: include/conversation.php:1122
+msgid "and"
+msgstr "y"
 
-#: include/enotify.php:27
-msgid "Thank You,"
-msgstr "Gracias,"
+#: include/conversation.php:1128
+#, php-format
+msgid ", and %d other people"
+msgstr " y a otras %d personas"
 
-#: include/enotify.php:30
+#: include/conversation.php:1137
 #, php-format
-msgid "%s Administrator"
-msgstr "%s Administrador"
+msgid "<span  %1$s>%2$d people</span> like this"
+msgstr "<span  %1$s>%2$d personas</span> les gusta esto"
 
-#: include/enotify.php:32
+#: include/conversation.php:1138
 #, php-format
-msgid "%1$s, %2$s Administrator"
-msgstr "%1$s, %2$s Administrador"
+msgid "%s like this."
+msgstr "A %s le gusta esto."
 
-#: include/enotify.php:43 include/delivery.php:457
-msgid "noreply"
-msgstr "no responder"
+#: include/conversation.php:1141
+#, php-format
+msgid "<span  %1$s>%2$d people</span> don't like this"
+msgstr "<span  %1$s>%2$d personas</span> no les gusta esto"
 
-#: include/enotify.php:70
+#: include/conversation.php:1142
 #, php-format
-msgid "%s <!item_type!>"
-msgstr "%s <!item_type!>"
+msgid "%s don't like this."
+msgstr "A %s no le gusta esto."
 
-#: include/enotify.php:83
+#: include/conversation.php:1145
 #, php-format
-msgid "[Friendica:Notify] New mail received at %s"
-msgstr "[Friendica:Notificación] Nuevo correo recibido de %s"
+msgid "<span  %1$s>%2$d people</span> attend"
+msgstr "<span  %1$s>%2$d personas</span> atienden"
 
-#: include/enotify.php:85
+#: include/conversation.php:1146
 #, php-format
-msgid "%1$s sent you a new private message at %2$s."
-msgstr "%1$s te ha enviado un mensaje privado desde %2$s."
+msgid "%s attend."
+msgstr "%s atiende."
 
-#: include/enotify.php:86
+#: include/conversation.php:1149
 #, php-format
-msgid "%1$s sent you %2$s."
-msgstr "%1$s te ha enviado %2$s."
-
-#: include/enotify.php:86
-msgid "a private message"
-msgstr "un mensaje privado"
+msgid "<span  %1$s>%2$d people</span> don't attend"
+msgstr "<span  %1$s>%2$d personas</span>no atienden"
 
-#: include/enotify.php:88
+#: include/conversation.php:1150
 #, php-format
-msgid "Please visit %s to view and/or reply to your private messages."
-msgstr "Por favor, visita %s para ver y/o responder a tus mensajes privados."
+msgid "%s don't attend."
+msgstr "%s no atiende."
 
-#: include/enotify.php:134
+#: include/conversation.php:1153
 #, php-format
-msgid "%1$s commented on [url=%2$s]a %3$s[/url]"
-msgstr "%1$s comentó en [url=%2$s]a %3$s[/url]"
+msgid "<span  %1$s>%2$d people</span> attend maybe"
+msgstr "<span  %1$s>%2$d people</span> quizá asistan"
 
-#: include/enotify.php:141
+#: include/conversation.php:1154
 #, php-format
-msgid "%1$s commented on [url=%2$s]%3$s's %4$s[/url]"
-msgstr "%1$s comentó en [url=%2$s] %4$s de %3$s[/url]"
+msgid "%s anttend maybe."
+msgstr "%s atiende quizás."
 
-#: include/enotify.php:149
-#, php-format
-msgid "%1$s commented on [url=%2$s]your %3$s[/url]"
-msgstr "%1$s comentó en [url=%2$s] tu %3$s[/url]"
+#: include/conversation.php:1184 include/conversation.php:1200
+msgid "Visible to <strong>everybody</strong>"
+msgstr "Visible para <strong>cualquiera</strong>"
 
-#: include/enotify.php:159
-#, php-format
-msgid "[Friendica:Notify] Comment to conversation #%1$d by %2$s"
-msgstr "[Friendica:Notificación] Comentario en la conversación de #%1$d por %2$s"
+#: include/conversation.php:1185 include/conversation.php:1201
+#: mod/message.php:271 mod/message.php:278 mod/message.php:418
+#: mod/message.php:425 mod/wallmessage.php:114 mod/wallmessage.php:121
+msgid "Please enter a link URL:"
+msgstr "Introduce la dirección del enlace:"
 
-#: include/enotify.php:161
-#, php-format
-msgid "%s commented on an item/conversation you have been following."
-msgstr "%s ha comentado en una conversación/elemento que sigues."
+#: include/conversation.php:1186 include/conversation.php:1202
+msgid "Please enter a video link/URL:"
+msgstr "Por favor, introduce la URL/enlace del vídeo:"
 
-#: include/enotify.php:164 include/enotify.php:178 include/enotify.php:192
-#: include/enotify.php:206 include/enotify.php:224 include/enotify.php:238
-#, php-format
-msgid "Please visit %s to view and/or reply to the conversation."
-msgstr "Por favor, visita %s para ver y/o responder a la conversación."
+#: include/conversation.php:1187 include/conversation.php:1203
+msgid "Please enter an audio link/URL:"
+msgstr "Por favor, introduce la URL/enlace del audio:"
 
-#: include/enotify.php:171
-#, php-format
-msgid "[Friendica:Notify] %s posted to your profile wall"
-msgstr "[Friendica:Notificación] %s publicó en tu muro"
+#: include/conversation.php:1188 include/conversation.php:1204
+msgid "Tag term:"
+msgstr "Etiquetar:"
 
-#: include/enotify.php:173
-#, php-format
-msgid "%1$s posted to your profile wall at %2$s"
-msgstr "%1$s publicó en tu perfil de %2$s"
+#: include/conversation.php:1189 include/conversation.php:1205
+#: mod/filer.php:30
+msgid "Save to Folder:"
+msgstr "Guardar en directorio:"
 
-#: include/enotify.php:174
-#, php-format
-msgid "%1$s posted to [url=%2$s]your wall[/url]"
-msgstr "%1$s publicó en [url=%2$s]tu muro[/url]"
+#: include/conversation.php:1190 include/conversation.php:1206
+msgid "Where are you right now?"
+msgstr "¿Dónde estás ahora?"
 
-#: include/enotify.php:185
-#, php-format
-msgid "[Friendica:Notify] %s tagged you"
-msgstr "[Friendica:Notificación] %s te ha nombrado"
+#: include/conversation.php:1191
+msgid "Delete item(s)?"
+msgstr "¿Borrar objeto(s)?"
 
-#: include/enotify.php:187
-#, php-format
-msgid "%1$s tagged you at %2$s"
-msgstr "%1$s te ha nombrado en %2$s"
+#: include/conversation.php:1237
+msgid "Share"
+msgstr "Compartir"
 
-#: include/enotify.php:188
-#, php-format
-msgid "%1$s [url=%2$s]tagged you[/url]."
-msgstr "%1$s [url=%2$s]te nombró[/url]."
+#: include/conversation.php:1238 mod/editpost.php:100 mod/message.php:335
+#: mod/message.php:519 mod/wallmessage.php:138
+msgid "Upload photo"
+msgstr "Subir foto"
 
-#: include/enotify.php:199
-#, php-format
-msgid "[Friendica:Notify] %s shared a new post"
-msgstr "[Notificacion Friendica] %s compartio una nueva publicacion"
+#: include/conversation.php:1239 mod/editpost.php:101
+msgid "upload photo"
+msgstr "subir imagen"
 
-#: include/enotify.php:201
-#, php-format
-msgid "%1$s shared a new post at %2$s"
-msgstr "%1$s compartió un nuevo tema en %2$s"
+#: include/conversation.php:1240 mod/editpost.php:102
+msgid "Attach file"
+msgstr "Adjuntar archivo"
 
-#: include/enotify.php:202
-#, php-format
-msgid "%1$s [url=%2$s]shared a post[/url]."
-msgstr "%1$s [url=%2$s]compartió una publicación[/url]."
+#: include/conversation.php:1241 mod/editpost.php:103
+msgid "attach file"
+msgstr "adjuntar archivo"
 
-#: include/enotify.php:213
-#, php-format
-msgid "[Friendica:Notify] %1$s poked you"
-msgstr "[Friendica:Notify] %1$s te dio un toque"
+#: include/conversation.php:1242 mod/editpost.php:104 mod/message.php:336
+#: mod/message.php:520 mod/wallmessage.php:139
+msgid "Insert web link"
+msgstr "Insertar enlace"
 
-#: include/enotify.php:215
-#, php-format
-msgid "%1$s poked you at %2$s"
-msgstr "%1$s te dio un toque en %2$s"
+#: include/conversation.php:1243 mod/editpost.php:105
+msgid "web link"
+msgstr "enlace web"
 
-#: include/enotify.php:216
-#, php-format
-msgid "%1$s [url=%2$s]poked you[/url]."
-msgstr "%1$s [url=%2$s]te dio un toque[/url]."
+#: include/conversation.php:1244 mod/editpost.php:106
+msgid "Insert video link"
+msgstr "Insertar enlace del vídeo"
 
-#: include/enotify.php:231
-#, php-format
-msgid "[Friendica:Notify] %s tagged your post"
-msgstr "[Friendica:Notificación] %s ha etiquetado tu publicación"
+#: include/conversation.php:1245 mod/editpost.php:107
+msgid "video link"
+msgstr "enlace de video"
 
-#: include/enotify.php:233
-#, php-format
-msgid "%1$s tagged your post at %2$s"
-msgstr "%1$s ha etiquetado tu publicación en %2$s"
+#: include/conversation.php:1246 mod/editpost.php:108
+msgid "Insert audio link"
+msgstr "Insertar vínculo del audio"
 
-#: include/enotify.php:234
-#, php-format
-msgid "%1$s tagged [url=%2$s]your post[/url]"
-msgstr "%1$s ha etiquetado [url=%2$s]tu publicación[/url]"
+#: include/conversation.php:1247 mod/editpost.php:109
+msgid "audio link"
+msgstr "enlace de audio"
 
-#: include/enotify.php:245
-msgid "[Friendica:Notify] Introduction received"
-msgstr "[Friendica:Notificación] Presentación recibida"
+#: include/conversation.php:1248 mod/editpost.php:110
+msgid "Set your location"
+msgstr "Configurar tu localización"
 
-#: include/enotify.php:247
-#, php-format
-msgid "You've received an introduction from '%1$s' at %2$s"
-msgstr "Has recibido una presentación de '%1$s' en %2$s"
+#: include/conversation.php:1249 mod/editpost.php:111
+msgid "set location"
+msgstr "establecer tu ubicación"
 
-#: include/enotify.php:248
-#, php-format
-msgid "You've received [url=%1$s]an introduction[/url] from %2$s."
-msgstr "Has recibido [url=%1$s]una presentación[/url] de %2$s."
+#: include/conversation.php:1250 mod/editpost.php:112
+msgid "Clear browser location"
+msgstr "Borrar la localización del navegador"
 
-#: include/enotify.php:252 include/enotify.php:295
-#, php-format
-msgid "You may visit their profile at %s"
-msgstr "Puedes visitar su perfil en %s"
+#: include/conversation.php:1251 mod/editpost.php:113
+msgid "clear location"
+msgstr "limpiar la localización"
 
-#: include/enotify.php:254
-#, php-format
-msgid "Please visit %s to approve or reject the introduction."
-msgstr "Visita %s para aceptar o rechazar la presentación por favor."
+#: include/conversation.php:1253 mod/editpost.php:127
+msgid "Set title"
+msgstr "Establecer el título"
 
-#: include/enotify.php:262
-msgid "[Friendica:Notify] A new person is sharing with you"
-msgstr "[Notificación:Friendica] Un nuevo contacto comparte contigo"
+#: include/conversation.php:1255 mod/editpost.php:129
+msgid "Categories (comma-separated list)"
+msgstr "Categorías (lista separada por comas)"
 
-#: include/enotify.php:264 include/enotify.php:265
-#, php-format
-msgid "%1$s is sharing with you at %2$s"
-msgstr "%1$s comparte con tigo en %2$s"
+#: include/conversation.php:1257 mod/editpost.php:115
+msgid "Permission settings"
+msgstr "Configuración de permisos"
 
-#: include/enotify.php:271
-msgid "[Friendica:Notify] You have a new follower"
-msgstr "[Notificación:Friendica] Tienes un nuevo seguidor"
+#: include/conversation.php:1258 mod/editpost.php:144
+msgid "permissions"
+msgstr "permisos"
 
-#: include/enotify.php:273 include/enotify.php:274
-#, php-format
-msgid "You have a new follower at %2$s : %1$s"
-msgstr "Tienes un nuevo seguidor en %2$s : %1$s"
+#: include/conversation.php:1266 mod/editpost.php:124
+msgid "Public post"
+msgstr "Publicación pública"
 
-#: include/enotify.php:285
-msgid "[Friendica:Notify] Friend suggestion received"
-msgstr "[Friendica:Notificación] Sugerencia de amigo recibida"
+#: include/conversation.php:1271 mod/content.php:737 mod/editpost.php:135
+#: mod/events.php:511 mod/photos.php:1613 mod/photos.php:1661
+#: mod/photos.php:1747 object/Item.php:714
+msgid "Preview"
+msgstr "Vista previa"
 
-#: include/enotify.php:287
-#, php-format
-msgid "You've received a friend suggestion from '%1$s' at %2$s"
-msgstr "Has recibido una sugerencia de amigo de '%1$s' en %2$s"
+#: include/conversation.php:1275 include/items.php:1983 mod/contacts.php:455
+#: mod/dfrn_request.php:889 mod/editpost.php:138 mod/fbrowser.php:100
+#: mod/fbrowser.php:135 mod/follow.php:124 mod/message.php:209
+#: mod/photos.php:240 mod/photos.php:331 mod/settings.php:682
+#: mod/settings.php:708 mod/suggest.php:32 mod/tagrm.php:11 mod/tagrm.php:96
+#: mod/videos.php:132
+msgid "Cancel"
+msgstr "Cancelar"
 
-#: include/enotify.php:288
-#, php-format
-msgid ""
-"You've received [url=%1$s]a friend suggestion[/url] for %2$s from %3$s."
-msgstr "Has recibido [url=%1$s]una sugerencia de amigo[/url] en %2$s de %3$s."
+#: include/conversation.php:1281
+msgid "Post to Groups"
+msgstr "Publicar hacia grupos"
 
-#: include/enotify.php:293
-msgid "Name:"
-msgstr "Nombre: "
+#: include/conversation.php:1282
+msgid "Post to Contacts"
+msgstr "Publicar hacia contactos"
 
-#: include/enotify.php:294
-msgid "Photo:"
-msgstr "Foto: "
+#: include/conversation.php:1283
+msgid "Private post"
+msgstr "Publicación privada"
 
-#: include/enotify.php:297
-#, php-format
-msgid "Please visit %s to approve or reject the suggestion."
-msgstr "Visita %s para aceptar o rechazar la sugerencia por favor."
+#: include/conversation.php:1288 include/identity.php:259 mod/editpost.php:142
+msgid "Message"
+msgstr "Mensaje"
 
-#: include/enotify.php:305 include/enotify.php:319
-msgid "[Friendica:Notify] Connection accepted"
-msgstr "[Notificación:Friendica] Conexión aceptada"
+#: include/conversation.php:1289 mod/editpost.php:143
+msgid "Browser"
+msgstr "Navegador"
 
-#: include/enotify.php:307 include/enotify.php:321
-#, php-format
-msgid "'%1$s' has accepted your connection request at %2$s"
-msgstr "'%1$s' acepto tu consulta de conexión %2$s"
+#: include/conversation.php:1445
+msgid "View all"
+msgstr "Ver todos los contactos"
 
-#: include/enotify.php:308 include/enotify.php:322
-#, php-format
-msgid "%2$s has accepted your [url=%1$s]connection request[/url]."
-msgstr "%2$s hacepto tu [url=%1$s]consulta de conexión[/url]."
+#: include/conversation.php:1467
+msgid "Like"
+msgid_plural "Likes"
+msgstr[0] "Me gusta"
+msgstr[1] "Me gusta"
 
-#: include/enotify.php:312
-msgid ""
-"You are now mutual friends and may exchange status updates, photos, and "
-"email without restriction."
-msgstr "Ahora tiene amigos en común y puede intercambiar actualizaciones de estado, fotos y email sin restricción."
+#: include/conversation.php:1470
+msgid "Dislike"
+msgid_plural "Dislikes"
+msgstr[0] "No me gusta"
+msgstr[1] "No me gusta"
 
-#: include/enotify.php:314
-#, php-format
-msgid "Please visit %s if you wish to make any changes to this relationship."
-msgstr "Por favor visite %s si desea hacer algún cambio a su relación."
+#: include/conversation.php:1476
+msgid "Not Attending"
+msgid_plural "Not Attending"
+msgstr[0] "No atendiendo"
+msgstr[1] "No atendiendo"
 
-#: include/enotify.php:326
-#, php-format
-msgid ""
-"'%1$s' has chosen to accept you a \"fan\", which restricts some forms of "
-"communication - such as private messaging and some profile interactions. If "
-"this is a celebrity or community page, these settings were applied "
-"automatically."
-msgstr "'%1$s' eligió de aceptarte como fan/hincha lo que restringe algunas formas de comunicación - tales como mensajes privados y algunas interacciones de los perfiles. Si esto es una pagina de celebridad o comunidad, estas configuraciones se adoptaron automáticamente."
+#: include/conversation.php:1479 include/profile_selectors.php:6
+msgid "Undecided"
+msgid_plural "Undecided"
+msgstr[0] "Indeciso"
+msgstr[1] "Indeciso"
 
-#: include/enotify.php:328
-#, php-format
-msgid ""
-"'%1$s' may choose to extend this into a two-way or more permissive "
-"relationship in the future."
-msgstr "'%1$s' puede elegir extender esto en una relación más permisiva o ambidireccional en el futuro."
+#: include/datetime.php:58 include/datetime.php:60 mod/profiles.php:697
+msgid "Miscellaneous"
+msgstr "Varios"
 
-#: include/enotify.php:330
-#, php-format
-msgid "Please visit %s  if you wish to make any changes to this relationship."
-msgstr "Por favor visita %s si es preciso de hacer algún cambio a la relación con este contacto."
+#: include/datetime.php:184 include/identity.php:641
+msgid "Birthday:"
+msgstr "Fecha de nacimiento:"
 
-#: include/enotify.php:340
-msgid "[Friendica System:Notify] registration request"
-msgstr "[Notificacion:Friendica] consulta de registro"
+#: include/datetime.php:186 mod/profiles.php:720
+msgid "Age: "
+msgstr "Edad: "
 
-#: include/enotify.php:342
-#, php-format
-msgid "You've received a registration request from '%1$s' at %2$s"
-msgstr "Recibiste una consulta de registro de '%1$s' en %2$s"
+#: include/datetime.php:188
+msgid "YYYY-MM-DD or MM-DD"
+msgstr "YYYY-MM-DD o MM-DD"
 
-#: include/enotify.php:343
-#, php-format
-msgid "You've received a [url=%1$s]registration request[/url] from %2$s."
-msgstr "Recibiste una [url=%1$s]consulta de registro[/url] from %2$s."
+#: include/datetime.php:343
+msgid "never"
+msgstr "nunca"
 
-#: include/enotify.php:347
-#, php-format
-msgid "Full Name:\t%1$s\\nSite Location:\t%2$s\\nLogin Name:\t%3$s (%4$s)"
-msgstr "Nombre completo:\t%1$s\\nUbicación del sitio:\t%2$s\\nLogin Nombre:\t%3$s (%4$s)"
+#: include/datetime.php:349
+msgid "less than a second ago"
+msgstr "hace menos de un segundo"
 
-#: include/enotify.php:350
-#, php-format
-msgid "Please visit %s to approve or reject the request."
-msgstr "Por favor visita %s para aprobar o negar la solicitud."
+#: include/datetime.php:352
+msgid "year"
+msgstr "año"
 
-#: include/event.php:16 include/bb2diaspora.php:152 mod/localtime.php:12
-msgid "l F d, Y \\@ g:i A"
-msgstr "l F d, Y \\@ g:i A"
+#: include/datetime.php:352
+msgid "years"
+msgstr "años"
 
-#: include/event.php:33 include/event.php:51 include/event.php:487
-#: include/bb2diaspora.php:158
-msgid "Starts:"
-msgstr "Inicio:"
+#: include/datetime.php:353 include/event.php:481 mod/cal.php:279
+#: mod/events.php:396
+msgid "month"
+msgstr "mes"
 
-#: include/event.php:36 include/event.php:57 include/event.php:488
-#: include/bb2diaspora.php:166
-msgid "Finishes:"
-msgstr "Final:"
+#: include/datetime.php:353
+msgid "months"
+msgstr "meses"
 
-#: include/event.php:39 include/event.php:63 include/event.php:489
-#: include/bb2diaspora.php:174 include/identity.php:328
-#: mod/notifications.php:232 mod/directory.php:137 mod/events.php:494
-#: mod/contacts.php:628
-msgid "Location:"
-msgstr "Localización:"
+#: include/datetime.php:354 include/event.php:482 mod/cal.php:280
+#: mod/events.php:397
+msgid "week"
+msgstr "semana"
 
-#: include/event.php:441
-msgid "Sun"
-msgstr "Dom"
+#: include/datetime.php:354
+msgid "weeks"
+msgstr "semanas"
 
-#: include/event.php:442
-msgid "Mon"
-msgstr "Lun"
+#: include/datetime.php:355 include/event.php:483 mod/cal.php:281
+#: mod/events.php:398
+msgid "day"
+msgstr "día"
 
-#: include/event.php:443
-msgid "Tue"
-msgstr "Mar"
+#: include/datetime.php:355
+msgid "days"
+msgstr "días"
 
-#: include/event.php:444
-msgid "Wed"
-msgstr "Mie"
+#: include/datetime.php:356
+msgid "hour"
+msgstr "hora"
 
-#: include/event.php:445
-msgid "Thu"
-msgstr "Jue"
+#: include/datetime.php:356
+msgid "hours"
+msgstr "horas"
 
-#: include/event.php:446
-msgid "Fri"
-msgstr "Vie"
+#: include/datetime.php:357
+msgid "minute"
+msgstr "minuto"
 
-#: include/event.php:447
-msgid "Sat"
-msgstr "Sab"
+#: include/datetime.php:357
+msgid "minutes"
+msgstr "minutos"
 
-#: include/event.php:448 include/text.php:1130 mod/settings.php:972
-msgid "Sunday"
-msgstr "Domingo"
+#: include/datetime.php:358
+msgid "second"
+msgstr "segundo"
 
-#: include/event.php:449 include/text.php:1130 mod/settings.php:972
-msgid "Monday"
-msgstr "Lunes"
+#: include/datetime.php:358
+msgid "seconds"
+msgstr "segundos"
 
-#: include/event.php:450 include/text.php:1130
-msgid "Tuesday"
-msgstr "Martes"
+#: include/datetime.php:367
+#, php-format
+msgid "%1$d %2$s ago"
+msgstr "hace %1$d %2$s"
 
-#: include/event.php:451 include/text.php:1130
-msgid "Wednesday"
-msgstr "Miércoles"
+#: include/datetime.php:585
+#, php-format
+msgid "%s's birthday"
+msgstr "Cumpleaños de %s"
 
-#: include/event.php:452 include/text.php:1130
-msgid "Thursday"
-msgstr "Jueves"
+#: include/datetime.php:586 include/dfrn.php:1131
+#, php-format
+msgid "Happy Birthday %s"
+msgstr "Feliz cumpleaños %s"
 
-#: include/event.php:453 include/text.php:1130
-msgid "Friday"
-msgstr "Viernes"
+#: include/dba.php:43 include/dba_pdo.php:72
+#, php-format
+msgid "Cannot locate DNS info for database server '%s'"
+msgstr "No se puede encontrar información DNS para la base de datos del servidor '%s'"
 
-#: include/event.php:454 include/text.php:1130
-msgid "Saturday"
-msgstr "Sábado"
+#: include/dbstructure.php:36
+#, php-format
+msgid ""
+"\n"
+"\t\t\tThe friendica developers released update %s recently,\n"
+"\t\t\tbut when I tried to install it, something went terribly wrong.\n"
+"\t\t\tThis needs to be fixed soon and I can't do it alone. Please contact a\n"
+"\t\t\tfriendica developer if you can not help me on your own. My database might be invalid."
+msgstr "\n\t\t\tLos desarolladores de friendica publicaron una actualización  %s recientemente\n\t\t\tpero cuando intento de instalarla,algo salio terriblemente mal.\n\t\t\tEsto necesita ser arreglado pronto y no puedo hacerlo solo. Por favor contacta\n\t\t\tlos desarolladores de friendica si no me podes ayudar por ti solo. Mi base de datos puede estar invalido."
 
-#: include/event.php:455
-msgid "Jan"
-msgstr "Ene"
+#: include/dbstructure.php:41
+#, php-format
+msgid ""
+"The error message is\n"
+"[pre]%s[/pre]"
+msgstr "El mensaje de error es\n[pre]%s[/pre]"
 
-#: include/event.php:456
-msgid "Feb"
-msgstr "Feb"
+#: include/dbstructure.php:199
+msgid "Errors encountered creating database tables."
+msgstr "Se han encontrados errores creando las tablas de la base de datos."
 
-#: include/event.php:457
-msgid "Mar"
-msgstr "Mar"
+#: include/dbstructure.php:333 include/dbstructure.php:341
+#: include/dbstructure.php:349 include/dbstructure.php:354
+#: include/dbstructure.php:359
+msgid "Errors encountered performing database changes."
+msgstr "Errores encontrados al ejecutar cambios en la base de datos."
 
-#: include/event.php:458
-msgid "Apr"
-msgstr "Abr"
+#: include/delivery.php:427
+msgid "(no subject)"
+msgstr "(sin asunto)"
 
-#: include/event.php:459 include/event.php:471 include/text.php:1134
-msgid "May"
-msgstr "Mayo"
+#: include/delivery.php:439 include/enotify.php:43
+msgid "noreply"
+msgstr "no responder"
 
-#: include/event.php:460
-msgid "Jun"
-msgstr "Jun"
+#: include/dfrn.php:1130
+#, php-format
+msgid "%s\\'s birthday"
+msgstr "%s\\'s cumpleaños"
 
-#: include/event.php:461
-msgid "Jul"
-msgstr "Jul"
+#: include/diaspora.php:2087
+msgid "Sharing notification from Diaspora network"
+msgstr "Compartir notificaciones con la red Diaspora*"
 
-#: include/event.php:462
-msgid "Aug"
-msgstr "Ago"
+#: include/diaspora.php:3096
+msgid "Attachments:"
+msgstr "Archivos adjuntos:"
 
-#: include/event.php:463
-msgid "Sept"
-msgstr "Sept"
+#: include/enotify.php:24
+msgid "Friendica Notification"
+msgstr "Notificación de Friendica"
 
-#: include/event.php:464
-msgid "Oct"
-msgstr "Oct"
+#: include/enotify.php:27
+msgid "Thank You,"
+msgstr "Gracias,"
 
-#: include/event.php:465
-msgid "Nov"
-msgstr "Nov"
+#: include/enotify.php:30
+#, php-format
+msgid "%s Administrator"
+msgstr "%s Administrador"
 
-#: include/event.php:466
-msgid "Dec"
-msgstr "Dec"
+#: include/enotify.php:32
+#, php-format
+msgid "%1$s, %2$s Administrator"
+msgstr "%1$s, %2$s Administrador"
 
-#: include/event.php:467 include/text.php:1134
-msgid "January"
-msgstr "Enero"
+#: include/enotify.php:70
+#, php-format
+msgid "%s <!item_type!>"
+msgstr "%s <!item_type!>"
 
-#: include/event.php:468 include/text.php:1134
-msgid "February"
-msgstr "Febrero"
+#: include/enotify.php:83
+#, php-format
+msgid "[Friendica:Notify] New mail received at %s"
+msgstr "[Friendica:Notificación] Nuevo correo recibido de %s"
 
-#: include/event.php:469 include/text.php:1134
-msgid "March"
-msgstr "Marzo"
+#: include/enotify.php:85
+#, php-format
+msgid "%1$s sent you a new private message at %2$s."
+msgstr "%1$s te ha enviado un mensaje privado desde %2$s."
 
-#: include/event.php:470 include/text.php:1134
-msgid "April"
-msgstr "Abril"
+#: include/enotify.php:86
+#, php-format
+msgid "%1$s sent you %2$s."
+msgstr "%1$s te ha enviado %2$s."
 
-#: include/event.php:472 include/text.php:1134
-msgid "June"
-msgstr "Junio"
+#: include/enotify.php:86
+msgid "a private message"
+msgstr "un mensaje privado"
 
-#: include/event.php:473 include/text.php:1134
-msgid "July"
-msgstr "Julio"
+#: include/enotify.php:88
+#, php-format
+msgid "Please visit %s to view and/or reply to your private messages."
+msgstr "Por favor, visita %s para ver y/o responder a tus mensajes privados."
 
-#: include/event.php:474 include/text.php:1134
-msgid "August"
-msgstr "Agosto"
+#: include/enotify.php:134
+#, php-format
+msgid "%1$s commented on [url=%2$s]a %3$s[/url]"
+msgstr "%1$s comentó en [url=%2$s]a %3$s[/url]"
 
-#: include/event.php:475 include/text.php:1134
-msgid "September"
-msgstr "Septiembre"
+#: include/enotify.php:141
+#, php-format
+msgid "%1$s commented on [url=%2$s]%3$s's %4$s[/url]"
+msgstr "%1$s comentó en [url=%2$s] %4$s de %3$s[/url]"
 
-#: include/event.php:476 include/text.php:1134
-msgid "October"
-msgstr "Octubre"
+#: include/enotify.php:149
+#, php-format
+msgid "%1$s commented on [url=%2$s]your %3$s[/url]"
+msgstr "%1$s comentó en [url=%2$s] tu %3$s[/url]"
 
-#: include/event.php:477 include/text.php:1134
-msgid "November"
-msgstr "Noviembre"
+#: include/enotify.php:159
+#, php-format
+msgid "[Friendica:Notify] Comment to conversation #%1$d by %2$s"
+msgstr "[Friendica:Notificación] Comentario en la conversación de #%1$d por %2$s"
 
-#: include/event.php:478 include/text.php:1134
-msgid "December"
-msgstr "Diciembre"
+#: include/enotify.php:161
+#, php-format
+msgid "%s commented on an item/conversation you have been following."
+msgstr "%s ha comentado en una conversación/elemento que sigues."
 
-#: include/event.php:479 mod/cal.php:283 mod/events.php:388
-msgid "today"
-msgstr "hoy"
+#: include/enotify.php:164 include/enotify.php:178 include/enotify.php:192
+#: include/enotify.php:206 include/enotify.php:224 include/enotify.php:238
+#, php-format
+msgid "Please visit %s to view and/or reply to the conversation."
+msgstr "Por favor, visita %s para ver y/o responder a la conversación."
 
-#: include/event.php:483
-msgid "all-day"
-msgstr "todo el día"
+#: include/enotify.php:171
+#, php-format
+msgid "[Friendica:Notify] %s posted to your profile wall"
+msgstr "[Friendica:Notificación] %s publicó en tu muro"
 
-#: include/event.php:485
-msgid "No events to display"
-msgstr "No hay eventos a mostrar"
+#: include/enotify.php:173
+#, php-format
+msgid "%1$s posted to your profile wall at %2$s"
+msgstr "%1$s publicó en tu perfil de %2$s"
 
-#: include/event.php:574
-msgid "l, F j"
-msgstr "l, F j"
+#: include/enotify.php:174
+#, php-format
+msgid "%1$s posted to [url=%2$s]your wall[/url]"
+msgstr "%1$s publicó en [url=%2$s]tu muro[/url]"
 
-#: include/event.php:593
-msgid "Edit event"
-msgstr "Editar evento"
+#: include/enotify.php:185
+#, php-format
+msgid "[Friendica:Notify] %s tagged you"
+msgstr "[Friendica:Notificación] %s te ha nombrado"
 
-#: include/event.php:615 include/text.php:1532 include/text.php:1539
-msgid "link to source"
-msgstr "Enlace al original"
+#: include/enotify.php:187
+#, php-format
+msgid "%1$s tagged you at %2$s"
+msgstr "%1$s te ha nombrado en %2$s"
 
-#: include/event.php:850
-msgid "Export"
-msgstr "Exportar"
+#: include/enotify.php:188
+#, php-format
+msgid "%1$s [url=%2$s]tagged you[/url]."
+msgstr "%1$s [url=%2$s]te nombró[/url]."
 
-#: include/event.php:851
-msgid "Export calendar as ical"
-msgstr "Exportar calendario como ical"
+#: include/enotify.php:199
+#, php-format
+msgid "[Friendica:Notify] %s shared a new post"
+msgstr "[Notificacion Friendica] %s compartio una nueva publicacion"
 
-#: include/event.php:852
-msgid "Export calendar as csv"
-msgstr "Exportar calendario como csv"
+#: include/enotify.php:201
+#, php-format
+msgid "%1$s shared a new post at %2$s"
+msgstr "%1$s compartió un nuevo tema en %2$s"
 
-#: include/nav.php:35 mod/navigation.php:19
-msgid "Nothing new here"
-msgstr "Nada nuevo por aquí"
+#: include/enotify.php:202
+#, php-format
+msgid "%1$s [url=%2$s]shared a post[/url]."
+msgstr "%1$s [url=%2$s]compartió una publicación[/url]."
 
-#: include/nav.php:39 mod/navigation.php:23
-msgid "Clear notifications"
-msgstr "Limpiar notificaciones"
+#: include/enotify.php:213
+#, php-format
+msgid "[Friendica:Notify] %1$s poked you"
+msgstr "[Friendica:Notify] %1$s te dio un toque"
 
-#: include/nav.php:40 include/text.php:1015
-msgid "@name, !forum, #tags, content"
-msgstr "@name, !forum, #tags, contenido"
+#: include/enotify.php:215
+#, php-format
+msgid "%1$s poked you at %2$s"
+msgstr "%1$s te dio un toque en %2$s"
 
-#: include/nav.php:78 view/theme/frio/theme.php:246 boot.php:1792
-msgid "Logout"
-msgstr "Salir"
+#: include/enotify.php:216
+#, php-format
+msgid "%1$s [url=%2$s]poked you[/url]."
+msgstr "%1$s [url=%2$s]te dio un toque[/url]."
 
-#: include/nav.php:78 view/theme/frio/theme.php:246
-msgid "End this session"
-msgstr "Cerrar la sesión"
+#: include/enotify.php:231
+#, php-format
+msgid "[Friendica:Notify] %s tagged your post"
+msgstr "[Friendica:Notificación] %s ha etiquetado tu publicación"
 
-#: include/nav.php:81 include/identity.php:714 mod/contacts.php:637
-#: mod/contacts.php:833 view/theme/frio/theme.php:249
-msgid "Status"
-msgstr "Estado"
+#: include/enotify.php:233
+#, php-format
+msgid "%1$s tagged your post at %2$s"
+msgstr "%1$s ha etiquetado tu publicación en %2$s"
 
-#: include/nav.php:81 include/nav.php:161 view/theme/frio/theme.php:249
-msgid "Your posts and conversations"
-msgstr "Tus publicaciones y conversaciones"
+#: include/enotify.php:234
+#, php-format
+msgid "%1$s tagged [url=%2$s]your post[/url]"
+msgstr "%1$s ha etiquetado [url=%2$s]tu publicación[/url]"
 
-#: include/nav.php:82 include/identity.php:605 include/identity.php:691
-#: include/identity.php:722 mod/profperm.php:104 mod/newmember.php:32
-#: mod/contacts.php:639 mod/contacts.php:841 view/theme/frio/theme.php:250
-msgid "Profile"
-msgstr "Perfil"
+#: include/enotify.php:245
+msgid "[Friendica:Notify] Introduction received"
+msgstr "[Friendica:Notificación] Presentación recibida"
+
+#: include/enotify.php:247
+#, php-format
+msgid "You've received an introduction from '%1$s' at %2$s"
+msgstr "Has recibido una presentación de '%1$s' en %2$s"
+
+#: include/enotify.php:248
+#, php-format
+msgid "You've received [url=%1$s]an introduction[/url] from %2$s."
+msgstr "Has recibido [url=%1$s]una presentación[/url] de %2$s."
+
+#: include/enotify.php:252 include/enotify.php:295
+#, php-format
+msgid "You may visit their profile at %s"
+msgstr "Puedes visitar su perfil en %s"
+
+#: include/enotify.php:254
+#, php-format
+msgid "Please visit %s to approve or reject the introduction."
+msgstr "Visita %s para aceptar o rechazar la presentación por favor."
+
+#: include/enotify.php:262
+msgid "[Friendica:Notify] A new person is sharing with you"
+msgstr "[Notificación:Friendica] Un nuevo contacto comparte contigo"
+
+#: include/enotify.php:264 include/enotify.php:265
+#, php-format
+msgid "%1$s is sharing with you at %2$s"
+msgstr "%1$s comparte con tigo en %2$s"
+
+#: include/enotify.php:271
+msgid "[Friendica:Notify] You have a new follower"
+msgstr "[Notificación:Friendica] Tienes un nuevo seguidor"
+
+#: include/enotify.php:273 include/enotify.php:274
+#, php-format
+msgid "You have a new follower at %2$s : %1$s"
+msgstr "Tienes un nuevo seguidor en %2$s : %1$s"
+
+#: include/enotify.php:285
+msgid "[Friendica:Notify] Friend suggestion received"
+msgstr "[Friendica:Notificación] Sugerencia de amigo recibida"
+
+#: include/enotify.php:287
+#, php-format
+msgid "You've received a friend suggestion from '%1$s' at %2$s"
+msgstr "Has recibido una sugerencia de amigo de '%1$s' en %2$s"
+
+#: include/enotify.php:288
+#, php-format
+msgid ""
+"You've received [url=%1$s]a friend suggestion[/url] for %2$s from %3$s."
+msgstr "Has recibido [url=%1$s]una sugerencia de amigo[/url] en %2$s de %3$s."
+
+#: include/enotify.php:293
+msgid "Name:"
+msgstr "Nombre: "
+
+#: include/enotify.php:294
+msgid "Photo:"
+msgstr "Foto: "
+
+#: include/enotify.php:297
+#, php-format
+msgid "Please visit %s to approve or reject the suggestion."
+msgstr "Visita %s para aceptar o rechazar la sugerencia por favor."
+
+#: include/enotify.php:305 include/enotify.php:319
+msgid "[Friendica:Notify] Connection accepted"
+msgstr "[Notificación:Friendica] Conexión aceptada"
+
+#: include/enotify.php:307 include/enotify.php:321
+#, php-format
+msgid "'%1$s' has accepted your connection request at %2$s"
+msgstr "'%1$s' acepto tu consulta de conexión %2$s"
+
+#: include/enotify.php:308 include/enotify.php:322
+#, php-format
+msgid "%2$s has accepted your [url=%1$s]connection request[/url]."
+msgstr "%2$s hacepto tu [url=%1$s]consulta de conexión[/url]."
+
+#: include/enotify.php:312
+msgid ""
+"You are now mutual friends and may exchange status updates, photos, and "
+"email without restriction."
+msgstr "Ahora tiene amigos en común y puede intercambiar actualizaciones de estado, fotos y email sin restricción."
+
+#: include/enotify.php:314
+#, php-format
+msgid "Please visit %s if you wish to make any changes to this relationship."
+msgstr "Por favor visite %s si desea hacer algún cambio a su relación."
+
+#: include/enotify.php:326
+#, php-format
+msgid ""
+"'%1$s' has chosen to accept you a \"fan\", which restricts some forms of "
+"communication - such as private messaging and some profile interactions. If "
+"this is a celebrity or community page, these settings were applied "
+"automatically."
+msgstr "'%1$s' eligió de aceptarte como fan/hincha lo que restringe algunas formas de comunicación - tales como mensajes privados y algunas interacciones de los perfiles. Si esto es una pagina de celebridad o comunidad, estas configuraciones se adoptaron automáticamente."
+
+#: include/enotify.php:328
+#, php-format
+msgid ""
+"'%1$s' may choose to extend this into a two-way or more permissive "
+"relationship in the future."
+msgstr "'%1$s' puede elegir extender esto en una relación más permisiva o ambidireccional en el futuro."
+
+#: include/enotify.php:330
+#, php-format
+msgid "Please visit %s  if you wish to make any changes to this relationship."
+msgstr "Por favor visita %s si es preciso de hacer algún cambio a la relación con este contacto."
+
+#: include/enotify.php:340
+msgid "[Friendica System:Notify] registration request"
+msgstr "[Notificacion:Friendica] consulta de registro"
+
+#: include/enotify.php:342
+#, php-format
+msgid "You've received a registration request from '%1$s' at %2$s"
+msgstr "Recibiste una consulta de registro de '%1$s' en %2$s"
+
+#: include/enotify.php:343
+#, php-format
+msgid "You've received a [url=%1$s]registration request[/url] from %2$s."
+msgstr "Recibiste una [url=%1$s]consulta de registro[/url] from %2$s."
+
+#: include/enotify.php:347
+#, php-format
+msgid "Full Name:\t%1$s\\nSite Location:\t%2$s\\nLogin Name:\t%3$s (%4$s)"
+msgstr "Nombre completo:\t%1$s\\nUbicación del sitio:\t%2$s\\nLogin Nombre:\t%3$s (%4$s)"
+
+#: include/enotify.php:350
+#, php-format
+msgid "Please visit %s to approve or reject the request."
+msgstr "Por favor visita %s para aprobar o negar la solicitud."
 
-#: include/nav.php:82 view/theme/frio/theme.php:250
-msgid "Your profile page"
-msgstr "Tu página de perfil"
+#: include/event.php:442
+msgid "Sun"
+msgstr "Dom"
 
-#: include/nav.php:83 include/identity.php:730 mod/fbrowser.php:32
-#: view/theme/frio/theme.php:251
-msgid "Photos"
-msgstr "Fotografías"
+#: include/event.php:443
+msgid "Mon"
+msgstr "Lun"
 
-#: include/nav.php:83 view/theme/frio/theme.php:251
-msgid "Your photos"
-msgstr "Tus fotos"
+#: include/event.php:444
+msgid "Tue"
+msgstr "Mar"
 
-#: include/nav.php:84 include/identity.php:738 include/identity.php:741
-#: view/theme/frio/theme.php:252
-msgid "Videos"
-msgstr "Videos"
+#: include/event.php:445
+msgid "Wed"
+msgstr "Mie"
 
-#: include/nav.php:84 view/theme/frio/theme.php:252
-msgid "Your videos"
-msgstr "Tus videos"
+#: include/event.php:446
+msgid "Thu"
+msgstr "Jue"
 
-#: include/nav.php:85 include/nav.php:149 include/identity.php:750
-#: include/identity.php:761 mod/cal.php:275 mod/events.php:379
-#: view/theme/frio/theme.php:253 view/theme/frio/theme.php:257
-msgid "Events"
-msgstr "Eventos"
+#: include/event.php:447
+msgid "Fri"
+msgstr "Vie"
 
-#: include/nav.php:85 view/theme/frio/theme.php:253
-msgid "Your events"
-msgstr "Tus eventos"
+#: include/event.php:448
+msgid "Sat"
+msgstr "Sab"
 
-#: include/nav.php:86
-msgid "Personal notes"
-msgstr "Notas personales"
+#: include/event.php:449 include/text.php:1132 mod/settings.php:981
+msgid "Sunday"
+msgstr "Domingo"
 
-#: include/nav.php:86
-msgid "Your personal notes"
-msgstr "Tus notas personales"
+#: include/event.php:450 include/text.php:1132 mod/settings.php:981
+msgid "Monday"
+msgstr "Lunes"
 
-#: include/nav.php:95 mod/bookmarklet.php:12 boot.php:1793
-msgid "Login"
-msgstr "Acceder"
+#: include/event.php:451 include/text.php:1132
+msgid "Tuesday"
+msgstr "Martes"
 
-#: include/nav.php:95
-msgid "Sign in"
-msgstr "Date de alta"
+#: include/event.php:452 include/text.php:1132
+msgid "Wednesday"
+msgstr "Miércoles"
 
-#: include/nav.php:105 include/nav.php:161
-#: include/NotificationsManager.php:174
-msgid "Home"
-msgstr "Inicio"
+#: include/event.php:453 include/text.php:1132
+msgid "Thursday"
+msgstr "Jueves"
 
-#: include/nav.php:105
-msgid "Home Page"
-msgstr "Página de inicio"
+#: include/event.php:454 include/text.php:1132
+msgid "Friday"
+msgstr "Viernes"
 
-#: include/nav.php:109 mod/register.php:289 boot.php:1768
-msgid "Register"
-msgstr "Registrarse"
+#: include/event.php:455 include/text.php:1132
+msgid "Saturday"
+msgstr "Sábado"
 
-#: include/nav.php:109
-msgid "Create an account"
-msgstr "Crea una cuenta"
+#: include/event.php:456
+msgid "Jan"
+msgstr "Ene"
 
-#: include/nav.php:115 mod/help.php:47 view/theme/vier/theme.php:298
-msgid "Help"
-msgstr "Ayuda"
+#: include/event.php:457
+msgid "Feb"
+msgstr "Feb"
 
-#: include/nav.php:115
-msgid "Help and documentation"
-msgstr "Ayuda y documentación"
+#: include/event.php:458
+msgid "Mar"
+msgstr "Mar"
 
-#: include/nav.php:119
-msgid "Apps"
-msgstr "Aplicaciones"
+#: include/event.php:459
+msgid "Apr"
+msgstr "Abr"
 
-#: include/nav.php:119
-msgid "Addon applications, utilities, games"
-msgstr "Aplicaciones, utilidades, juegos"
+#: include/event.php:460 include/event.php:472 include/text.php:1136
+msgid "May"
+msgstr "Mayo"
 
-#: include/nav.php:123 include/text.php:1012 mod/search.php:149
-msgid "Search"
-msgstr "Buscar"
+#: include/event.php:461
+msgid "Jun"
+msgstr "Jun"
 
-#: include/nav.php:123
-msgid "Search site content"
-msgstr " Busca contenido en la página"
+#: include/event.php:462
+msgid "Jul"
+msgstr "Jul"
 
-#: include/nav.php:126 include/text.php:1020
-msgid "Full Text"
-msgstr "Texto completo"
+#: include/event.php:463
+msgid "Aug"
+msgstr "Ago"
 
-#: include/nav.php:127 include/text.php:1021
-msgid "Tags"
-msgstr "Tags"
+#: include/event.php:464
+msgid "Sept"
+msgstr "Sept"
 
-#: include/nav.php:128 include/nav.php:192 include/identity.php:783
-#: include/identity.php:786 include/text.php:1022 mod/contacts.php:792
-#: mod/contacts.php:853 mod/viewcontacts.php:116 view/theme/frio/theme.php:260
-msgid "Contacts"
-msgstr "Contactos"
+#: include/event.php:465
+msgid "Oct"
+msgstr "Oct"
 
-#: include/nav.php:143 include/nav.php:145 mod/community.php:36
-msgid "Community"
-msgstr "Comunidad"
+#: include/event.php:466
+msgid "Nov"
+msgstr "Nov"
 
-#: include/nav.php:143
-msgid "Conversations on this site"
-msgstr "Conversaciones en este sitio"
+#: include/event.php:467
+msgid "Dec"
+msgstr "Dec"
 
-#: include/nav.php:145
-msgid "Conversations on the network"
-msgstr "Conversaciones en la red"
+#: include/event.php:468 include/text.php:1136
+msgid "January"
+msgstr "Enero"
 
-#: include/nav.php:149 include/identity.php:753 include/identity.php:764
-#: view/theme/frio/theme.php:257
-msgid "Events and Calendar"
-msgstr "Eventos y Calendario"
+#: include/event.php:469 include/text.php:1136
+msgid "February"
+msgstr "Febrero"
 
-#: include/nav.php:152
-msgid "Directory"
-msgstr "Directorio"
+#: include/event.php:470 include/text.php:1136
+msgid "March"
+msgstr "Marzo"
 
-#: include/nav.php:152
-msgid "People directory"
-msgstr "Directorio de usuarios"
+#: include/event.php:471 include/text.php:1136
+msgid "April"
+msgstr "Abril"
 
-#: include/nav.php:154
-msgid "Information"
-msgstr "Información"
+#: include/event.php:473 include/text.php:1136
+msgid "June"
+msgstr "Junio"
 
-#: include/nav.php:154
-msgid "Information about this friendica instance"
-msgstr "Información sobre esta instancia de friendica"
+#: include/event.php:474 include/text.php:1136
+msgid "July"
+msgstr "Julio"
 
-#: include/nav.php:158 include/NotificationsManager.php:160 mod/admin.php:411
-#: view/theme/frio/theme.php:256
-msgid "Network"
-msgstr "Red"
+#: include/event.php:475 include/text.php:1136
+msgid "August"
+msgstr "Agosto"
 
-#: include/nav.php:158 view/theme/frio/theme.php:256
-msgid "Conversations from your friends"
-msgstr "Conversaciones de tus amigos"
+#: include/event.php:476 include/text.php:1136
+msgid "September"
+msgstr "Septiembre"
 
-#: include/nav.php:159
-msgid "Network Reset"
-msgstr "Reseteo de la red"
+#: include/event.php:477 include/text.php:1136
+msgid "October"
+msgstr "Octubre"
 
-#: include/nav.php:159
-msgid "Load Network page with no filters"
-msgstr "Cargar pagina de redes sin filtros"
+#: include/event.php:478 include/text.php:1136
+msgid "November"
+msgstr "Noviembre"
 
-#: include/nav.php:166 include/NotificationsManager.php:181
-msgid "Introductions"
-msgstr "Presentaciones"
+#: include/event.php:479 include/text.php:1136
+msgid "December"
+msgstr "Diciembre"
 
-#: include/nav.php:166
-msgid "Friend Requests"
-msgstr "Solicitudes de amistad"
+#: include/event.php:480 mod/cal.php:278 mod/events.php:395
+msgid "today"
+msgstr "hoy"
 
-#: include/nav.php:169 mod/notifications.php:96
-msgid "Notifications"
-msgstr "Notificaciones"
+#: include/event.php:484
+msgid "all-day"
+msgstr "todo el día"
 
-#: include/nav.php:170
-msgid "See all notifications"
-msgstr "Ver todas las notificaciones"
+#: include/event.php:486
+msgid "No events to display"
+msgstr "No hay eventos a mostrar"
 
-#: include/nav.php:171 mod/settings.php:902
-msgid "Mark as seen"
-msgstr "Marcar como leído"
+#: include/event.php:596
+msgid "l, F j"
+msgstr "l, F j"
 
-#: include/nav.php:171
-msgid "Mark all system notifications seen"
-msgstr "Marcar todas las notificaciones del sistema como leídas"
+#: include/event.php:615
+msgid "Edit event"
+msgstr "Editar evento"
 
-#: include/nav.php:175 mod/message.php:190 view/theme/frio/theme.php:258
-msgid "Messages"
-msgstr "Mensajes"
+#: include/event.php:637 include/text.php:1534 include/text.php:1541
+msgid "link to source"
+msgstr "Enlace al original"
 
-#: include/nav.php:175 view/theme/frio/theme.php:258
-msgid "Private mail"
-msgstr "Correo privado"
+#: include/event.php:872
+msgid "Export"
+msgstr "Exportar"
 
-#: include/nav.php:176
-msgid "Inbox"
-msgstr "Entrada"
+#: include/event.php:873
+msgid "Export calendar as ical"
+msgstr "Exportar calendario como ical"
 
-#: include/nav.php:177
-msgid "Outbox"
-msgstr "Enviados"
+#: include/event.php:874
+msgid "Export calendar as csv"
+msgstr "Exportar calendario como csv"
 
-#: include/nav.php:178 mod/message.php:16
-msgid "New Message"
-msgstr "Nuevo mensaje"
+#: include/features.php:65
+msgid "General Features"
+msgstr "Opciones generales"
 
-#: include/nav.php:181
-msgid "Manage"
-msgstr "Administrar"
+#: include/features.php:67
+msgid "Multiple Profiles"
+msgstr "Perfiles multiples"
 
-#: include/nav.php:181
-msgid "Manage other pages"
-msgstr "Administrar otras páginas"
+#: include/features.php:67
+msgid "Ability to create multiple profiles"
+msgstr "Capacidad de crear perfiles multiples. Cada pagina/perfil/usuario puede tener diferentes perfiles/apariencias. Las mismas pueden ser visibles para determinados contactos seleccionados dentro de la red friendica."
 
-#: include/nav.php:184 mod/settings.php:81
-msgid "Delegations"
-msgstr "Delegaciones"
+#: include/features.php:68
+msgid "Photo Location"
+msgstr "Localización foto"
 
-#: include/nav.php:184 mod/delegate.php:130
-msgid "Delegate Page Management"
-msgstr "Delegar la administración de la página"
+#: include/features.php:68
+msgid ""
+"Photo metadata is normally stripped. This extracts the location (if present)"
+" prior to stripping metadata and links it to a map."
+msgstr "Normalmente los meta datos de las imágenes son eliminados. Esto extraerá la localización si presente antes de eliminar los meta datos y enlaza la misma con el mapa."
 
-#: include/nav.php:186 mod/newmember.php:22 mod/settings.php:111
-#: mod/admin.php:1524 mod/admin.php:1782 view/theme/frio/theme.php:259
-msgid "Settings"
-msgstr "Configuración"
+#: include/features.php:69
+msgid "Export Public Calendar"
+msgstr "Exportar Calendario Público"
 
-#: include/nav.php:186 view/theme/frio/theme.php:259
-msgid "Account settings"
-msgstr "Configuración de tu cuenta"
+#: include/features.php:69
+msgid "Ability for visitors to download the public calendar"
+msgstr "Posibilidad de los visitantes de descargar el calendario público"
 
-#: include/nav.php:189 include/identity.php:282
-msgid "Profiles"
-msgstr "Perfiles"
+#: include/features.php:74
+msgid "Post Composition Features"
+msgstr "Opciones de edición de publicaciones."
 
-#: include/nav.php:189
-msgid "Manage/Edit Profiles"
-msgstr "Manejar/editar Perfiles"
+#: include/features.php:75
+msgid "Post Preview"
+msgstr "Previsualizar publicaciones"
 
-#: include/nav.php:192 view/theme/frio/theme.php:260
-msgid "Manage/edit friends and contacts"
-msgstr "Administrar/editar amigos y contactos"
+#: include/features.php:75
+msgid "Allow previewing posts and comments before publishing them"
+msgstr "Permitir la previsualización de publicaciones antes de publicar las mismas."
 
-#: include/nav.php:197 mod/admin.php:186
-msgid "Admin"
-msgstr "Admin"
+#: include/features.php:76
+msgid "Auto-mention Forums"
+msgstr "Auto-mencionar foros"
 
-#: include/nav.php:197
-msgid "Site setup and configuration"
-msgstr "Opciones y configuración del sitio"
+#: include/features.php:76
+msgid ""
+"Add/remove mention when a forum page is selected/deselected in ACL window."
+msgstr "Añadir/eliminar mención cuando un foro es seleccionado/deseleccionado en la ventana ACL."
 
-#: include/nav.php:200
-msgid "Navigation"
-msgstr "Navegación"
+#: include/features.php:81
+msgid "Network Sidebar Widgets"
+msgstr "Accesorios de red del panel lateral"
 
-#: include/nav.php:200
-msgid "Site map"
-msgstr "Mapa del sitio"
+#: include/features.php:82
+msgid "Search by Date"
+msgstr "Buscar por fecha"
 
-#: include/photos.php:53 mod/fbrowser.php:41 mod/fbrowser.php:62
-#: mod/photos.php:180 mod/photos.php:1086 mod/photos.php:1211
-#: mod/photos.php:1232 mod/photos.php:1795 mod/photos.php:1807
-msgid "Contact Photos"
-msgstr "Foto del contacto"
+#: include/features.php:82
+msgid "Ability to select posts by date ranges"
+msgstr "Habilidad de seleccionar publicaciones por fecha"
 
-#: include/security.php:22
-msgid "Welcome "
-msgstr "Bienvenido "
+#: include/features.php:83 include/features.php:113
+msgid "List Forums"
+msgstr "Listar foros"
 
-#: include/security.php:23
-msgid "Please upload a profile photo."
-msgstr "Por favor sube una foto para tu perfil."
+#: include/features.php:83
+msgid "Enable widget to display the forums your are connected with"
+msgstr "Habilitar la pestaña para mostrar los foros en que estas participando."
 
-#: include/security.php:26
-msgid "Welcome back "
-msgstr "Bienvenido de nuevo "
+#: include/features.php:84
+msgid "Group Filter"
+msgstr "Filtro del grupo"
 
-#: include/security.php:373
-msgid ""
-"The form security token was not correct. This probably happened because the "
-"form has been opened for too long (>3 hours) before submitting it."
-msgstr "La ficha de seguridad no es correcta. Seguramente haya ocurrido por haber dejado el formulario abierto demasiado tiempo (>3 horas) antes de enviarlo."
+#: include/features.php:84
+msgid "Enable widget to display Network posts only from selected group"
+msgstr "Habilitar accesorios para visualizar publicaciones en la red solo de grupos seleccionados"
 
-#: include/NotificationsManager.php:153
-msgid "System"
-msgstr "Sistema"
+#: include/features.php:85
+msgid "Network Filter"
+msgstr "Filtro de red"
 
-#: include/NotificationsManager.php:167 mod/profiles.php:703
-#: mod/network.php:845
-msgid "Personal"
-msgstr "Personal"
+#: include/features.php:85
+msgid "Enable widget to display Network posts only from selected network"
+msgstr "Habilitar accesorios para visualizar publicaciones solo de las redes seleccionadas."
 
-#: include/NotificationsManager.php:234 include/NotificationsManager.php:244
-#, php-format
-msgid "%s commented on %s's post"
-msgstr "%s comentó la publicación de %s"
+#: include/features.php:86 mod/network.php:199 mod/search.php:34
+msgid "Saved Searches"
+msgstr "Búsquedas guardadas"
 
-#: include/NotificationsManager.php:243
-#, php-format
-msgid "%s created a new post"
-msgstr "%s creó una nueva publicación"
+#: include/features.php:86
+msgid "Save search terms for re-use"
+msgstr "Guardar términos de búsqueda para su reutilizacion"
 
-#: include/NotificationsManager.php:256
-#, php-format
-msgid "%s liked %s's post"
-msgstr "A %s le gusta la publicación de %s"
+#: include/features.php:91
+msgid "Network Tabs"
+msgstr "Pestañas de redes"
 
-#: include/NotificationsManager.php:267
-#, php-format
-msgid "%s disliked %s's post"
-msgstr "A %s no le gusta la publicación de %s"
+#: include/features.php:92
+msgid "Network Personal Tab"
+msgstr "Pestaña actividad personal"
 
-#: include/NotificationsManager.php:278
-#, php-format
-msgid "%s is attending %s's event"
-msgstr "%s está asistiendo al evento %s's"
+#: include/features.php:92
+msgid "Enable tab to display only Network posts that you've interacted on"
+msgstr "Habilitar para visualizar solo publicaciones con las que se ha interactuado"
 
-#: include/NotificationsManager.php:289
-#, php-format
-msgid "%s is not attending %s's event"
-msgstr "%s no está asistiendo al evento %s's"
+#: include/features.php:93
+msgid "Network New Tab"
+msgstr "Pestaña nuevo en la red"
 
-#: include/NotificationsManager.php:300
-#, php-format
-msgid "%s may attend %s's event"
-msgstr "%s podría asistir al evento %s's"
+#: include/features.php:93
+msgid "Enable tab to display only new Network posts (from the last 12 hours)"
+msgstr "Activar para mostrar solo publicaciones nuevas en la red (de las ultimas 12 horas)"
 
-#: include/NotificationsManager.php:315
-#, php-format
-msgid "%s is now friends with %s"
-msgstr "%s es ahora es amigo de %s"
+#: include/features.php:94
+msgid "Network Shared Links Tab"
+msgstr "Pestaña publicaciones con enlaces"
 
-#: include/NotificationsManager.php:748
-msgid "Friend Suggestion"
-msgstr "Propuestas de amistad"
+#: include/features.php:94
+msgid "Enable tab to display only Network posts with links in them"
+msgstr "Habilitar para visualizar solo publicaciones que contienen enlaces"
 
-#: include/NotificationsManager.php:781
-msgid "Friend/Connect Request"
-msgstr "Solicitud de Amistad/Conexión"
+#: include/features.php:99
+msgid "Post/Comment Tools"
+msgstr "Herramienta de publicaciones/respuestas"
 
-#: include/NotificationsManager.php:781
-msgid "New Follower"
-msgstr "Nuevo seguidor"
+#: include/features.php:100
+msgid "Multiple Deletion"
+msgstr "Borrar múltiples publicaciones"
 
-#: include/dbstructure.php:26
-#, php-format
-msgid ""
-"\n"
-"\t\t\tThe friendica developers released update %s recently,\n"
-"\t\t\tbut when I tried to install it, something went terribly wrong.\n"
-"\t\t\tThis needs to be fixed soon and I can't do it alone. Please contact a\n"
-"\t\t\tfriendica developer if you can not help me on your own. My database might be invalid."
-msgstr "\n\t\t\tLos desarolladores de friendica publicaron una actualización  %s recientemente\n\t\t\tpero cuando intento de instalarla,algo salio terriblemente mal.\n\t\t\tEsto necesita ser arreglado pronto y no puedo hacerlo solo. Por favor contacta\n\t\t\tlos desarolladores de friendica si no me podes ayudar por ti solo. Mi base de datos puede estar invalido."
+#: include/features.php:100
+msgid "Select and delete multiple posts/comments at once"
+msgstr "Habilidad de seleccionar y borrar varias publicaciones/comentarios a la vez"
 
-#: include/dbstructure.php:31
-#, php-format
-msgid ""
-"The error message is\n"
-"[pre]%s[/pre]"
-msgstr "El mensaje de error es\n[pre]%s[/pre]"
+#: include/features.php:101
+msgid "Edit Sent Posts"
+msgstr "Editar temas enviados"
 
-#: include/dbstructure.php:183
-msgid "Errors encountered creating database tables."
-msgstr "Se han encontrados errores creando las tablas de la base de datos."
+#: include/features.php:101
+msgid "Edit and correct posts and comments after sending"
+msgstr "Editar y corregir publicaciones y respuestas enviados. Las ediciones solo son comunicados dentro de la red friendica. No se modificaran copias enviadas a diaspora, OStatus/GNUsocial/Quitter u otros servicios conectados."
 
-#: include/dbstructure.php:260
-msgid "Errors encountered performing database changes."
-msgstr "Errores encontrados al ejecutar cambios en la base de datos."
+#: include/features.php:102
+msgid "Tagging"
+msgstr "taggear"
 
-#: include/delivery.php:446
-msgid "(no subject)"
-msgstr "(sin asunto)"
+#: include/features.php:102
+msgid "Ability to tag existing posts"
+msgstr "Habilidad de taggear publicaciones existentes"
 
-#: include/diaspora.php:1958
-msgid "Sharing notification from Diaspora network"
-msgstr "Compartir notificaciones con la red Diaspora*"
+#: include/features.php:103
+msgid "Post Categories"
+msgstr "Categorías de publicaciones"
 
-#: include/diaspora.php:2864
-msgid "Attachments:"
-msgstr "Archivos adjuntos:"
+#: include/features.php:103
+msgid "Add categories to your posts"
+msgstr "Agregue categorías a sus publicaciones. Las mismas serán visualizadas en su pagina de inicio."
 
-#: include/network.php:595
-msgid "view full size"
-msgstr "Ver a tamaño completo"
+#: include/features.php:104
+msgid "Ability to file posts under folders"
+msgstr "Archivar publicaciones en carpetas"
 
-#: include/Contact.php:340 include/Contact.php:353 include/Contact.php:398
-#: include/conversation.php:968 include/conversation.php:984
-#: mod/allfriends.php:65 mod/directory.php:155 mod/dirfind.php:203
-#: mod/match.php:71 mod/suggest.php:82
-msgid "View Profile"
-msgstr "Ver perfil"
+#: include/features.php:105
+msgid "Dislike Posts"
+msgstr "Desaprobar publicación (dislike)"
 
-#: include/Contact.php:397 include/conversation.php:967
-msgid "View Status"
-msgstr "Ver estado"
+#: include/features.php:105
+msgid "Ability to dislike posts/comments"
+msgstr "Habilidad de expresar desacuerdo en publicaciones y comentarios. Esta función solo es visualizado en la red friendica."
 
-#: include/Contact.php:399 include/conversation.php:969
-msgid "View Photos"
-msgstr "Ver fotos"
+#: include/features.php:106
+msgid "Star Posts"
+msgstr "Fijar publicaciones"
 
-#: include/Contact.php:400 include/conversation.php:970
-msgid "Network Posts"
-msgstr "Publicaciones en la red"
+#: include/features.php:106
+msgid "Ability to mark special posts with a star indicator"
+msgstr "Habilidad de marcar - observar fijamente publicaciones.\nEl simbolo de estrella es habilitado. Se recibirán notificaciones sobre comentarios, además una pestaña de publicaciones fijadas es habilitada. En las opciones de expiración de publicaciones se puede filtrar estas publicaciones para no ser eliminados contrario a las publicaciones demás de los contactos."
 
-#: include/Contact.php:401 include/conversation.php:971
-msgid "View Contact"
-msgstr "Ver contacto"
+#: include/features.php:107
+msgid "Mute Post Notifications"
+msgstr "Silenciar notificaciones de una publicacion"
 
-#: include/Contact.php:402
-msgid "Drop Contact"
-msgstr "Eliminar contacto"
+#: include/features.php:107
+msgid "Ability to mute notifications for a thread"
+msgstr "Habilidad de silenciar notificaciones sobre nuevos comentarios en una publicación."
 
-#: include/Contact.php:403 include/conversation.php:972
-msgid "Send PM"
-msgstr "Enviar mensaje privado"
+#: include/features.php:112
+msgid "Advanced Profile Settings"
+msgstr "Ajustes avanzados del perfil"
 
-#: include/Contact.php:404 include/conversation.php:976
-msgid "Poke"
-msgstr "Toque"
+#: include/features.php:113
+msgid "Show visitors public community forums at the Advanced Profile Page"
+msgstr "Mostrar a los visitantes foros públicos en las que se esta participando en el pagina avanzada de perfiles."
 
-#: include/Contact.php:775
-msgid "Organisation"
-msgstr "Organización"
+#: include/follow.php:81 mod/dfrn_request.php:512
+msgid "Disallowed profile URL."
+msgstr "Dirección de perfil no permitida."
 
-#: include/Contact.php:778
-msgid "News"
-msgstr "Noticias"
+#: include/follow.php:86
+msgid "Connect URL missing."
+msgstr "Falta el conector URL."
 
-#: include/Contact.php:781
-msgid "Forum"
-msgstr "Foro"
+#: include/follow.php:114
+msgid ""
+"This site is not configured to allow communications with other networks."
+msgstr "Este sitio no está configurado para permitir la comunicación con otras redes."
 
-#: include/api.php:1018
-#, php-format
-msgid "Daily posting limit of %d posts reached. The post was rejected."
-msgstr "Limite diario de publicaciones %d alcanzado. La publicación fue rechazada."
+#: include/follow.php:115 include/follow.php:129
+msgid "No compatible communication protocols or feeds were discovered."
+msgstr "No se ha descubierto protocolos de comunicación o fuentes compatibles."
 
-#: include/api.php:1038
-#, php-format
-msgid "Weekly posting limit of %d posts reached. The post was rejected."
-msgstr "Limite semanal de publicaciones %d alcanzado. La publicación fue rechazada."
+#: include/follow.php:127
+msgid "The profile address specified does not provide adequate information."
+msgstr "La dirección del perfil especificado no proporciona información adecuada."
 
-#: include/api.php:1059
-#, php-format
-msgid "Monthly posting limit of %d posts reached. The post was rejected."
-msgstr "Limite mensual de publicaciones %d alcanzado. La publicación fue rechazada."
+#: include/follow.php:132
+msgid "An author or name was not found."
+msgstr "No se ha encontrado un autor o nombre."
 
-#: include/bbcode.php:350 include/bbcode.php:1057 include/bbcode.php:1058
-msgid "Image/photo"
-msgstr "Imagen/Foto"
+#: include/follow.php:135
+msgid "No browser URL could be matched to this address."
+msgstr "Ninguna dirección concuerda con la suministrada."
 
-#: include/bbcode.php:467
-#, php-format
-msgid "<a href=\"%1$s\" target=\"_blank\">%2$s</a> %3$s"
-msgstr "<a href=\"%1$s\" target=\"_blank\">%2$s</a> %3$s"
+#: include/follow.php:138
+msgid ""
+"Unable to match @-style Identity Address with a known protocol or email "
+"contact."
+msgstr "Imposible identificar la dirección @ con algún protocolo conocido o dirección de contacto."
 
-#: include/bbcode.php:1017 include/bbcode.php:1037
-msgid "$1 wrote:"
-msgstr "$1 escribió:"
+#: include/follow.php:139
+msgid "Use mailto: in front of address to force email check."
+msgstr "Escribe mailto: al principio de la dirección para forzar el envío."
 
-#: include/bbcode.php:1066 include/bbcode.php:1067
-msgid "Encrypted content"
-msgstr "Contenido cifrado"
+#: include/follow.php:145
+msgid ""
+"The profile address specified belongs to a network which has been disabled "
+"on this site."
+msgstr "La dirección del perfil especificada pertenece a una red que ha sido deshabilitada en este sitio."
 
-#: include/bbcode.php:1169
-msgid "Invalid source protocol"
-msgstr "Protocolo de fuente inválido"
+#: include/follow.php:150
+msgid ""
+"Limited profile. This person will be unable to receive direct/personal "
+"notifications from you."
+msgstr "Perfil limitado. Esta persona no podrá recibir notificaciones directas/personales tuyas."
 
-#: include/bbcode.php:1179
-msgid "Invalid link protocol"
-msgstr "Protocolo de enlace inválido"
+#: include/follow.php:251
+msgid "Unable to retrieve contact information."
+msgstr "No ha sido posible recibir la información del contacto."
 
-#: include/conversation.php:147
-#, php-format
-msgid "%1$s attends %2$s's %3$s"
-msgstr "%1$s atenderá %2$s's %3$s"
+#: include/group.php:25
+msgid ""
+"A deleted group with this name was revived. Existing item permissions "
+"<strong>may</strong> apply to this group and any future members. If this is "
+"not what you intended, please create another group with a different name."
+msgstr "Un grupo eliminado con este nombre fue restablecido. Los permisos existentes <strong>pueden</strong> aplicarse a este grupo y a sus futuros miembros. Si esto no es lo que pretendes, por favor, crea otro grupo con un nombre diferente."
 
-#: include/conversation.php:150
-#, php-format
-msgid "%1$s doesn't attend %2$s's %3$s"
-msgstr "%1$s no atenderá %2$s's %3$s"
+#: include/group.php:210
+msgid "Default privacy group for new contacts"
+msgstr "Grupo por defecto para nuevos contactos"
 
-#: include/conversation.php:153
-#, php-format
-msgid "%1$s attends maybe %2$s's %3$s"
-msgstr "%1$s atenderá quizás %2$s's %3$s"
+#: include/group.php:243
+msgid "Everybody"
+msgstr "Todo el mundo"
 
-#: include/conversation.php:185 mod/dfrn_confirm.php:477
-#, php-format
-msgid "%1$s is now friends with %2$s"
-msgstr "%1$s ahora es amigo de %2$s"
+#: include/group.php:266
+msgid "edit"
+msgstr "editar"
 
-#: include/conversation.php:219
-#, php-format
-msgid "%1$s poked %2$s"
-msgstr "%1$s le dio un toque a %2$s"
+#: include/group.php:287 mod/newmember.php:61
+msgid "Groups"
+msgstr "Grupos"
 
-#: include/conversation.php:239 mod/mood.php:62
-#, php-format
-msgid "%1$s is currently %2$s"
-msgstr "%1$s está actualmente %2$s"
+#: include/group.php:289
+msgid "Edit groups"
+msgstr "Editar grupo"
 
-#: include/conversation.php:278 mod/tagger.php:95
-#, php-format
-msgid "%1$s tagged %2$s's %3$s with %4$s"
-msgstr "%1$s ha etiquetado el %3$s de %2$s con %4$s"
+#: include/group.php:291
+msgid "Edit group"
+msgstr "Editar grupo"
 
-#: include/conversation.php:303
-msgid "post/item"
-msgstr "publicación/tema"
+#: include/group.php:292
+msgid "Create a new group"
+msgstr "Crear un nuevo grupo"
 
-#: include/conversation.php:304
-#, php-format
-msgid "%1$s marked %2$s's %3$s as favorite"
-msgstr "%1$s ha marcado %3$s de %2$s como Favorito"
+#: include/group.php:293 mod/group.php:98 mod/group.php:188
+msgid "Group Name: "
+msgstr "Nombre del grupo: "
 
-#: include/conversation.php:585 mod/content.php:372 mod/profiles.php:346
-#: mod/photos.php:1607
-msgid "Likes"
-msgstr "Me gusta"
+#: include/group.php:295
+msgid "Contacts not in any group"
+msgstr "Contactos sin grupo"
 
-#: include/conversation.php:585 mod/content.php:372 mod/profiles.php:350
-#: mod/photos.php:1607
-msgid "Dislikes"
-msgstr "No me gusta"
+#: include/group.php:297 mod/network.php:200
+msgid "add"
+msgstr "añadir"
 
-#: include/conversation.php:586 include/conversation.php:1481
-#: mod/content.php:373 mod/photos.php:1608
-msgid "Attending"
-msgid_plural "Attending"
-msgstr[0] "Atendiendo"
-msgstr[1] "Atendiendo"
+#: include/identity.php:43
+msgid "Requested account is not available."
+msgstr "La cuenta solicitada no está disponible."
 
-#: include/conversation.php:586 mod/content.php:373 mod/photos.php:1608
-msgid "Not attending"
-msgstr "No atendiendo"
+#: include/identity.php:52 mod/profile.php:21
+msgid "Requested profile is not available."
+msgstr "El perfil solicitado no está disponible."
 
-#: include/conversation.php:586 mod/content.php:373 mod/photos.php:1608
-msgid "Might attend"
-msgstr "Puede que atienda"
+#: include/identity.php:96 include/identity.php:314 include/identity.php:737
+msgid "Edit profile"
+msgstr "Editar perfil"
 
-#: include/conversation.php:708 mod/content.php:453 mod/content.php:758
-#: mod/photos.php:1681 object/Item.php:133
-msgid "Select"
-msgstr "Seleccionar"
+#: include/identity.php:254
+msgid "Atom feed"
+msgstr "Atom feed"
 
-#: include/conversation.php:709 mod/group.php:171 mod/content.php:454
-#: mod/content.php:759 mod/photos.php:1682 mod/settings.php:741
-#: mod/admin.php:1414 mod/contacts.php:808 mod/contacts.php:1007
-#: object/Item.php:134
-msgid "Delete"
-msgstr "Eliminar"
+#: include/identity.php:285 include/nav.php:189
+msgid "Profiles"
+msgstr "Perfiles"
 
-#: include/conversation.php:753 mod/content.php:487 mod/content.php:910
-#: mod/content.php:911 object/Item.php:367 object/Item.php:368
-#, php-format
-msgid "View %s's profile @ %s"
-msgstr "Ver perfil de %s @ %s"
+#: include/identity.php:285
+msgid "Manage/edit profiles"
+msgstr "Administrar/editar perfiles"
 
-#: include/conversation.php:765 object/Item.php:355
-msgid "Categories:"
-msgstr "Categorías:"
+#: include/identity.php:290 include/identity.php:316 mod/profiles.php:789
+msgid "Change profile photo"
+msgstr "Cambiar foto del perfil"
 
-#: include/conversation.php:766 object/Item.php:356
-msgid "Filed under:"
-msgstr "Archivado en:"
+#: include/identity.php:291 mod/profiles.php:790
+msgid "Create New Profile"
+msgstr "Crear nuevo perfil"
 
-#: include/conversation.php:773 mod/content.php:497 mod/content.php:923
-#: object/Item.php:381
-#, php-format
-msgid "%s from %s"
-msgstr "%s de %s"
+#: include/identity.php:301 mod/profiles.php:779
+msgid "Profile Image"
+msgstr "Imagen del Perfil"
 
-#: include/conversation.php:789 mod/content.php:513
-msgid "View in context"
-msgstr "Verlo en contexto"
+#: include/identity.php:304 mod/profiles.php:781
+msgid "visible to everybody"
+msgstr "Visible para todos"
 
-#: include/conversation.php:791 include/conversation.php:1264
-#: mod/editpost.php:124 mod/wallmessage.php:156 mod/message.php:356
-#: mod/message.php:548 mod/content.php:515 mod/content.php:948
-#: mod/photos.php:1570 object/Item.php:406
-msgid "Please wait"
-msgstr "Por favor, espera"
+#: include/identity.php:305 mod/profiles.php:683 mod/profiles.php:782
+msgid "Edit visibility"
+msgstr "Editar visibilidad"
 
-#: include/conversation.php:870
-msgid "remove"
-msgstr "eliminar"
+#: include/identity.php:333 include/identity.php:628 mod/directory.php:141
+#: mod/notifications.php:244
+msgid "Gender:"
+msgstr "Género:"
 
-#: include/conversation.php:874
-msgid "Delete Selected Items"
-msgstr "Eliminar el elemento seleccionado"
+#: include/identity.php:336 include/identity.php:648 mod/directory.php:143
+msgid "Status:"
+msgstr "Estado:"
 
-#: include/conversation.php:966
-msgid "Follow Thread"
-msgstr "Seguir publicacion"
+#: include/identity.php:338 include/identity.php:664 mod/directory.php:145
+msgid "Homepage:"
+msgstr "Página de inicio:"
 
-#: include/conversation.php:1097
-#, php-format
-msgid "%s likes this."
-msgstr "A %s le gusta esto."
+#: include/identity.php:340 include/identity.php:684 mod/contacts.php:640
+#: mod/directory.php:147 mod/notifications.php:240
+msgid "About:"
+msgstr "Acerca de:"
 
-#: include/conversation.php:1100
-#, php-format
-msgid "%s doesn't like this."
-msgstr "A %s no le gusta esto."
+#: include/identity.php:342 mod/contacts.php:638
+msgid "XMPP:"
+msgstr "XMPP:"
 
-#: include/conversation.php:1103
-#, php-format
-msgid "%s attends."
-msgstr "%s atiende."
+#: include/identity.php:428 mod/contacts.php:55 mod/notifications.php:252
+msgid "Network:"
+msgstr "Red:"
 
-#: include/conversation.php:1106
-#, php-format
-msgid "%s doesn't attend."
-msgstr "%s no atenderá."
+#: include/identity.php:457 include/identity.php:547
+msgid "g A l F d"
+msgstr "g A l F d"
 
-#: include/conversation.php:1109
-#, php-format
-msgid "%s attends maybe."
-msgstr "%s quizás atenderá"
+#: include/identity.php:458 include/identity.php:548
+msgid "F d"
+msgstr "F d"
 
-#: include/conversation.php:1119
-msgid "and"
-msgstr "y"
+#: include/identity.php:509 include/identity.php:594
+msgid "[today]"
+msgstr "[hoy]"
 
-#: include/conversation.php:1125
-#, php-format
-msgid ", and %d other people"
-msgstr " y a otras %d personas"
+#: include/identity.php:521
+msgid "Birthday Reminders"
+msgstr "Recordatorios de cumpleaños"
 
-#: include/conversation.php:1134
-#, php-format
-msgid "<span  %1$s>%2$d people</span> like this"
-msgstr "<span  %1$s>%2$d personas</span> les gusta esto"
+#: include/identity.php:522
+msgid "Birthdays this week:"
+msgstr "Cumpleaños esta semana:"
 
-#: include/conversation.php:1135
-#, php-format
-msgid "%s like this."
-msgstr "A %s le gusta esto."
+#: include/identity.php:581
+msgid "[No description]"
+msgstr "[Sin descripción]"
 
-#: include/conversation.php:1138
-#, php-format
-msgid "<span  %1$s>%2$d people</span> don't like this"
-msgstr "<span  %1$s>%2$d personas</span> no les gusta esto"
+#: include/identity.php:605
+msgid "Event Reminders"
+msgstr "Recordatorios de eventos"
 
-#: include/conversation.php:1139
-#, php-format
-msgid "%s don't like this."
-msgstr "A %s no le gusta esto."
+#: include/identity.php:606
+msgid "Events this week:"
+msgstr "Eventos de esta semana:"
 
-#: include/conversation.php:1142
-#, php-format
-msgid "<span  %1$s>%2$d people</span> attend"
-msgstr "<span  %1$s>%2$d personas</span> atienden"
+#: include/identity.php:617 include/identity.php:741 include/identity.php:774
+#: include/nav.php:82 mod/contacts.php:647 mod/contacts.php:849
+#: mod/newmember.php:32 mod/profperm.php:105 view/theme/frio/theme.php:247
+msgid "Profile"
+msgstr "Perfil"
 
-#: include/conversation.php:1143
-#, php-format
-msgid "%s attend."
-msgstr "%s atiende."
+#: include/identity.php:626 mod/settings.php:1286
+msgid "Full Name:"
+msgstr "Nombre completo:"
 
-#: include/conversation.php:1146
-#, php-format
-msgid "<span  %1$s>%2$d people</span> don't attend"
-msgstr "<span  %1$s>%2$d personas</span>no atienden"
+#: include/identity.php:633
+msgid "j F, Y"
+msgstr "j F, Y"
 
-#: include/conversation.php:1147
-#, php-format
-msgid "%s don't attend."
-msgstr "%s no atiende."
+#: include/identity.php:634
+msgid "j F"
+msgstr "j F"
 
-#: include/conversation.php:1150
-#, php-format
-msgid "<span  %1$s>%2$d people</span> attend maybe"
-msgstr "<span  %1$s>%2$d people</span> quizá asistan"
+#: include/identity.php:645
+msgid "Age:"
+msgstr "Edad:"
 
-#: include/conversation.php:1151
+#: include/identity.php:656
 #, php-format
-msgid "%s anttend maybe."
-msgstr "%s atiende quizás."
-
-#: include/conversation.php:1190 include/conversation.php:1208
-msgid "Visible to <strong>everybody</strong>"
-msgstr "Visible para <strong>cualquiera</strong>"
-
-#: include/conversation.php:1191 include/conversation.php:1209
-#: mod/wallmessage.php:127 mod/wallmessage.php:135 mod/message.php:291
-#: mod/message.php:299 mod/message.php:442 mod/message.php:450
-msgid "Please enter a link URL:"
-msgstr "Introduce la dirección del enlace:"
+msgid "for %1$d %2$s"
+msgstr "por %1$d %2$s"
 
-#: include/conversation.php:1192 include/conversation.php:1210
-msgid "Please enter a video link/URL:"
-msgstr "Por favor, introduce la URL/enlace del vídeo:"
+#: include/identity.php:660 mod/profiles.php:702
+msgid "Sexual Preference:"
+msgstr "Preferencia sexual:"
 
-#: include/conversation.php:1193 include/conversation.php:1211
-msgid "Please enter an audio link/URL:"
-msgstr "Por favor, introduce la URL/enlace del audio:"
+#: include/identity.php:668 mod/profiles.php:729
+msgid "Hometown:"
+msgstr "Ciudad de origen:"
 
-#: include/conversation.php:1194 include/conversation.php:1212
-msgid "Tag term:"
-msgstr "Etiquetar:"
+#: include/identity.php:672 mod/contacts.php:642 mod/follow.php:137
+#: mod/notifications.php:242
+msgid "Tags:"
+msgstr "Etiquetas:"
 
-#: include/conversation.php:1195 include/conversation.php:1213
-#: mod/filer.php:30
-msgid "Save to Folder:"
-msgstr "Guardar en directorio:"
+#: include/identity.php:676 mod/profiles.php:730
+msgid "Political Views:"
+msgstr "Ideas políticas:"
 
-#: include/conversation.php:1196 include/conversation.php:1214
-msgid "Where are you right now?"
-msgstr "¿Dónde estás ahora?"
+#: include/identity.php:680
+msgid "Religion:"
+msgstr "Religión:"
 
-#: include/conversation.php:1197
-msgid "Delete item(s)?"
-msgstr "¿Borrar objeto(s)?"
+#: include/identity.php:688
+msgid "Hobbies/Interests:"
+msgstr "Aficiones/Intereses:"
 
-#: include/conversation.php:1245 mod/photos.php:1569
-msgid "Share"
-msgstr "Compartir"
+#: include/identity.php:692 mod/profiles.php:734
+msgid "Likes:"
+msgstr "Me gusta:"
 
-#: include/conversation.php:1246 mod/editpost.php:110 mod/wallmessage.php:154
-#: mod/message.php:354 mod/message.php:545
-msgid "Upload photo"
-msgstr "Subir foto"
+#: include/identity.php:696 mod/profiles.php:735
+msgid "Dislikes:"
+msgstr "No me gusta:"
 
-#: include/conversation.php:1247 mod/editpost.php:111
-msgid "upload photo"
-msgstr "subir imagen"
+#: include/identity.php:700
+msgid "Contact information and Social Networks:"
+msgstr "Información de contacto y Redes sociales:"
 
-#: include/conversation.php:1248 mod/editpost.php:112
-msgid "Attach file"
-msgstr "Adjuntar archivo"
+#: include/identity.php:704
+msgid "Musical interests:"
+msgstr "Intereses musicales:"
 
-#: include/conversation.php:1249 mod/editpost.php:113
-msgid "attach file"
-msgstr "adjuntar archivo"
+#: include/identity.php:708
+msgid "Books, literature:"
+msgstr "Libros, literatura:"
 
-#: include/conversation.php:1250 mod/editpost.php:114 mod/wallmessage.php:155
-#: mod/message.php:355 mod/message.php:546
-msgid "Insert web link"
-msgstr "Insertar enlace"
+#: include/identity.php:712
+msgid "Television:"
+msgstr "Televisión:"
 
-#: include/conversation.php:1251 mod/editpost.php:115
-msgid "web link"
-msgstr "enlace web"
+#: include/identity.php:716
+msgid "Film/dance/culture/entertainment:"
+msgstr "Películas/baile/cultura/entretenimiento:"
 
-#: include/conversation.php:1252 mod/editpost.php:116
-msgid "Insert video link"
-msgstr "Insertar enlace del vídeo"
+#: include/identity.php:720
+msgid "Love/Romance:"
+msgstr "Amor/Romance:"
 
-#: include/conversation.php:1253 mod/editpost.php:117
-msgid "video link"
-msgstr "enlace de video"
+#: include/identity.php:724
+msgid "Work/employment:"
+msgstr "Trabajo/ocupación:"
 
-#: include/conversation.php:1254 mod/editpost.php:118
-msgid "Insert audio link"
-msgstr "Insertar vínculo del audio"
+#: include/identity.php:728
+msgid "School/education:"
+msgstr "Escuela/estudios:"
 
-#: include/conversation.php:1255 mod/editpost.php:119
-msgid "audio link"
-msgstr "enlace de audio"
+#: include/identity.php:733
+msgid "Forums:"
+msgstr "Foros:"
 
-#: include/conversation.php:1256 mod/editpost.php:120
-msgid "Set your location"
-msgstr "Configurar tu localización"
+#: include/identity.php:742 mod/events.php:514
+msgid "Basic"
+msgstr "Basic"
 
-#: include/conversation.php:1257 mod/editpost.php:121
-msgid "set location"
-msgstr "establecer tu ubicación"
+#: include/identity.php:743 mod/admin.php:972 mod/contacts.php:878
+#: mod/events.php:515
+msgid "Advanced"
+msgstr "Avanzado"
 
-#: include/conversation.php:1258 mod/editpost.php:122
-msgid "Clear browser location"
-msgstr "Borrar la localización del navegador"
+#: include/identity.php:766 include/nav.php:81 mod/contacts.php:645
+#: mod/contacts.php:841 view/theme/frio/theme.php:246
+msgid "Status"
+msgstr "Estado"
 
-#: include/conversation.php:1259 mod/editpost.php:123
-msgid "clear location"
-msgstr "limpiar la localización"
+#: include/identity.php:769 mod/contacts.php:844 mod/follow.php:145
+msgid "Status Messages and Posts"
+msgstr "Mensajes de Estado y Publicaciones"
 
-#: include/conversation.php:1261 mod/editpost.php:137
-msgid "Set title"
-msgstr "Establecer el título"
+#: include/identity.php:777 mod/contacts.php:852
+msgid "Profile Details"
+msgstr "Detalles del Perfil"
 
-#: include/conversation.php:1263 mod/editpost.php:139
-msgid "Categories (comma-separated list)"
-msgstr "Categorías (lista separada por comas)"
+#: include/identity.php:782 include/nav.php:83 mod/fbrowser.php:31
+#: view/theme/frio/theme.php:248
+msgid "Photos"
+msgstr "Fotografías"
 
-#: include/conversation.php:1265 mod/editpost.php:125
-msgid "Permission settings"
-msgstr "Configuración de permisos"
+#: include/identity.php:785 mod/photos.php:89
+msgid "Photo Albums"
+msgstr "Álbum de Fotos"
 
-#: include/conversation.php:1266 mod/editpost.php:154
-msgid "permissions"
-msgstr "permisos"
+#: include/identity.php:790 include/identity.php:793 include/nav.php:84
+#: view/theme/frio/theme.php:249
+msgid "Videos"
+msgstr "Videos"
 
-#: include/conversation.php:1274 mod/editpost.php:134
-msgid "Public post"
-msgstr "Publicación pública"
+#: include/identity.php:802 include/identity.php:813 include/nav.php:85
+#: include/nav.php:149 mod/cal.php:270 mod/events.php:386
+#: view/theme/frio/theme.php:250 view/theme/frio/theme.php:254
+msgid "Events"
+msgstr "Eventos"
 
-#: include/conversation.php:1279 mod/editpost.php:145 mod/content.php:737
-#: mod/events.php:504 mod/photos.php:1591 mod/photos.php:1639
-#: mod/photos.php:1725 object/Item.php:729
-msgid "Preview"
-msgstr "Vista previa"
+#: include/identity.php:805 include/identity.php:816 include/nav.php:149
+#: view/theme/frio/theme.php:254
+msgid "Events and Calendar"
+msgstr "Eventos y Calendario"
 
-#: include/conversation.php:1283 include/items.php:1974 mod/fbrowser.php:101
-#: mod/fbrowser.php:136 mod/tagrm.php:11 mod/tagrm.php:94 mod/editpost.php:148
-#: mod/message.php:220 mod/suggest.php:32 mod/photos.php:235
-#: mod/photos.php:322 mod/settings.php:679 mod/settings.php:705
-#: mod/videos.php:128 mod/contacts.php:445 mod/dfrn_request.php:876
-#: mod/follow.php:121
-msgid "Cancel"
-msgstr "Cancelar"
+#: include/identity.php:824 mod/notes.php:47
+msgid "Personal Notes"
+msgstr "Notas personales"
 
-#: include/conversation.php:1289
-msgid "Post to Groups"
-msgstr "Publicar hacia grupos"
+#: include/identity.php:827
+msgid "Only You Can See This"
+msgstr "Únicamente tú puedes ver esto"
 
-#: include/conversation.php:1290
-msgid "Post to Contacts"
-msgstr "Publicar hacia contactos"
+#: include/identity.php:835 include/identity.php:838 include/nav.php:128
+#: include/nav.php:192 include/text.php:1024 mod/contacts.php:800
+#: mod/contacts.php:861 mod/viewcontacts.php:121 view/theme/frio/theme.php:257
+msgid "Contacts"
+msgstr "Contactos"
 
-#: include/conversation.php:1291
-msgid "Private post"
-msgstr "Publicación privada"
+#: include/items.php:1584 mod/dfrn_confirm.php:735 mod/dfrn_request.php:754
+msgid "[Name Withheld]"
+msgstr "[Nombre oculto]"
 
-#: include/conversation.php:1296 include/identity.php:256 mod/editpost.php:152
-msgid "Message"
-msgstr "Mensaje"
+#: include/items.php:1939 mod/admin.php:240 mod/admin.php:1480
+#: mod/admin.php:1731 mod/display.php:103 mod/display.php:279
+#: mod/display.php:484 mod/notice.php:15 mod/viewsrc.php:15
+msgid "Item not found."
+msgstr "Elemento no encontrado."
 
-#: include/conversation.php:1297 mod/editpost.php:153
-msgid "Browser"
-msgstr "Navegador"
+#: include/items.php:1978
+msgid "Do you really want to delete this item?"
+msgstr "¿Realmente quieres borrar este objeto?"
 
-#: include/conversation.php:1453
-msgid "View all"
-msgstr "Ver todos los contactos"
+#: include/items.php:1980 mod/api.php:105 mod/contacts.php:452
+#: mod/dfrn_request.php:875 mod/follow.php:113 mod/message.php:206
+#: mod/profiles.php:640 mod/profiles.php:643 mod/profiles.php:669
+#: mod/register.php:245 mod/settings.php:1171 mod/settings.php:1177
+#: mod/settings.php:1184 mod/settings.php:1188 mod/settings.php:1193
+#: mod/settings.php:1198 mod/settings.php:1203 mod/settings.php:1208
+#: mod/settings.php:1234 mod/settings.php:1235 mod/settings.php:1236
+#: mod/settings.php:1237 mod/settings.php:1238 mod/suggest.php:29
+msgid "Yes"
+msgstr "Sí"
 
-#: include/conversation.php:1475
-msgid "Like"
-msgid_plural "Likes"
-msgstr[0] "Me gusta"
-msgstr[1] "Me gusta"
+#: include/items.php:2143 index.php:407 mod/allfriends.php:12 mod/api.php:26
+#: mod/api.php:31 mod/attach.php:33 mod/cal.php:299 mod/common.php:18
+#: mod/contacts.php:360 mod/crepair.php:102 mod/delegate.php:12
+#: mod/dfrn_confirm.php:61 mod/dirfind.php:11 mod/display.php:481
+#: mod/editpost.php:10 mod/events.php:195 mod/follow.php:11 mod/follow.php:74
+#: mod/follow.php:158 mod/fsuggest.php:79 mod/group.php:19 mod/invite.php:15
+#: mod/invite.php:103 mod/item.php:193 mod/item.php:205 mod/manage.php:98
+#: mod/message.php:46 mod/message.php:171 mod/mood.php:115 mod/network.php:4
+#: mod/nogroup.php:27 mod/notes.php:23 mod/notifications.php:71
+#: mod/ostatus_subscribe.php:9 mod/photos.php:161 mod/photos.php:1092
+#: mod/poke.php:154 mod/profile_photo.php:19 mod/profile_photo.php:180
+#: mod/profile_photo.php:191 mod/profile_photo.php:204 mod/profiles.php:166
+#: mod/profiles.php:607 mod/register.php:42 mod/regmod.php:113
+#: mod/repair_ostatus.php:9 mod/settings.php:22 mod/settings.php:130
+#: mod/settings.php:668 mod/suggest.php:58 mod/uimport.php:24
+#: mod/viewcontacts.php:46 mod/wall_attach.php:67 mod/wall_attach.php:70
+#: mod/wall_upload.php:77 mod/wall_upload.php:80 mod/wallmessage.php:9
+#: mod/wallmessage.php:33 mod/wallmessage.php:73 mod/wallmessage.php:97
+msgid "Permission denied."
+msgstr "Permiso denegado."
 
-#: include/conversation.php:1478
-msgid "Dislike"
-msgid_plural "Dislikes"
-msgstr[0] "No me gusta"
-msgstr[1] "No me gusta"
+#: include/items.php:2248
+msgid "Archives"
+msgstr "Archivos"
 
-#: include/conversation.php:1484
-msgid "Not Attending"
-msgid_plural "Not Attending"
-msgstr[0] "No atendiendo"
-msgstr[1] "No atendiendo"
+#: include/like.php:41
+#, php-format
+msgid "%1$s is attending %2$s's %3$s"
+msgstr "%1$s atenderá %2$s's %3$s"
 
-#: include/dfrn.php:1108
+#: include/like.php:46
 #, php-format
-msgid "%s\\'s birthday"
-msgstr "%s\\'s cumpleaños"
+msgid "%1$s is not attending %2$s's %3$s"
+msgstr "%1$s no atenderá %2$s's %3$s"
 
-#: include/features.php:70
-msgid "General Features"
-msgstr "Opciones generales"
+#: include/like.php:51
+#, php-format
+msgid "%1$s may attend %2$s's %3$s"
+msgstr "%1$s puede que atienda %2$s's %3$s"
 
-#: include/features.php:72
-msgid "Multiple Profiles"
-msgstr "Perfiles multiples"
+#: include/message.php:15 include/message.php:169
+msgid "[no subject]"
+msgstr "[sin asunto]"
 
-#: include/features.php:72
-msgid "Ability to create multiple profiles"
-msgstr "Capacidad de crear perfiles multiples. Cada pagina/perfil/usuario puede tener diferentes perfiles/apariencias. Las mismas pueden ser visibles para determinados contactos seleccionados dentro de la red friendica."
+#: include/nav.php:35 mod/navigation.php:19
+msgid "Nothing new here"
+msgstr "Nada nuevo por aquí"
 
-#: include/features.php:73
-msgid "Photo Location"
-msgstr "Localización foto"
+#: include/nav.php:39 mod/navigation.php:23
+msgid "Clear notifications"
+msgstr "Limpiar notificaciones"
 
-#: include/features.php:73
-msgid ""
-"Photo metadata is normally stripped. This extracts the location (if present)"
-" prior to stripping metadata and links it to a map."
-msgstr "Normalmente los meta datos de las imágenes son eliminados. Esto extraerá la localización si presente antes de eliminar los meta datos y enlaza la misma con el mapa."
+#: include/nav.php:40 include/text.php:1017
+msgid "@name, !forum, #tags, content"
+msgstr "@name, !forum, #tags, contenido"
 
-#: include/features.php:74
-msgid "Export Public Calendar"
-msgstr "Exportar Calendario Público"
+#: include/nav.php:78 view/theme/frio/theme.php:243
+msgid "End this session"
+msgstr "Cerrar la sesión"
 
-#: include/features.php:74
-msgid "Ability for visitors to download the public calendar"
-msgstr "Posibilidad de los visitantes de descargar el calendario público"
+#: include/nav.php:81 include/nav.php:161 view/theme/frio/theme.php:246
+msgid "Your posts and conversations"
+msgstr "Tus publicaciones y conversaciones"
 
-#: include/features.php:79
-msgid "Post Composition Features"
-msgstr "Opciones de edición de publicaciones."
+#: include/nav.php:82 view/theme/frio/theme.php:247
+msgid "Your profile page"
+msgstr "Tu página de perfil"
 
-#: include/features.php:80
-msgid "Richtext Editor"
-msgstr "Editor de texto sofisticado (richt text editor)"
+#: include/nav.php:83 view/theme/frio/theme.php:248
+msgid "Your photos"
+msgstr "Tus fotos"
 
-#: include/features.php:80
-msgid "Enable richtext editor"
-msgstr "Habilitar editor de textos sofisticado"
+#: include/nav.php:84 view/theme/frio/theme.php:249
+msgid "Your videos"
+msgstr "Tus videos"
 
-#: include/features.php:81
-msgid "Post Preview"
-msgstr "Previsualizar publicaciones"
+#: include/nav.php:85 view/theme/frio/theme.php:250
+msgid "Your events"
+msgstr "Tus eventos"
 
-#: include/features.php:81
-msgid "Allow previewing posts and comments before publishing them"
-msgstr "Permitir la previsualización de publicaciones antes de publicar las mismas."
+#: include/nav.php:86
+msgid "Personal notes"
+msgstr "Notas personales"
 
-#: include/features.php:82
-msgid "Auto-mention Forums"
-msgstr "Auto-mencionar foros"
+#: include/nav.php:86
+msgid "Your personal notes"
+msgstr "Tus notas personales"
 
-#: include/features.php:82
-msgid ""
-"Add/remove mention when a forum page is selected/deselected in ACL window."
-msgstr "Añadir/eliminar mención cuando un foro es seleccionado/deseleccionado en la ventana ACL."
+#: include/nav.php:95
+msgid "Sign in"
+msgstr "Date de alta"
 
-#: include/features.php:87
-msgid "Network Sidebar Widgets"
-msgstr "Accesorios de red del panel lateral"
+#: include/nav.php:105
+msgid "Home Page"
+msgstr "Página de inicio"
 
-#: include/features.php:88
-msgid "Search by Date"
-msgstr "Buscar por fecha"
+#: include/nav.php:109
+msgid "Create an account"
+msgstr "Crea una cuenta"
 
-#: include/features.php:88
-msgid "Ability to select posts by date ranges"
-msgstr "Habilidad de seleccionar publicaciones por fecha"
+#: include/nav.php:115 mod/help.php:47 view/theme/vier/theme.php:293
+msgid "Help"
+msgstr "Ayuda"
 
-#: include/features.php:89 include/features.php:119
-msgid "List Forums"
-msgstr "Listar foros"
+#: include/nav.php:115
+msgid "Help and documentation"
+msgstr "Ayuda y documentación"
 
-#: include/features.php:89
-msgid "Enable widget to display the forums your are connected with"
-msgstr "Habilitar la pestaña para mostrar los foros en que estas participando."
+#: include/nav.php:119
+msgid "Apps"
+msgstr "Aplicaciones"
 
-#: include/features.php:90
-msgid "Group Filter"
-msgstr "Filtro del grupo"
+#: include/nav.php:119
+msgid "Addon applications, utilities, games"
+msgstr "Aplicaciones, utilidades, juegos"
 
-#: include/features.php:90
-msgid "Enable widget to display Network posts only from selected group"
-msgstr "Habilitar accesorios para visualizar publicaciones en la red solo de grupos seleccionados"
+#: include/nav.php:123 include/text.php:1014 mod/search.php:149
+msgid "Search"
+msgstr "Buscar"
 
-#: include/features.php:91
-msgid "Network Filter"
-msgstr "Filtro de red"
+#: include/nav.php:123
+msgid "Search site content"
+msgstr " Busca contenido en la página"
 
-#: include/features.php:91
-msgid "Enable widget to display Network posts only from selected network"
-msgstr "Habilitar accesorios para visualizar publicaciones solo de las redes seleccionadas."
+#: include/nav.php:126 include/text.php:1022
+msgid "Full Text"
+msgstr "Texto completo"
 
-#: include/features.php:92 mod/search.php:34 mod/network.php:200
-msgid "Saved Searches"
-msgstr "Búsquedas guardadas"
+#: include/nav.php:127 include/text.php:1023
+msgid "Tags"
+msgstr "Tags"
 
-#: include/features.php:92
-msgid "Save search terms for re-use"
-msgstr "Guardar términos de búsqueda para su reutilizacion"
+#: include/nav.php:143 include/nav.php:145 mod/community.php:36
+msgid "Community"
+msgstr "Comunidad"
 
-#: include/features.php:97
-msgid "Network Tabs"
-msgstr "Pestañas de redes"
+#: include/nav.php:143
+msgid "Conversations on this site"
+msgstr "Conversaciones en este sitio"
 
-#: include/features.php:98
-msgid "Network Personal Tab"
-msgstr "Pestaña actividad personal"
+#: include/nav.php:145
+msgid "Conversations on the network"
+msgstr "Conversaciones en la red"
 
-#: include/features.php:98
-msgid "Enable tab to display only Network posts that you've interacted on"
-msgstr "Habilitar para visualizar solo publicaciones con las que se ha interactuado"
+#: include/nav.php:152
+msgid "Directory"
+msgstr "Directorio"
 
-#: include/features.php:99
-msgid "Network New Tab"
-msgstr "Pestaña nuevo en la red"
+#: include/nav.php:152
+msgid "People directory"
+msgstr "Directorio de usuarios"
 
-#: include/features.php:99
-msgid "Enable tab to display only new Network posts (from the last 12 hours)"
-msgstr "Activar para mostrar solo publicaciones nuevas en la red (de las ultimas 12 horas)"
+#: include/nav.php:154
+msgid "Information"
+msgstr "Información"
 
-#: include/features.php:100
-msgid "Network Shared Links Tab"
-msgstr "Pestaña publicaciones con enlaces"
+#: include/nav.php:154
+msgid "Information about this friendica instance"
+msgstr "Información sobre esta instancia de friendica"
 
-#: include/features.php:100
-msgid "Enable tab to display only Network posts with links in them"
-msgstr "Habilitar para visualizar solo publicaciones que contienen enlaces"
+#: include/nav.php:158 view/theme/frio/theme.php:253
+msgid "Conversations from your friends"
+msgstr "Conversaciones de tus amigos"
 
-#: include/features.php:105
-msgid "Post/Comment Tools"
-msgstr "Herramienta de publicaciones/respuestas"
+#: include/nav.php:159
+msgid "Network Reset"
+msgstr "Reseteo de la red"
 
-#: include/features.php:106
-msgid "Multiple Deletion"
-msgstr "Borrar múltiples publicaciones"
+#: include/nav.php:159
+msgid "Load Network page with no filters"
+msgstr "Cargar pagina de redes sin filtros"
 
-#: include/features.php:106
-msgid "Select and delete multiple posts/comments at once"
-msgstr "Habilidad de seleccionar y borrar varias publicaciones/comentarios a la vez"
+#: include/nav.php:166
+msgid "Friend Requests"
+msgstr "Solicitudes de amistad"
 
-#: include/features.php:107
-msgid "Edit Sent Posts"
-msgstr "Editar temas enviados"
+#: include/nav.php:169 mod/notifications.php:96
+msgid "Notifications"
+msgstr "Notificaciones"
 
-#: include/features.php:107
-msgid "Edit and correct posts and comments after sending"
-msgstr "Editar y corregir publicaciones y respuestas enviados. Las ediciones solo son comunicados dentro de la red friendica. No se modificaran copias enviadas a diaspora, OStatus/GNUsocial/Quitter u otros servicios conectados."
+#: include/nav.php:170
+msgid "See all notifications"
+msgstr "Ver todas las notificaciones"
 
-#: include/features.php:108
-msgid "Tagging"
-msgstr "taggear"
+#: include/nav.php:171 mod/settings.php:906
+msgid "Mark as seen"
+msgstr "Marcar como leído"
 
-#: include/features.php:108
-msgid "Ability to tag existing posts"
-msgstr "Habilidad de taggear publicaciones existentes"
+#: include/nav.php:171
+msgid "Mark all system notifications seen"
+msgstr "Marcar todas las notificaciones del sistema como leídas"
 
-#: include/features.php:109
-msgid "Post Categories"
-msgstr "Categorías de publicaciones"
+#: include/nav.php:175 mod/message.php:179 view/theme/frio/theme.php:255
+msgid "Messages"
+msgstr "Mensajes"
 
-#: include/features.php:109
-msgid "Add categories to your posts"
-msgstr "Agregue categorías a sus publicaciones. Las mismas serán visualizadas en su pagina de inicio."
+#: include/nav.php:175 view/theme/frio/theme.php:255
+msgid "Private mail"
+msgstr "Correo privado"
 
-#: include/features.php:110
-msgid "Ability to file posts under folders"
-msgstr "Archivar publicaciones en carpetas"
+#: include/nav.php:176
+msgid "Inbox"
+msgstr "Entrada"
 
-#: include/features.php:111
-msgid "Dislike Posts"
-msgstr "Desaprobar publicación (dislike)"
+#: include/nav.php:177
+msgid "Outbox"
+msgstr "Enviados"
 
-#: include/features.php:111
-msgid "Ability to dislike posts/comments"
-msgstr "Habilidad de expresar desacuerdo en publicaciones y comentarios. Esta función solo es visualizado en la red friendica."
+#: include/nav.php:178 mod/message.php:16
+msgid "New Message"
+msgstr "Nuevo mensaje"
 
-#: include/features.php:112
-msgid "Star Posts"
-msgstr "Fijar publicaciones"
+#: include/nav.php:181
+msgid "Manage"
+msgstr "Administrar"
 
-#: include/features.php:112
-msgid "Ability to mark special posts with a star indicator"
-msgstr "Habilidad de marcar - observar fijamente publicaciones.\nEl simbolo de estrella es habilitado. Se recibirán notificaciones sobre comentarios, además una pestaña de publicaciones fijadas es habilitada. En las opciones de expiración de publicaciones se puede filtrar estas publicaciones para no ser eliminados contrario a las publicaciones demás de los contactos."
+#: include/nav.php:181
+msgid "Manage other pages"
+msgstr "Administrar otras páginas"
 
-#: include/features.php:113
-msgid "Mute Post Notifications"
-msgstr "Silenciar notificaciones de una publicacion"
+#: include/nav.php:184 mod/settings.php:81
+msgid "Delegations"
+msgstr "Delegaciones"
 
-#: include/features.php:113
-msgid "Ability to mute notifications for a thread"
-msgstr "Habilidad de silenciar notificaciones sobre nuevos comentarios en una publicación."
+#: include/nav.php:184 mod/delegate.php:130
+msgid "Delegate Page Management"
+msgstr "Delegar la administración de la página"
 
-#: include/features.php:118
-msgid "Advanced Profile Settings"
-msgstr "Ajustes avanzados del perfil"
+#: include/nav.php:186 mod/admin.php:1533 mod/admin.php:1809
+#: mod/newmember.php:22 mod/settings.php:111 view/theme/frio/theme.php:256
+msgid "Settings"
+msgstr "Configuración"
 
-#: include/features.php:119
-msgid "Show visitors public community forums at the Advanced Profile Page"
-msgstr "Mostrar a los visitantes foros públicos en las que se esta participando en el pagina avanzada de perfiles."
+#: include/nav.php:186 view/theme/frio/theme.php:256
+msgid "Account settings"
+msgstr "Configuración de tu cuenta"
 
-#: include/follow.php:81 mod/dfrn_request.php:509
-msgid "Disallowed profile URL."
-msgstr "Dirección de perfil no permitida."
+#: include/nav.php:189
+msgid "Manage/Edit Profiles"
+msgstr "Manejar/editar Perfiles"
 
-#: include/follow.php:86
-msgid "Connect URL missing."
-msgstr "Falta el conector URL."
+#: include/nav.php:192 view/theme/frio/theme.php:257
+msgid "Manage/edit friends and contacts"
+msgstr "Administrar/editar amigos y contactos"
 
-#: include/follow.php:113
-msgid ""
-"This site is not configured to allow communications with other networks."
-msgstr "Este sitio no está configurado para permitir la comunicación con otras redes."
+#: include/nav.php:197 mod/admin.php:192
+msgid "Admin"
+msgstr "Admin"
 
-#: include/follow.php:114 include/follow.php:134
-msgid "No compatible communication protocols or feeds were discovered."
-msgstr "No se ha descubierto protocolos de comunicación o fuentes compatibles."
+#: include/nav.php:197
+msgid "Site setup and configuration"
+msgstr "Opciones y configuración del sitio"
 
-#: include/follow.php:132
-msgid "The profile address specified does not provide adequate information."
-msgstr "La dirección del perfil especificado no proporciona información adecuada."
+#: include/nav.php:200
+msgid "Navigation"
+msgstr "Navegación"
 
-#: include/follow.php:136
-msgid "An author or name was not found."
-msgstr "No se ha encontrado un autor o nombre."
+#: include/nav.php:200
+msgid "Site map"
+msgstr "Mapa del sitio"
 
-#: include/follow.php:138
-msgid "No browser URL could be matched to this address."
-msgstr "Ninguna dirección concuerda con la suministrada."
+#: include/network.php:622
+msgid "view full size"
+msgstr "Ver a tamaño completo"
 
-#: include/follow.php:140
-msgid ""
-"Unable to match @-style Identity Address with a known protocol or email "
-"contact."
-msgstr "Imposible identificar la dirección @ con algún protocolo conocido o dirección de contacto."
+#: include/oembed.php:266
+msgid "Embedded content"
+msgstr "Contenido integrado"
 
-#: include/follow.php:141
-msgid "Use mailto: in front of address to force email check."
-msgstr "Escribe mailto: al principio de la dirección para forzar el envío."
+#: include/oembed.php:274
+msgid "Embedding disabled"
+msgstr "Contenido incrustrado desabilitado"
 
-#: include/follow.php:147
-msgid ""
-"The profile address specified belongs to a network which has been disabled "
-"on this site."
-msgstr "La dirección del perfil especificada pertenece a una red que ha sido deshabilitada en este sitio."
+#: include/ostatus.php:1832
+#, php-format
+msgid "%s is now following %s."
+msgstr "%s sigue ahora a %s."
 
-#: include/follow.php:157
-msgid ""
-"Limited profile. This person will be unable to receive direct/personal "
-"notifications from you."
-msgstr "Perfil limitado. Esta persona no podrá recibir notificaciones directas/personales tuyas."
+#: include/ostatus.php:1833
+msgid "following"
+msgstr "siguiendo"
 
-#: include/follow.php:258
-msgid "Unable to retrieve contact information."
-msgstr "No ha sido posible recibir la información del contacto."
+#: include/ostatus.php:1836
+#, php-format
+msgid "%s stopped following %s."
+msgstr "%s dejó de seguir a %s."
 
-#: include/identity.php:42
-msgid "Requested account is not available."
-msgstr "La cuenta solicitada no está disponible."
+#: include/ostatus.php:1837
+msgid "stopped following"
+msgstr "dejó de seguir"
 
-#: include/identity.php:51 mod/profile.php:21
-msgid "Requested profile is not available."
-msgstr "El perfil solicitado no está disponible."
+#: include/photos.php:57 include/photos.php:67 mod/fbrowser.php:40
+#: mod/fbrowser.php:61 mod/photos.php:182 mod/photos.php:1106
+#: mod/photos.php:1231 mod/photos.php:1252 mod/photos.php:1817
+#: mod/photos.php:1829
+msgid "Contact Photos"
+msgstr "Foto del contacto"
 
-#: include/identity.php:95 include/identity.php:311 include/identity.php:688
-msgid "Edit profile"
-msgstr "Editar perfil"
+#: include/plugin.php:530 include/plugin.php:532
+msgid "Click here to upgrade."
+msgstr "Pulsa aquí para actualizar."
 
-#: include/identity.php:251
-msgid "Atom feed"
-msgstr "Atom feed"
+#: include/plugin.php:538
+msgid "This action exceeds the limits set by your subscription plan."
+msgstr "Esta acción excede los límites permitidos por tu subscripción."
 
-#: include/identity.php:282
-msgid "Manage/edit profiles"
-msgstr "Administrar/editar perfiles"
+#: include/plugin.php:543
+msgid "This action is not available under your subscription plan."
+msgstr "Esta acción no está permitida para tu subscripción."
 
-#: include/identity.php:287 include/identity.php:313 mod/profiles.php:795
-msgid "Change profile photo"
-msgstr "Cambiar foto del perfil"
+#: include/profile_selectors.php:6
+msgid "Male"
+msgstr "Hombre"
 
-#: include/identity.php:288 mod/profiles.php:796
-msgid "Create New Profile"
-msgstr "Crear nuevo perfil"
+#: include/profile_selectors.php:6
+msgid "Female"
+msgstr "Mujer"
 
-#: include/identity.php:298 mod/profiles.php:785
-msgid "Profile Image"
-msgstr "Imagen del Perfil"
+#: include/profile_selectors.php:6
+msgid "Currently Male"
+msgstr "Actualmente Hombre"
 
-#: include/identity.php:301 mod/profiles.php:787
-msgid "visible to everybody"
-msgstr "Visible para todos"
+#: include/profile_selectors.php:6
+msgid "Currently Female"
+msgstr "Actualmente Mujer"
 
-#: include/identity.php:302 mod/profiles.php:691 mod/profiles.php:788
-msgid "Edit visibility"
-msgstr "Editar visibilidad"
+#: include/profile_selectors.php:6
+msgid "Mostly Male"
+msgstr "Mayormente Hombre"
 
-#: include/identity.php:330 include/identity.php:616 mod/notifications.php:238
-#: mod/directory.php:139
-msgid "Gender:"
-msgstr "Género:"
+#: include/profile_selectors.php:6
+msgid "Mostly Female"
+msgstr "Mayormente Mujer"
 
-#: include/identity.php:333 include/identity.php:636 mod/directory.php:141
-msgid "Status:"
-msgstr "Estado:"
+#: include/profile_selectors.php:6
+msgid "Transgender"
+msgstr "Transgenérico"
 
-#: include/identity.php:335 include/identity.php:647 mod/directory.php:143
-msgid "Homepage:"
-msgstr "Página de inicio:"
+#: include/profile_selectors.php:6
+msgid "Intersex"
+msgstr "Bisexual"
 
-#: include/identity.php:337 include/identity.php:657 mod/notifications.php:234
-#: mod/directory.php:145 mod/contacts.php:632
-msgid "About:"
-msgstr "Acerca de:"
+#: include/profile_selectors.php:6
+msgid "Transsexual"
+msgstr "Transexual"
 
-#: include/identity.php:339 mod/contacts.php:630
-msgid "XMPP:"
-msgstr "XMPP:"
+#: include/profile_selectors.php:6
+msgid "Hermaphrodite"
+msgstr "Hermafrodita"
 
-#: include/identity.php:422 mod/notifications.php:246 mod/contacts.php:50
-msgid "Network:"
-msgstr "Red:"
+#: include/profile_selectors.php:6
+msgid "Neuter"
+msgstr "Neutro"
 
-#: include/identity.php:451 include/identity.php:535
-msgid "g A l F d"
-msgstr "g A l F d"
+#: include/profile_selectors.php:6
+msgid "Non-specific"
+msgstr "Sin especificar"
 
-#: include/identity.php:452 include/identity.php:536
-msgid "F d"
-msgstr "F d"
+#: include/profile_selectors.php:6
+msgid "Other"
+msgstr "Otro"
 
-#: include/identity.php:497 include/identity.php:582
-msgid "[today]"
-msgstr "[hoy]"
+#: include/profile_selectors.php:23
+msgid "Males"
+msgstr "Hombres"
 
-#: include/identity.php:509
-msgid "Birthday Reminders"
-msgstr "Recordatorios de cumpleaños"
+#: include/profile_selectors.php:23
+msgid "Females"
+msgstr "Mujeres"
 
-#: include/identity.php:510
-msgid "Birthdays this week:"
-msgstr "Cumpleaños esta semana:"
+#: include/profile_selectors.php:23
+msgid "Gay"
+msgstr "Gay"
 
-#: include/identity.php:569
-msgid "[No description]"
-msgstr "[Sin descripción]"
+#: include/profile_selectors.php:23
+msgid "Lesbian"
+msgstr "Lesbiana"
 
-#: include/identity.php:593
-msgid "Event Reminders"
-msgstr "Recordatorios de eventos"
+#: include/profile_selectors.php:23
+msgid "No Preference"
+msgstr "Sin preferencias"
 
-#: include/identity.php:594
-msgid "Events this week:"
-msgstr "Eventos de esta semana:"
+#: include/profile_selectors.php:23
+msgid "Bisexual"
+msgstr "Bisexual"
 
-#: include/identity.php:614 mod/settings.php:1279
-msgid "Full Name:"
-msgstr "Nombre completo:"
+#: include/profile_selectors.php:23
+msgid "Autosexual"
+msgstr "Autosexual"
 
-#: include/identity.php:621
-msgid "j F, Y"
-msgstr "j F, Y"
+#: include/profile_selectors.php:23
+msgid "Abstinent"
+msgstr "Célibe"
 
-#: include/identity.php:622
-msgid "j F"
-msgstr "j F"
+#: include/profile_selectors.php:23
+msgid "Virgin"
+msgstr "Virgen"
 
-#: include/identity.php:633
-msgid "Age:"
-msgstr "Edad:"
+#: include/profile_selectors.php:23
+msgid "Deviant"
+msgstr "Desviado"
 
-#: include/identity.php:642
-#, php-format
-msgid "for %1$d %2$s"
-msgstr "por %1$d %2$s"
+#: include/profile_selectors.php:23
+msgid "Fetish"
+msgstr "Fetichista"
 
-#: include/identity.php:645 mod/profiles.php:710
-msgid "Sexual Preference:"
-msgstr "Preferencia sexual:"
+#: include/profile_selectors.php:23
+msgid "Oodles"
+msgstr "Orgiástico"
 
-#: include/identity.php:649 mod/profiles.php:737
-msgid "Hometown:"
-msgstr "Ciudad de origen:"
+#: include/profile_selectors.php:23
+msgid "Nonsexual"
+msgstr "Asexual"
 
-#: include/identity.php:651 mod/notifications.php:236 mod/contacts.php:634
-#: mod/follow.php:134
-msgid "Tags:"
-msgstr "Etiquetas:"
+#: include/profile_selectors.php:42
+msgid "Single"
+msgstr "Soltero"
 
-#: include/identity.php:653 mod/profiles.php:738
-msgid "Political Views:"
-msgstr "Ideas políticas:"
+#: include/profile_selectors.php:42
+msgid "Lonely"
+msgstr "Solitario"
 
-#: include/identity.php:655
-msgid "Religion:"
-msgstr "Religión:"
+#: include/profile_selectors.php:42
+msgid "Available"
+msgstr "Disponible"
 
-#: include/identity.php:659
-msgid "Hobbies/Interests:"
-msgstr "Aficiones/Intereses:"
+#: include/profile_selectors.php:42
+msgid "Unavailable"
+msgstr "No disponible"
 
-#: include/identity.php:661 mod/profiles.php:742
-msgid "Likes:"
-msgstr "Me gusta:"
+#: include/profile_selectors.php:42
+msgid "Has crush"
+msgstr "Enamorado"
 
-#: include/identity.php:663 mod/profiles.php:743
-msgid "Dislikes:"
-msgstr "No me gusta:"
+#: include/profile_selectors.php:42
+msgid "Infatuated"
+msgstr "Loco/a por alguien"
 
-#: include/identity.php:666
-msgid "Contact information and Social Networks:"
-msgstr "Información de contacto y Redes sociales:"
+#: include/profile_selectors.php:42
+msgid "Dating"
+msgstr "De citas"
 
-#: include/identity.php:668
-msgid "Musical interests:"
-msgstr "Intereses musicales:"
+#: include/profile_selectors.php:42
+msgid "Unfaithful"
+msgstr "Infiel"
 
-#: include/identity.php:670
-msgid "Books, literature:"
-msgstr "Libros, literatura:"
+#: include/profile_selectors.php:42
+msgid "Sex Addict"
+msgstr "Adicto al sexo"
 
-#: include/identity.php:672
-msgid "Television:"
-msgstr "Televisión:"
+#: include/profile_selectors.php:42 include/user.php:280 include/user.php:284
+msgid "Friends"
+msgstr "Amigos"
 
-#: include/identity.php:674
-msgid "Film/dance/culture/entertainment:"
-msgstr "Películas/baile/cultura/entretenimiento:"
+#: include/profile_selectors.php:42
+msgid "Friends/Benefits"
+msgstr "Amigos con beneficios"
 
-#: include/identity.php:676
-msgid "Love/Romance:"
-msgstr "Amor/Romance:"
+#: include/profile_selectors.php:42
+msgid "Casual"
+msgstr "Casual"
 
-#: include/identity.php:678
-msgid "Work/employment:"
-msgstr "Trabajo/ocupación:"
+#: include/profile_selectors.php:42
+msgid "Engaged"
+msgstr "Comprometido/a"
 
-#: include/identity.php:680
-msgid "School/education:"
-msgstr "Escuela/estudios:"
+#: include/profile_selectors.php:42
+msgid "Married"
+msgstr "Casado/a"
 
-#: include/identity.php:684
-msgid "Forums:"
-msgstr "Foros:"
+#: include/profile_selectors.php:42
+msgid "Imaginarily married"
+msgstr "Casado imaginario"
 
-#: include/identity.php:692 mod/events.php:507
-msgid "Basic"
-msgstr "Basic"
+#: include/profile_selectors.php:42
+msgid "Partners"
+msgstr "Socios"
 
-#: include/identity.php:693 mod/events.php:508 mod/admin.php:959
-#: mod/contacts.php:870
-msgid "Advanced"
-msgstr "Avanzado"
+#: include/profile_selectors.php:42
+msgid "Cohabiting"
+msgstr "Cohabitando"
 
-#: include/identity.php:717 mod/contacts.php:836 mod/follow.php:142
-msgid "Status Messages and Posts"
-msgstr "Mensajes de Estado y Publicaciones"
+#: include/profile_selectors.php:42
+msgid "Common law"
+msgstr "Pareja de hecho"
 
-#: include/identity.php:725 mod/contacts.php:844
-msgid "Profile Details"
-msgstr "Detalles del Perfil"
+#: include/profile_selectors.php:42
+msgid "Happy"
+msgstr "Feliz"
 
-#: include/identity.php:733 mod/photos.php:87
-msgid "Photo Albums"
-msgstr "Álbum de Fotos"
+#: include/profile_selectors.php:42
+msgid "Not looking"
+msgstr "No busca relación"
 
-#: include/identity.php:772 mod/notes.php:46
-msgid "Personal Notes"
-msgstr "Notas personales"
+#: include/profile_selectors.php:42
+msgid "Swinger"
+msgstr "Swinger"
 
-#: include/identity.php:775
-msgid "Only You Can See This"
-msgstr "Únicamente tú puedes ver esto"
+#: include/profile_selectors.php:42
+msgid "Betrayed"
+msgstr "Traicionado/a"
 
-#: include/items.php:1575 mod/dfrn_confirm.php:730 mod/dfrn_request.php:746
-msgid "[Name Withheld]"
-msgstr "[Nombre oculto]"
+#: include/profile_selectors.php:42
+msgid "Separated"
+msgstr "Separado/a"
 
-#: include/items.php:1930 mod/viewsrc.php:15 mod/notice.php:15
-#: mod/display.php:103 mod/display.php:279 mod/display.php:478
-#: mod/admin.php:234 mod/admin.php:1471 mod/admin.php:1705
-msgid "Item not found."
-msgstr "Elemento no encontrado."
+#: include/profile_selectors.php:42
+msgid "Unstable"
+msgstr "Inestable"
 
-#: include/items.php:1969
-msgid "Do you really want to delete this item?"
-msgstr "¿Realmente quieres borrar este objeto?"
+#: include/profile_selectors.php:42
+msgid "Divorced"
+msgstr "Divorciado/a"
 
-#: include/items.php:1971 mod/api.php:105 mod/message.php:217
-#: mod/profiles.php:648 mod/profiles.php:651 mod/profiles.php:677
-#: mod/suggest.php:29 mod/register.php:245 mod/settings.php:1163
-#: mod/settings.php:1169 mod/settings.php:1177 mod/settings.php:1181
-#: mod/settings.php:1186 mod/settings.php:1192 mod/settings.php:1198
-#: mod/settings.php:1204 mod/settings.php:1230 mod/settings.php:1231
-#: mod/settings.php:1232 mod/settings.php:1233 mod/settings.php:1234
-#: mod/contacts.php:442 mod/dfrn_request.php:862 mod/follow.php:110
-msgid "Yes"
-msgstr "Sí"
+#: include/profile_selectors.php:42
+msgid "Imaginarily divorced"
+msgstr "Divorciado imaginario"
 
-#: include/items.php:2134 mod/notes.php:22 mod/uimport.php:23
-#: mod/nogroup.php:25 mod/invite.php:15 mod/invite.php:101
-#: mod/repair_ostatus.php:9 mod/delegate.php:12 mod/attach.php:33
-#: mod/editpost.php:10 mod/group.php:19 mod/wallmessage.php:9
-#: mod/wallmessage.php:33 mod/wallmessage.php:79 mod/wallmessage.php:103
-#: mod/api.php:26 mod/api.php:31 mod/ostatus_subscribe.php:9
-#: mod/message.php:46 mod/message.php:182 mod/manage.php:96
-#: mod/crepair.php:100 mod/fsuggest.php:78 mod/mood.php:114 mod/poke.php:150
-#: mod/profile_photo.php:19 mod/profile_photo.php:175
-#: mod/profile_photo.php:186 mod/profile_photo.php:199 mod/regmod.php:110
-#: mod/notifications.php:71 mod/profiles.php:166 mod/profiles.php:605
-#: mod/allfriends.php:12 mod/cal.php:304 mod/common.php:18 mod/dirfind.php:11
-#: mod/display.php:475 mod/events.php:190 mod/suggest.php:58
-#: mod/photos.php:159 mod/photos.php:1072 mod/register.php:42
-#: mod/settings.php:22 mod/settings.php:128 mod/settings.php:665
-#: mod/wall_attach.php:67 mod/wall_attach.php:70 mod/wall_upload.php:77
-#: mod/wall_upload.php:80 mod/contacts.php:350 mod/dfrn_confirm.php:61
-#: mod/follow.php:11 mod/follow.php:73 mod/follow.php:155 mod/item.php:199
-#: mod/item.php:211 mod/network.php:4 mod/viewcontacts.php:45 index.php:401
-msgid "Permission denied."
-msgstr "Permiso denegado."
+#: include/profile_selectors.php:42
+msgid "Widowed"
+msgstr "Viudo/a"
 
-#: include/items.php:2239
-msgid "Archives"
-msgstr "Archivos"
+#: include/profile_selectors.php:42
+msgid "Uncertain"
+msgstr "Incierto"
 
-#: include/oembed.php:264
-msgid "Embedded content"
-msgstr "Contenido integrado"
+#: include/profile_selectors.php:42
+msgid "It's complicated"
+msgstr "Es complicado"
+
+#: include/profile_selectors.php:42
+msgid "Don't care"
+msgstr "No te importa"
 
-#: include/oembed.php:272
-msgid "Embedding disabled"
-msgstr "Contenido incrustrado desabilitado"
+#: include/profile_selectors.php:42
+msgid "Ask me"
+msgstr "Pregúntame"
 
-#: include/ostatus.php:1825
-#, php-format
-msgid "%s is now following %s."
-msgstr "%s sigue ahora a %s."
+#: include/security.php:61
+msgid "Welcome "
+msgstr "Bienvenido "
 
-#: include/ostatus.php:1826
-msgid "following"
-msgstr "siguiendo"
+#: include/security.php:62
+msgid "Please upload a profile photo."
+msgstr "Por favor sube una foto para tu perfil."
 
-#: include/ostatus.php:1829
-#, php-format
-msgid "%s stopped following %s."
-msgstr "%s dejó de seguir a %s."
+#: include/security.php:65
+msgid "Welcome back "
+msgstr "Bienvenido de nuevo "
 
-#: include/ostatus.php:1830
-msgid "stopped following"
-msgstr "dejó de seguir"
+#: include/security.php:429
+msgid ""
+"The form security token was not correct. This probably happened because the "
+"form has been opened for too long (>3 hours) before submitting it."
+msgstr "La ficha de seguridad no es correcta. Seguramente haya ocurrido por haber dejado el formulario abierto demasiado tiempo (>3 horas) antes de enviarlo."
 
-#: include/text.php:304
+#: include/text.php:307
 msgid "newer"
 msgstr "más nuevo"
 
-#: include/text.php:306
+#: include/text.php:308
 msgid "older"
 msgstr "más antiguo"
 
-#: include/text.php:311
-msgid "prev"
-msgstr "ant."
-
 #: include/text.php:313
 msgid "first"
 msgstr "primera"
 
-#: include/text.php:345
-msgid "last"
-msgstr "última"
+#: include/text.php:314
+msgid "prev"
+msgstr "ant."
 
 #: include/text.php:348
 msgid "next"
 msgstr "sig."
 
+#: include/text.php:349
+msgid "last"
+msgstr "última"
+
 #: include/text.php:403
 msgid "Loading more entries..."
 msgstr "Cargar mas entradas .."
@@ -2788,190 +2807,225 @@ msgstr "El fin"
 msgid "No contacts"
 msgstr "Sin contactos"
 
-#: include/text.php:912
+#: include/text.php:914
 #, php-format
 msgid "%d Contact"
 msgid_plural "%d Contacts"
 msgstr[0] "%d Contacto"
 msgstr[1] "%d Contactos"
 
-#: include/text.php:925
+#: include/text.php:927
 msgid "View Contacts"
 msgstr "Ver contactos"
 
-#: include/text.php:1013 mod/notes.php:61 mod/filer.php:31
-#: mod/editpost.php:109
+#: include/text.php:1015 mod/editpost.php:99 mod/filer.php:31 mod/notes.php:62
 msgid "Save"
 msgstr "Guardar"
 
-#: include/text.php:1076
+#: include/text.php:1078
 msgid "poke"
 msgstr "tocar"
 
-#: include/text.php:1076
+#: include/text.php:1078
 msgid "poked"
 msgstr "tocó a"
 
-#: include/text.php:1077
+#: include/text.php:1079
 msgid "ping"
 msgstr "hacer \"ping\""
 
-#: include/text.php:1077
+#: include/text.php:1079
 msgid "pinged"
 msgstr "hizo \"ping\" a"
 
-#: include/text.php:1078
+#: include/text.php:1080
 msgid "prod"
 msgstr "empujar"
 
-#: include/text.php:1078
+#: include/text.php:1080
 msgid "prodded"
 msgstr "empujó a"
 
-#: include/text.php:1079
+#: include/text.php:1081
 msgid "slap"
 msgstr "abofetear"
 
-#: include/text.php:1079
+#: include/text.php:1081
 msgid "slapped"
 msgstr "abofeteó a"
 
-#: include/text.php:1080
+#: include/text.php:1082
 msgid "finger"
 msgstr "meter dedo"
 
-#: include/text.php:1080
+#: include/text.php:1082
 msgid "fingered"
 msgstr "le metió un dedo a"
 
-#: include/text.php:1081
+#: include/text.php:1083
 msgid "rebuff"
 msgstr "desairar"
 
-#: include/text.php:1081
+#: include/text.php:1083
 msgid "rebuffed"
 msgstr "desairó a"
 
-#: include/text.php:1095
+#: include/text.php:1097
 msgid "happy"
 msgstr "feliz"
 
-#: include/text.php:1096
+#: include/text.php:1098
 msgid "sad"
 msgstr "triste"
 
-#: include/text.php:1097
+#: include/text.php:1099
 msgid "mellow"
 msgstr "sentimental"
 
-#: include/text.php:1098
+#: include/text.php:1100
 msgid "tired"
 msgstr "cansado"
 
-#: include/text.php:1099
+#: include/text.php:1101
 msgid "perky"
 msgstr "alegre"
 
-#: include/text.php:1100
+#: include/text.php:1102
 msgid "angry"
 msgstr "furioso"
 
-#: include/text.php:1101
+#: include/text.php:1103
 msgid "stupified"
 msgstr "estupefacto"
 
-#: include/text.php:1102
+#: include/text.php:1104
 msgid "puzzled"
 msgstr "extrañado"
 
-#: include/text.php:1103
+#: include/text.php:1105
 msgid "interested"
 msgstr "interesado"
 
-#: include/text.php:1104
+#: include/text.php:1106
 msgid "bitter"
 msgstr "rencoroso"
 
-#: include/text.php:1105
+#: include/text.php:1107
 msgid "cheerful"
 msgstr "jovial"
 
-#: include/text.php:1106
+#: include/text.php:1108
 msgid "alive"
 msgstr "vivo"
 
-#: include/text.php:1107
+#: include/text.php:1109
 msgid "annoyed"
 msgstr "enojado"
 
-#: include/text.php:1108
+#: include/text.php:1110
 msgid "anxious"
 msgstr "ansioso"
 
-#: include/text.php:1109
+#: include/text.php:1111
 msgid "cranky"
 msgstr "irritable"
 
-#: include/text.php:1110
+#: include/text.php:1112
 msgid "disturbed"
 msgstr "perturbado"
 
-#: include/text.php:1111
+#: include/text.php:1113
 msgid "frustrated"
 msgstr "frustrado"
 
-#: include/text.php:1112
+#: include/text.php:1114
 msgid "motivated"
 msgstr "motivado"
 
-#: include/text.php:1113
+#: include/text.php:1115
 msgid "relaxed"
 msgstr "relajado"
 
-#: include/text.php:1114
+#: include/text.php:1116
 msgid "surprised"
 msgstr "sorprendido"
 
-#: include/text.php:1324 mod/videos.php:380
+#: include/text.php:1326 mod/videos.php:384
 msgid "View Video"
 msgstr "Ver vídeo"
 
-#: include/text.php:1356
+#: include/text.php:1358
 msgid "bytes"
 msgstr "bytes"
 
-#: include/text.php:1388 include/text.php:1400
+#: include/text.php:1390 include/text.php:1402
 msgid "Click to open/close"
 msgstr "Pulsa para abrir/cerrar"
 
-#: include/text.php:1526
+#: include/text.php:1528
 msgid "View on separate page"
 msgstr "Ver en pagina aparte"
 
-#: include/text.php:1527
+#: include/text.php:1529
 msgid "view on separate page"
 msgstr "ver en pagina aparte"
 
-#: include/text.php:1806
+#: include/text.php:1808
 msgid "activity"
 msgstr "Actividad"
 
-#: include/text.php:1808 mod/content.php:623 object/Item.php:431
-#: object/Item.php:444
+#: include/text.php:1810 mod/content.php:623 object/Item.php:419
+#: object/Item.php:431
 msgid "comment"
 msgid_plural "comments"
 msgstr[0] ""
 msgstr[1] "Comentario"
 
-#: include/text.php:1809
+#: include/text.php:1811
 msgid "post"
 msgstr "Publicación"
 
-#: include/text.php:1977
+#: include/text.php:1979
 msgid "Item filed"
 msgstr "Elemento archivado"
 
-#: include/user.php:39 mod/settings.php:373
+#: include/uimport.php:91
+msgid "Error decoding account file"
+msgstr "Error decodificando el archivo de cuenta"
+
+#: include/uimport.php:97
+msgid "Error! No version data in file! This is not a Friendica account file?"
+msgstr "Error! No hay datos de versión en el archivo! ¿Es esto de una cuenta friendica? "
+
+#: include/uimport.php:113 include/uimport.php:124
+msgid "Error! Cannot check nickname"
+msgstr "Error! No puedo consultar el apodo"
+
+#: include/uimport.php:117 include/uimport.php:128
+#, php-format
+msgid "User '%s' already exists on this server!"
+msgstr "La cuenta '%s' ya existe en este servidor!"
+
+#: include/uimport.php:150
+msgid "User creation error"
+msgstr "Error al crear la cuenta"
+
+#: include/uimport.php:170
+msgid "User profile creation error"
+msgstr "Error de creación del perfil de la cuenta"
+
+#: include/uimport.php:219
+#, php-format
+msgid "%d contact not imported"
+msgid_plural "%d contacts not imported"
+msgstr[0] "%d contactos no encontrado"
+msgstr[1] "%d contactos no importado"
+
+#: include/uimport.php:289
+msgid "Done. You can now login with your username and password"
+msgstr "Hecho. Ahora podes ingresar con tu nombre de cuenta y la contraseña."
+
+#: include/user.php:39 mod/settings.php:375
 msgid "Passwords do not match. Password unchanged."
 msgstr "Las contraseñas no coinciden. La contraseña no ha sido modificada."
 
@@ -3037,7 +3091,7 @@ msgstr "ERROR GRAVE: La generación de claves de seguridad ha fallado."
 msgid "An error occurred during registration. Please try again."
 msgstr "Se produjo un error durante el registro. Por favor, inténtalo de nuevo."
 
-#: include/user.php:256 view/theme/duepuntozero/config.php:44
+#: include/user.php:256 view/theme/duepuntozero/config.php:43
 msgid "default"
 msgstr "predeterminado"
 
@@ -3045,16 +3099,15 @@ msgstr "predeterminado"
 msgid "An error occurred creating your default profile. Please try again."
 msgstr "Error al crear tu perfil predeterminado. Por favor, inténtalo de nuevo."
 
-#: include/user.php:326 include/user.php:333 include/user.php:340
-#: mod/profile_photo.php:74 mod/profile_photo.php:81 mod/profile_photo.php:88
-#: mod/profile_photo.php:210 mod/profile_photo.php:302
-#: mod/profile_photo.php:311 mod/photos.php:66 mod/photos.php:180
-#: mod/photos.php:751 mod/photos.php:1211 mod/photos.php:1232
-#: mod/photos.php:1819
+#: include/user.php:326 include/user.php:334 include/user.php:342
+#: mod/photos.php:68 mod/photos.php:182 mod/photos.php:768 mod/photos.php:1231
+#: mod/photos.php:1252 mod/photos.php:1839 mod/profile_photo.php:74
+#: mod/profile_photo.php:82 mod/profile_photo.php:90 mod/profile_photo.php:215
+#: mod/profile_photo.php:310 mod/profile_photo.php:320
 msgid "Profile Photos"
 msgstr "Foto del perfil"
 
-#: include/user.php:414
+#: include/user.php:417
 #, php-format
 msgid ""
 "\n"
@@ -3063,5643 +3116,5651 @@ msgid ""
 "\t"
 msgstr "\n\t\tEstimado %1$s,\n\t\t\tGracias por registrarse en %2$s. Su cuenta está pendiente de aprobación por el administrador.\n\t"
 
-#: include/user.php:424
+#: include/user.php:427
 #, php-format
 msgid "Registration at %s"
 msgstr "Registro en %s"
 
-#: include/user.php:434
-#, php-format
-msgid ""
-"\n"
-"\t\tDear %1$s,\n"
-"\t\t\tThank you for registering at %2$s. Your account has been created.\n"
-"\t"
-msgstr "\n\t\tEstimado %1$s,\n\t\t\tGracias por registrar en %2$s. Su cuenta ha sido creada.\n\t"
-
-#: include/user.php:438
-#, php-format
-msgid ""
-"\n"
-"\t\tThe login details are as follows:\n"
-"\t\t\tSite Location:\t%3$s\n"
-"\t\t\tLogin Name:\t%1$s\n"
-"\t\t\tPassword:\t%5$s\n"
-"\n"
-"\t\tYou may change your password from your account \"Settings\" page after logging\n"
-"\t\tin.\n"
-"\n"
-"\t\tPlease take a few moments to review the other account settings on that page.\n"
-"\n"
-"\t\tYou may also wish to add some basic information to your default profile\n"
-"\t\t(on the \"Profiles\" page) so that other people can easily find you.\n"
-"\n"
-"\t\tWe recommend setting your full name, adding a profile photo,\n"
-"\t\tadding some profile \"keywords\" (very useful in making new friends) - and\n"
-"\t\tperhaps what country you live in; if you do not wish to be more specific\n"
-"\t\tthan that.\n"
-"\n"
-"\t\tWe fully respect your right to privacy, and none of these items are necessary.\n"
-"\t\tIf you are new and do not know anybody here, they may help\n"
-"\t\tyou to make some new and interesting friends.\n"
-"\n"
-"\n"
-"\t\tThank you and welcome to %2$s."
-msgstr "\n\t\t\tLos detalles de acceso son las siguientes:\n\n\t\t\tDirección del sitio:\t%3$s\n\t\t\tNombre de la cuenta:\t\t%1$s\n\t\t\tContraseña:\t\t%5$s\n\n\t\t\tPodrá cambiar la contraseña desde la pagina de configuración de su cuenta después de acceder a la misma\n\t\t\ten.\n\n\t\t\tPor favor tome unos minutos para revisar las opciones demás de la cuenta en dicha pagina de configuración.\n\n\t\t\tTambién podrá agregar informaciones adicionales a su pagina de perfil predeterminado. \n\t\t\t(en la pagina \"Perfiles\") para que otras personas pueden encontrarlo fácilmente.\n\n\t\t\tRecomendamos que elija un nombre apropiado, agregando una imagen de perfil,\n\t\t\tagregando algunas palabras claves de la cuenta (muy útil para hacer nuevos amigos) - y \n\t\t\tquizás el país en donde vive; si no quiere ser mas especifico\n\t\t\tque eso.\n\n\t\t\tRespetamos absolutamente su derecho a la privacidad y ninguno de estos detalles es necesario.\n\t\t\tSi eres nuevo aquí y no conoces a nadie, estos detalles pueden ayudarte\n\t\t\tpara hacer nuevas e interesantes amistades.\n\n\t\t\tGracias y bienvenido a  %2$s."
-
-#: include/user.php:470 mod/admin.php:1213
-#, php-format
-msgid "Registration details for %s"
-msgstr "Detalles de registro para %s"
-
-#: mod/oexchange.php:25
-msgid "Post successful."
-msgstr "¡Publicado!"
-
-#: mod/viewsrc.php:7
-msgid "Access denied."
-msgstr "Acceso denegado."
-
-#: mod/home.php:35
-#, php-format
-msgid "Welcome to %s"
-msgstr "Bienvenido a %s"
-
-#: mod/notify.php:60
-msgid "No more system notifications."
-msgstr "No hay más notificaciones del sistema."
-
-#: mod/notify.php:64 mod/notifications.php:111
-msgid "System Notifications"
-msgstr "Notificaciones del sistema"
-
-#: mod/search.php:25 mod/network.php:191
-msgid "Remove term"
-msgstr "Eliminar término"
-
-#: mod/search.php:93 mod/search.php:99 mod/community.php:22
-#: mod/directory.php:37 mod/display.php:200 mod/photos.php:944
-#: mod/videos.php:194 mod/dfrn_request.php:791 mod/viewcontacts.php:35
-msgid "Public access denied."
-msgstr "Acceso público denegado."
-
-#: mod/search.php:100
-msgid "Only logged in users are permitted to perform a search."
-msgstr "Solo usuarios activos tienen permiso para ejecutar búsquedas."
-
-#: mod/search.php:124
-msgid "Too Many Requests"
-msgstr "Demasiadas consultas"
-
-#: mod/search.php:125
-msgid "Only one search per minute is permitted for not logged in users."
-msgstr "Se permite solo una búsqueda por minuto para usuarios no identificados."
-
-#: mod/search.php:224 mod/community.php:66 mod/community.php:75
-msgid "No results."
-msgstr "Sin resultados."
-
-#: mod/search.php:230
-#, php-format
-msgid "Items tagged with: %s"
-msgstr "Objetos taggeado con: %s"
-
-#: mod/search.php:232 mod/contacts.php:797 mod/network.php:146
-#, php-format
-msgid "Results for: %s"
-msgstr "Resultados para: %s"
-
-#: mod/friendica.php:70
-msgid "This is Friendica, version"
-msgstr "Esto es Friendica, versión"
-
-#: mod/friendica.php:71
-msgid "running at web location"
-msgstr "ejecutándose en la dirección web"
-
-#: mod/friendica.php:73
-msgid ""
-"Please visit <a href=\"http://friendica.com\">Friendica.com</a> to learn "
-"more about the Friendica project."
-msgstr "Por favor, visita <a href=\"http://friendica.com\">Friendica.com</a> para saber más sobre el proyecto Friendica."
-
-#: mod/friendica.php:75
-msgid "Bug reports and issues: please visit"
-msgstr "Reporte de fallos y problemas: por favor visita"
-
-#: mod/friendica.php:75
-msgid "the bugtracker at github"
-msgstr "aviso de fallas (bugs) en github"
-
-#: mod/friendica.php:76
-msgid ""
-"Suggestions, praise, donations, etc. - please email \"Info\" at Friendica - "
-"dot com"
-msgstr "Sugerencias, elogios, donaciones, etc. por favor manda un correo a Info arroba Friendica punto com"
-
-#: mod/friendica.php:90
-msgid "Installed plugins/addons/apps:"
-msgstr "Módulos/extensiones/aplicaciones instalados:"
-
-#: mod/friendica.php:103
-msgid "No installed plugins/addons/apps"
-msgstr "Módulos/extensiones/aplicaciones no instalados"
-
-#: mod/lostpass.php:19
-msgid "No valid account found."
-msgstr "No se ha encontrado ninguna cuenta válida"
-
-#: mod/lostpass.php:35
-msgid "Password reset request issued. Check your email."
-msgstr "Solicitud de restablecimiento de contraseña enviada. Revisa tu correo."
-
-#: mod/lostpass.php:42
+#: include/user.php:437
 #, php-format
-msgid ""
-"\n"
-"\t\tDear %1$s,\n"
-"\t\t\tA request was recently received at \"%2$s\" to reset your account\n"
-"\t\tpassword. In order to confirm this request, please select the verification link\n"
-"\t\tbelow or paste it into your web browser address bar.\n"
-"\n"
-"\t\tIf you did NOT request this change, please DO NOT follow the link\n"
-"\t\tprovided and ignore and/or delete this email.\n"
-"\n"
-"\t\tYour password will not be changed unless we can verify that you\n"
-"\t\tissued this request."
-msgstr "\n\t\tEstimado %1$s,\n\t\t\tUna consulta llego recientemente a \"%2$s\" para renovar su\n\t\tcontraseña. Para confirmar esta solicitud por favor seleccione el enlace de verificación mas \n\t\tabajo o copie a pegue el mismo en la barra de dirección de su navegador.\n\n\t\tSi NO ha solicitado este cambio por favor NO SIGA este enlace\n\t\tproporcionado y ignore o borre este mail.\n\n\t\tSu contraseña no sera cambiada hasta que podamos verificar que usted haza\n\t\tsolicitado este cambio.."
+msgid ""
+"\n"
+"\t\tDear %1$s,\n"
+"\t\t\tThank you for registering at %2$s. Your account has been created.\n"
+"\t"
+msgstr "\n\t\tEstimado %1$s,\n\t\t\tGracias por registrar en %2$s. Su cuenta ha sido creada.\n\t"
 
-#: mod/lostpass.php:53
+#: include/user.php:441
 #, php-format
 msgid ""
 "\n"
-"\t\tFollow this link to verify your identity:\n"
+"\t\tThe login details are as follows:\n"
+"\t\t\tSite Location:\t%3$s\n"
+"\t\t\tLogin Name:\t%1$s\n"
+"\t\t\tPassword:\t%5$s\n"
 "\n"
-"\t\t%1$s\n"
+"\t\tYou may change your password from your account \"Settings\" page after logging\n"
+"\t\tin.\n"
 "\n"
-"\t\tYou will then receive a follow-up message containing the new password.\n"
-"\t\tYou may change that password from your account settings page after logging in.\n"
+"\t\tPlease take a few moments to review the other account settings on that page.\n"
 "\n"
-"\t\tThe login details are as follows:\n"
+"\t\tYou may also wish to add some basic information to your default profile\n"
+"\t\t(on the \"Profiles\" page) so that other people can easily find you.\n"
 "\n"
-"\t\tSite Location:\t%2$s\n"
-"\t\tLogin Name:\t%3$s"
-msgstr "\n\t\tSiga este enlace para verificar su identidad:\n\n\t\t%1$s\n\n\t\tA continuación recibirá un mensaje consecutivo conteniendo la nueva contraseña.\n\t\tPodrá cambiar la contraseña después de haber accedido a la cuenta.\n\n\t\tLos detalles del acceso son las siguientes:\n\n\t\tDirección del sitio:\t%2$s\n\t\tNombre de la cuenta:\t%3$s"
+"\t\tWe recommend setting your full name, adding a profile photo,\n"
+"\t\tadding some profile \"keywords\" (very useful in making new friends) - and\n"
+"\t\tperhaps what country you live in; if you do not wish to be more specific\n"
+"\t\tthan that.\n"
+"\n"
+"\t\tWe fully respect your right to privacy, and none of these items are necessary.\n"
+"\t\tIf you are new and do not know anybody here, they may help\n"
+"\t\tyou to make some new and interesting friends.\n"
+"\n"
+"\n"
+"\t\tThank you and welcome to %2$s."
+msgstr "\n\t\t\tLos detalles de acceso son las siguientes:\n\n\t\t\tDirección del sitio:\t%3$s\n\t\t\tNombre de la cuenta:\t\t%1$s\n\t\t\tContraseña:\t\t%5$s\n\n\t\t\tPodrá cambiar la contraseña desde la pagina de configuración de su cuenta después de acceder a la misma\n\t\t\ten.\n\n\t\t\tPor favor tome unos minutos para revisar las opciones demás de la cuenta en dicha pagina de configuración.\n\n\t\t\tTambién podrá agregar informaciones adicionales a su pagina de perfil predeterminado. \n\t\t\t(en la pagina \"Perfiles\") para que otras personas pueden encontrarlo fácilmente.\n\n\t\t\tRecomendamos que elija un nombre apropiado, agregando una imagen de perfil,\n\t\t\tagregando algunas palabras claves de la cuenta (muy útil para hacer nuevos amigos) - y \n\t\t\tquizás el país en donde vive; si no quiere ser mas especifico\n\t\t\tque eso.\n\n\t\t\tRespetamos absolutamente su derecho a la privacidad y ninguno de estos detalles es necesario.\n\t\t\tSi eres nuevo aquí y no conoces a nadie, estos detalles pueden ayudarte\n\t\t\tpara hacer nuevas e interesantes amistades.\n\n\t\t\tGracias y bienvenido a  %2$s."
 
-#: mod/lostpass.php:72
+#: include/user.php:473 mod/admin.php:1223
 #, php-format
-msgid "Password reset requested at %s"
-msgstr "Contraseña restablecida enviada a %s"
+msgid "Registration details for %s"
+msgstr "Detalles de registro para %s"
 
-#: mod/lostpass.php:92
-msgid ""
-"Request could not be verified. (You may have previously submitted it.) "
-"Password reset failed."
-msgstr "La solicitud no puede ser verificada (deberías haberla proporcionado antes). Falló el restablecimiento de la contraseña."
+#: index.php:248 mod/apps.php:7
+msgid "You must be logged in to use addons. "
+msgstr "Tienes que estar registrado para tener acceso a los accesorios."
 
-#: mod/lostpass.php:109 boot.php:1807
-msgid "Password Reset"
-msgstr "Restablecer la contraseña"
+#: index.php:292 mod/fetch.php:12 mod/fetch.php:39 mod/fetch.php:48
+#: mod/help.php:53 mod/p.php:16 mod/p.php:43 mod/p.php:52
+msgid "Not Found"
+msgstr "No se ha encontrado"
 
-#: mod/lostpass.php:110
-msgid "Your password has been reset as requested."
-msgstr "Tu contraseña ha sido restablecida como solicitaste."
+#: index.php:295 mod/help.php:56
+msgid "Page not found."
+msgstr "Página no encontrada."
 
-#: mod/lostpass.php:111
-msgid "Your new password is"
-msgstr "Tu nueva contraseña es"
+#: index.php:406 mod/group.php:76 mod/profperm.php:20
+msgid "Permission denied"
+msgstr "Permiso denegado"
 
-#: mod/lostpass.php:112
-msgid "Save or copy your new password - and then"
-msgstr "Guarda o copia tu nueva contraseña y luego"
+#: index.php:457
+msgid "toggle mobile"
+msgstr "Cambiar a versión móvil"
 
-#: mod/lostpass.php:113
-msgid "click here to login"
-msgstr "pulsa aquí para acceder"
+#: mod/admin.php:96
+msgid "Theme settings updated."
+msgstr "Configuración de la apariencia actualizada."
 
-#: mod/lostpass.php:114
-msgid ""
-"Your password may be changed from the <em>Settings</em> page after "
-"successful login."
-msgstr "Puedes cambiar tu contraseña desde la página de <em>Configuración</em> después de acceder con éxito."
+#: mod/admin.php:162 mod/admin.php:967
+msgid "Site"
+msgstr "Sitio"
 
-#: mod/lostpass.php:125
-#, php-format
-msgid ""
-"\n"
-"\t\t\t\tDear %1$s,\n"
-"\t\t\t\t\tYour password has been changed as requested. Please retain this\n"
-"\t\t\t\tinformation for your records (or change your password immediately to\n"
-"\t\t\t\tsomething that you will remember).\n"
-"\t\t\t"
-msgstr "\n\t\t\t\tEstimado %1$s,\n\t\t\t\t\tSu contraseña ha cambiado como solicitado. Por favor guarde esta\n\t\t\t\tinformación para sus documentación (o cambie su contraseña inmediatamente a\n\t\t\t\talgo que pueda recordar).\n\t\t"
+#: mod/admin.php:163 mod/admin.php:901 mod/admin.php:1413 mod/admin.php:1429
+msgid "Users"
+msgstr "Usuarios"
 
-#: mod/lostpass.php:131
-#, php-format
-msgid ""
-"\n"
-"\t\t\t\tYour login details are as follows:\n"
-"\n"
-"\t\t\t\tSite Location:\t%1$s\n"
-"\t\t\t\tLogin Name:\t%2$s\n"
-"\t\t\t\tPassword:\t%3$s\n"
-"\n"
-"\t\t\t\tYou may change that password from your account settings page after logging in.\n"
-"\t\t\t"
-msgstr "\n\t\t\t\tSus datos de acceso son las siguientes:\n\n\t\t\t\tDirección del sitio:\t%1$s\n\t\t\t\tNombre de cuenta:\t%2$s\n\t\t\t\tContraseña:\t%3$s\n\n\t\t\t\tPodrá cambiar esta contraseña después de ingresar al sitio en su pagina de configuración.\n\t\t\t"
+#: mod/admin.php:164 mod/admin.php:1531 mod/admin.php:1594 mod/settings.php:74
+msgid "Plugins"
+msgstr "Módulos"
 
-#: mod/lostpass.php:147
-#, php-format
-msgid "Your password has been changed at %s"
-msgstr "Tu contraseña se ha cambiado por %s"
+#: mod/admin.php:165 mod/admin.php:1807 mod/admin.php:1857
+msgid "Themes"
+msgstr "Temas"
 
-#: mod/lostpass.php:159
-msgid "Forgot your Password?"
-msgstr "¿Olvidaste tu contraseña?"
+#: mod/admin.php:166 mod/settings.php:52
+msgid "Additional features"
+msgstr "Características adicionales"
 
-#: mod/lostpass.php:160
-msgid ""
-"Enter your email address and submit to have your password reset. Then check "
-"your email for further instructions."
-msgstr "Introduce tu correo para restablecer tu contraseña. Luego comprueba tu correo para las instrucciones adicionales."
+#: mod/admin.php:167
+msgid "DB updates"
+msgstr "Actualizaciones de la Base de Datos"
 
-#: mod/lostpass.php:161 boot.php:1795
-msgid "Nickname or Email: "
-msgstr "Apodo o Correo electrónico: "
+#: mod/admin.php:168 mod/admin.php:416
+msgid "Inspect Queue"
+msgstr "Inspeccionar cola"
 
-#: mod/lostpass.php:162
-msgid "Reset"
-msgstr "Restablecer"
+#: mod/admin.php:169 mod/admin.php:382
+msgid "Federation Statistics"
+msgstr "Estadísticas de federación"
 
-#: mod/hcard.php:10
-msgid "No profile"
-msgstr "Nigún perfil"
+#: mod/admin.php:183 mod/admin.php:194 mod/admin.php:1931
+msgid "Logs"
+msgstr "Registros"
 
-#: mod/help.php:41
-msgid "Help:"
-msgstr "Ayuda:"
+#: mod/admin.php:184 mod/admin.php:1999
+msgid "View Logs"
+msgstr "Ver registro de depuración"
 
-#: mod/help.php:53 mod/p.php:16 mod/p.php:43 mod/p.php:52 mod/fetch.php:12
-#: mod/fetch.php:39 mod/fetch.php:48 index.php:288
-msgid "Not Found"
-msgstr "No se ha encontrado"
+#: mod/admin.php:185
+msgid "probe address"
+msgstr "probar direccion"
 
-#: mod/help.php:56 index.php:291
-msgid "Page not found."
-msgstr "Página no encontrada."
+#: mod/admin.php:186
+msgid "check webfinger"
+msgstr "Verificar webfinger"
 
-#: mod/lockview.php:31 mod/lockview.php:39
-msgid "Remote privacy information not available."
-msgstr "Privacidad de la información remota no disponible."
+#: mod/admin.php:193
+msgid "Plugin Features"
+msgstr "Características del módulo"
 
-#: mod/lockview.php:48
-msgid "Visible to:"
-msgstr "Visible para:"
+#: mod/admin.php:195
+msgid "diagnostics"
+msgstr "diagnosticos"
 
-#: mod/openid.php:24
-msgid "OpenID protocol error. No ID returned."
-msgstr "Error de protocolo OpenID. ID no devuelta."
+#: mod/admin.php:196
+msgid "User registrations waiting for confirmation"
+msgstr "Registro de usuarios esperando la confirmación"
 
-#: mod/openid.php:60
+#: mod/admin.php:312
+msgid "unknown"
+msgstr "desconocido"
+
+#: mod/admin.php:375
 msgid ""
-"Account not found and OpenID registration is not permitted on this site."
-msgstr "Cuenta no encontrada y el registro OpenID no está permitido en ese sitio."
+"This page offers you some numbers to the known part of the federated social "
+"network your Friendica node is part of. These numbers are not complete but "
+"only reflect the part of the network your node is aware of."
+msgstr "Esta pagina ofrece algunos datos sobre la red conocida a la que tu nodo friendica esta conectado. Estos nummeros no son completos respecto a las redes federadas, si no refleja los nodos esta instancia conoce. "
 
-#: mod/uimport.php:50 mod/register.php:198
+#: mod/admin.php:376
 msgid ""
-"This site has exceeded the number of allowed daily account registrations. "
-"Please try again tomorrow."
-msgstr "Este sitio ha excedido el número de registros diarios permitidos. Inténtalo de nuevo mañana por favor."
+"The <em>Auto Discovered Contact Directory</em> feature is not enabled, it "
+"will improve the data displayed here."
+msgstr "El modulo <em>directorio de contactos encontrados</em> no esta habilitado, habilitado aumentara la cantidad de datos detallados aquí."
 
-#: mod/uimport.php:64 mod/register.php:295
-msgid "Import"
-msgstr "Importar"
+#: mod/admin.php:381 mod/admin.php:415 mod/admin.php:493 mod/admin.php:966
+#: mod/admin.php:1412 mod/admin.php:1530 mod/admin.php:1593 mod/admin.php:1806
+#: mod/admin.php:1856 mod/admin.php:1930 mod/admin.php:1998
+msgid "Administration"
+msgstr "Administración"
 
-#: mod/uimport.php:66
-msgid "Move account"
-msgstr "Mover cuenta"
+#: mod/admin.php:388
+#, php-format
+msgid "Currently this node is aware of %d nodes from the following platforms:"
+msgstr "Actualmente este nodo reconoce %d nodos de las siguientes plataformas:"
 
-#: mod/uimport.php:67
-msgid "You can import an account from another Friendica server."
-msgstr "Puedes importar una cuenta desde otro servidor de Friendica."
+#: mod/admin.php:418
+msgid "ID"
+msgstr "ID"
 
-#: mod/uimport.php:68
-msgid ""
-"You need to export your account from the old server and upload it here. We "
-"will recreate your old account here with all your contacts. We will try also"
-" to inform your friends that you moved here."
-msgstr "Necesitas exportar tu cuenta del antiguo servidor y subirla aquí. Volveremos a crear tu antigua cuenta con todos tus contactos aquí. También intentaremos de informar a tus amigos de que te has mudado."
+#: mod/admin.php:419
+msgid "Recipient Name"
+msgstr "Nombre del recipiente"
 
-#: mod/uimport.php:69
-msgid ""
-"This feature is experimental. We can't import contacts from the OStatus "
-"network (GNU Social/Statusnet) or from Diaspora"
-msgstr "Esta característica es experimental. No podemos importar contactos desde la red OStatus (statusnet/identi.ca) o desde Diaspora*"
+#: mod/admin.php:420
+msgid "Recipient Profile"
+msgstr "Perfil del recipiente"
 
-#: mod/uimport.php:70
-msgid "Account file"
-msgstr "Archivo de la cuenta"
+#: mod/admin.php:422
+msgid "Created"
+msgstr "Creado"
 
-#: mod/uimport.php:70
+#: mod/admin.php:423
+msgid "Last Tried"
+msgstr "Ultimo intento"
+
+#: mod/admin.php:424
 msgid ""
-"To export your account, go to \"Settings->Export your personal data\" and "
-"select \"Export account\""
-msgstr "Para exportar el perfil vaya a \"Configuracion -> Exportar sus datos personales\" y seleccione \"Exportar cuenta\""
+"This page lists the content of the queue for outgoing postings. These are "
+"postings the initial delivery failed for. They will be resend later and "
+"eventually deleted if the delivery fails permanently."
+msgstr "Esta pagina muestra la cola de mensajes salientes. Estos son publicaciones cuyo envío inicial fallo. Serán reenviados mas tarde y eventualmente eliminados si la entrega falla permanentemente. "
 
-#: mod/nogroup.php:41 mod/contacts.php:586 mod/contacts.php:930
-#: mod/viewcontacts.php:97
+#: mod/admin.php:449
 #, php-format
-msgid "Visit %s's profile [%s]"
-msgstr "Ver el perfil de %s [%s]"
+msgid ""
+"Your DB still runs with MyISAM tables. You should change the engine type to "
+"InnoDB. As Friendica will use InnoDB only features in the future, you should"
+" change this! See <a href=\"%s\">here</a> for a guide that may be helpful "
+"converting the table engines. You may also use the "
+"<tt>convert_innodb.sql</tt> in the <tt>/util</tt> directory of your "
+"Friendica installation.<br />"
+msgstr "Su DB aún funciona con las tablas MyISAM. Debería cambiar el tipo de motror a InnoDB. ¡Como Friendica sólo usará las características de InnoDB en el futuro, debería cambiar esto! Vea <a href=\"%s\">aquí</a> para una guía que puede ayudar a convertir las tablas de motor. También puede usar <tt>convert_innodb.sql</tt> en el directorio <tt>/util</tt> de su instalación de Friendica.<br />"
 
-#: mod/nogroup.php:42 mod/contacts.php:931
-msgid "Edit contact"
-msgstr "Modificar contacto"
+#: mod/admin.php:454
+msgid ""
+"You are using a MySQL version which does not support all features that "
+"Friendica uses. You should consider switching to MariaDB."
+msgstr "Está usando una versión de MySQL que no soporta todas las características de Friendica. Debería considerar cambiar a MariaDB."
 
-#: mod/nogroup.php:63
-msgid "Contacts who are not members of a group"
-msgstr "Contactos sin grupo"
+#: mod/admin.php:458 mod/admin.php:1362
+msgid "Normal Account"
+msgstr "Cuenta normal"
 
-#: mod/uexport.php:29
-msgid "Export account"
-msgstr "Exportar cuenta"
+#: mod/admin.php:459 mod/admin.php:1363
+msgid "Soapbox Account"
+msgstr "Cuenta tribuna"
 
-#: mod/uexport.php:29
-msgid ""
-"Export your account info and contacts. Use this to make a backup of your "
-"account and/or to move it to another server."
-msgstr "Exporta la información de tu cuenta y tus contactos. Úsalo para guardar una copia de seguridad de tu cuenta y/o moverla a otro servidor."
+#: mod/admin.php:460 mod/admin.php:1364
+msgid "Community/Celebrity Account"
+msgstr "Cuenta de Comunidad/Celebridad"
 
-#: mod/uexport.php:30
-msgid "Export all"
-msgstr "Exportar todo"
+#: mod/admin.php:461 mod/admin.php:1365
+msgid "Automatic Friend Account"
+msgstr "Cuenta de amistad automática"
+
+#: mod/admin.php:462
+msgid "Blog Account"
+msgstr "Cuenta de blog"
 
-#: mod/uexport.php:30
-msgid ""
-"Export your accout info, contacts and all your items as json. Could be a "
-"very big file, and could take a lot of time. Use this to make a full backup "
-"of your account (photos are not exported)"
-msgstr "Exporta la información de tu cuenta, contactos y lo demás en JSON. Puede ser un archivo bastante grande, por lo que llevará tiempo. Úsalo para hacer una copia de seguridad completa de tu cuenta (las fotos no se exportarán)"
+#: mod/admin.php:463
+msgid "Private Forum"
+msgstr "Foro privado"
 
-#: mod/uexport.php:37 mod/settings.php:95
-msgid "Export personal data"
-msgstr "Exportación de datos personales"
+#: mod/admin.php:488
+msgid "Message queues"
+msgstr "Cola de mensajes"
 
-#: mod/invite.php:27
-msgid "Total invitation limit exceeded."
-msgstr "Límite total de invitaciones excedido."
+#: mod/admin.php:494
+msgid "Summary"
+msgstr "Resumen"
 
-#: mod/invite.php:49
-#, php-format
-msgid "%s : Not a valid email address."
-msgstr "%s : No es una dirección de correo válida."
+#: mod/admin.php:496
+msgid "Registered users"
+msgstr "Usuarios registrados"
 
-#: mod/invite.php:73
-msgid "Please join us on Friendica"
-msgstr "Únete a nosotros en Friendica"
+#: mod/admin.php:498
+msgid "Pending registrations"
+msgstr "Pendientes de registro"
 
-#: mod/invite.php:84
-msgid "Invitation limit exceeded. Please contact your site administrator."
-msgstr "Límite de invitaciones sobrepasado. Contacta con el administrador del sitio."
+#: mod/admin.php:499
+msgid "Version"
+msgstr "Versión"
 
-#: mod/invite.php:89
-#, php-format
-msgid "%s : Message delivery failed."
-msgstr "%s : Ha fallado la entrega del mensaje."
+#: mod/admin.php:504
+msgid "Active plugins"
+msgstr "Módulos activos"
 
-#: mod/invite.php:93
-#, php-format
-msgid "%d message sent."
-msgid_plural "%d messages sent."
-msgstr[0] "%d mensaje enviado."
-msgstr[1] "%d mensajes enviados."
+#: mod/admin.php:529
+msgid "Can not parse base url. Must have at least <scheme>://<domain>"
+msgstr "No se puede resolver la direccion URL base.\nDeberá tener al menos <scheme>://<domain>"
 
-#: mod/invite.php:112
-msgid "You have no more invitations available"
-msgstr "No tienes más invitaciones disponibles"
+#: mod/admin.php:819
+msgid "RINO2 needs mcrypt php extension to work."
+msgstr "RINO2 precisa la extensión mcrypt para funcionar.  "
 
-#: mod/invite.php:120
-#, php-format
-msgid ""
-"Visit %s for a list of public sites that you can join. Friendica members on "
-"other sites can all connect with each other, as well as with members of many"
-" other social networks."
-msgstr "Visita %s para ver una lista de servidores públicos donde puedes darte de alta. Los miembros de otros servidores de Friendica pueden conectarse entre ellos, así como con miembros de otras redes sociales diferentes."
+#: mod/admin.php:827
+msgid "Site settings updated."
+msgstr "Configuración de actualización."
 
-#: mod/invite.php:122
-#, php-format
-msgid ""
-"To accept this invitation, please visit and register at %s or any other "
-"public Friendica website."
-msgstr "Para aceptar la invitación visita y regístrate en %s o en cualquier otro servidor público de Friendica."
+#: mod/admin.php:855 mod/settings.php:943
+msgid "No special theme for mobile devices"
+msgstr "No hay tema especial para dispositivos móviles"
 
-#: mod/invite.php:123
-#, php-format
-msgid ""
-"Friendica sites all inter-connect to create a huge privacy-enhanced social "
-"web that is owned and controlled by its members. They can also connect with "
-"many traditional social networks. See %s for a list of alternate Friendica "
-"sites you can join."
-msgstr "Los servidores de Friendica están interconectados para crear una enorme red social centrada en la privacidad y controlada por sus miembros. También se puede conectar con muchas redes sociales tradicionales. Mira en %s para poder ver un listado de servidores alternativos de Friendica donde puedes darte de alta."
+#: mod/admin.php:884
+msgid "No community page"
+msgstr "No hay pagina de comunidad"
 
-#: mod/invite.php:126
-msgid ""
-"Our apologies. This system is not currently configured to connect with other"
-" public sites or invite members."
-msgstr "Discúlpanos. Este sistema no está configurado actualmente para conectar con otros servidores públicos o invitar nuevos miembros."
+#: mod/admin.php:885
+msgid "Public postings from users of this site"
+msgstr "Temas públicos de perfiles de este sitio."
 
-#: mod/invite.php:132
-msgid "Send invitations"
-msgstr "Enviar invitaciones"
+#: mod/admin.php:886
+msgid "Global community page"
+msgstr "Pagina global de comunidad"
 
-#: mod/invite.php:133
-msgid "Enter email addresses, one per line:"
-msgstr "Introduce las direcciones de correo, una por línea:"
+#: mod/admin.php:891 mod/contacts.php:538
+msgid "Never"
+msgstr "Nunca"
 
-#: mod/invite.php:134 mod/wallmessage.php:151 mod/message.php:351
-#: mod/message.php:541
-msgid "Your message:"
-msgstr "Tu mensaje:"
+#: mod/admin.php:892
+msgid "At post arrival"
+msgstr "A la llegada de una publicación"
 
-#: mod/invite.php:135
-msgid ""
-"You are cordially invited to join me and other close friends on Friendica - "
-"and help us to create a better social web."
-msgstr "Estás cordialmente invitado a unirte a mi y a otros amigos en Friendica, creemos juntos una red social mejor."
+#: mod/admin.php:900 mod/contacts.php:565
+msgid "Disabled"
+msgstr "Deshabilitado"
 
-#: mod/invite.php:137
-msgid "You will need to supply this invitation code: $invite_code"
-msgstr "Tienes que proporcionar el siguiente código: $invite_code"
+#: mod/admin.php:902
+msgid "Users, Global Contacts"
+msgstr "Perfiles, contactos globales"
 
-#: mod/invite.php:137
-msgid ""
-"Once you have registered, please connect with me via my profile page at:"
-msgstr "Una vez registrado, por favor contacta conmigo a través de mi página de perfil en:"
+#: mod/admin.php:903
+msgid "Users, Global Contacts/fallback"
+msgstr "Perfiles, contactos globales/fallback"
 
-#: mod/invite.php:139
-msgid ""
-"For more information about the Friendica project and why we feel it is "
-"important, please visit http://friendica.com"
-msgstr "Para más información sobre el Proyecto Friendica y sobre por qué pensamos que es algo importante, visita http://friendica.com"
+#: mod/admin.php:907
+msgid "One month"
+msgstr "Un mes"
 
-#: mod/invite.php:140 mod/localtime.php:45 mod/message.php:357
-#: mod/message.php:547 mod/manage.php:143 mod/crepair.php:154
-#: mod/content.php:728 mod/fsuggest.php:107 mod/mood.php:137 mod/poke.php:199
-#: mod/profiles.php:688 mod/events.php:506 mod/photos.php:1104
-#: mod/photos.php:1226 mod/photos.php:1539 mod/photos.php:1590
-#: mod/photos.php:1638 mod/photos.php:1724 mod/contacts.php:577
-#: mod/install.php:272 mod/install.php:312 object/Item.php:720
-#: view/theme/frio/config.php:59 view/theme/quattro/config.php:64
-#: view/theme/vier/config.php:107 view/theme/duepuntozero/config.php:59
-msgid "Submit"
-msgstr "Envíar"
+#: mod/admin.php:908
+msgid "Three months"
+msgstr "Tres meses"
 
-#: mod/fbrowser.php:133
-msgid "Files"
-msgstr "Archivos"
+#: mod/admin.php:909
+msgid "Half a year"
+msgstr "Medio año"
 
-#: mod/profperm.php:19 mod/group.php:72 index.php:400
-msgid "Permission denied"
-msgstr "Permiso denegado"
+#: mod/admin.php:910
+msgid "One year"
+msgstr "Un año"
 
-#: mod/profperm.php:25 mod/profperm.php:56
-msgid "Invalid profile identifier."
-msgstr "Identificador de perfil no válido."
+#: mod/admin.php:915
+msgid "Multi user instance"
+msgstr "Sesión multi usuario"
 
-#: mod/profperm.php:102
-msgid "Profile Visibility Editor"
-msgstr "Editor de visibilidad del perfil"
+#: mod/admin.php:938
+msgid "Closed"
+msgstr "Cerrado"
 
-#: mod/profperm.php:106 mod/group.php:223
-msgid "Click on a contact to add or remove."
-msgstr "Pulsa en un contacto para añadirlo o eliminarlo."
+#: mod/admin.php:939
+msgid "Requires approval"
+msgstr "Requiere aprobación"
 
-#: mod/profperm.php:115
-msgid "Visible To"
-msgstr "Visible para"
+#: mod/admin.php:940
+msgid "Open"
+msgstr "Abierto"
 
-#: mod/profperm.php:131
-msgid "All Contacts (with secure profile access)"
-msgstr "Todos los contactos (con perfil de acceso seguro)"
+#: mod/admin.php:944
+msgid "No SSL policy, links will track page SSL state"
+msgstr "No existe una política de SSL, los vínculos harán un seguimiento del estado de SSL en la página"
 
-#: mod/tagrm.php:41
-msgid "Tag removed"
-msgstr "Etiqueta eliminada"
+#: mod/admin.php:945
+msgid "Force all links to use SSL"
+msgstr "Forzar todos los enlaces a utilizar SSL"
 
-#: mod/tagrm.php:79
-msgid "Remove Item Tag"
-msgstr "Eliminar etiqueta"
+#: mod/admin.php:946
+msgid "Self-signed certificate, use SSL for local links only (discouraged)"
+msgstr "Certificación personal, usa SSL solo para enlaces locales (no recomendado)"
 
-#: mod/tagrm.php:81
-msgid "Select a tag to remove: "
-msgstr "Selecciona una etiqueta para eliminar: "
+#: mod/admin.php:968 mod/admin.php:1595 mod/admin.php:1858 mod/admin.php:1932
+#: mod/admin.php:2085 mod/settings.php:681 mod/settings.php:792
+#: mod/settings.php:841 mod/settings.php:908 mod/settings.php:1005
+#: mod/settings.php:1271
+msgid "Save Settings"
+msgstr "Guardar configuración"
 
-#: mod/tagrm.php:93 mod/delegate.php:139
-msgid "Remove"
-msgstr "Eliminar"
+#: mod/admin.php:969 mod/register.php:272
+msgid "Registration"
+msgstr "Registro"
 
-#: mod/repair_ostatus.php:14
-msgid "Resubscribing to OStatus contacts"
-msgstr "Resubscribir a contactos de OStatus"
+#: mod/admin.php:970
+msgid "File upload"
+msgstr "Subida de archivo"
 
-#: mod/repair_ostatus.php:30
-msgid "Error"
-msgstr "error"
+#: mod/admin.php:971
+msgid "Policies"
+msgstr "Políticas"
 
-#: mod/repair_ostatus.php:44 mod/ostatus_subscribe.php:51
-msgid "Done"
-msgstr "hecho!"
+#: mod/admin.php:973
+msgid "Auto Discovered Contact Directory"
+msgstr "Directorio de contactos descubierto automáticamente"
 
-#: mod/repair_ostatus.php:50 mod/ostatus_subscribe.php:73
-msgid "Keep this window open until done."
-msgstr "Mantén esta ventana abierta hasta que el proceso ha terminado."
+#: mod/admin.php:974
+msgid "Performance"
+msgstr "Rendimiento"
 
-#: mod/delegate.php:101
-msgid "No potential page delegates located."
-msgstr "No se han localizado delegados potenciales de la página."
+#: mod/admin.php:975
+msgid "Worker"
+msgstr "Trabajador (??)"
 
-#: mod/delegate.php:132
+#: mod/admin.php:976
 msgid ""
-"Delegates are able to manage all aspects of this account/page except for "
-"basic account settings. Please do not delegate your personal account to "
-"anybody that you do not trust completely."
-msgstr "Los delegados tienen la capacidad de gestionar todos los aspectos de esta cuenta/página, excepto los ajustes básicos de la cuenta. Por favor, no delegues tu cuenta personal a nadie en quien no confíes completamente."
+"Relocate - WARNING: advanced function. Could make this server unreachable."
+msgstr "Reubicación - ADVERTENCIA: función avanzada. Puede hacer a este servidor inaccesible. "
 
-#: mod/delegate.php:133
-msgid "Existing Page Managers"
-msgstr "Administradores actuales de la página"
+#: mod/admin.php:979
+msgid "Site name"
+msgstr "Nombre del sitio"
 
-#: mod/delegate.php:135
-msgid "Existing Page Delegates"
-msgstr "Delegados actuales de la página"
+#: mod/admin.php:980
+msgid "Host name"
+msgstr "Nombre de dominio"
 
-#: mod/delegate.php:137
-msgid "Potential Delegates"
-msgstr "Delegados potenciales"
+#: mod/admin.php:981
+msgid "Sender Email"
+msgstr "Dirección de origen de correo electrónico"
 
-#: mod/delegate.php:140
-msgid "Add"
-msgstr "Añadir"
+#: mod/admin.php:981
+msgid ""
+"The email address your server shall use to send notification emails from."
+msgstr "La dirección de correo electrónico que el servidor debería usar como dirección de envío."
 
-#: mod/delegate.php:141
-msgid "No entries."
-msgstr "Sin entradas."
+#: mod/admin.php:982
+msgid "Banner/Logo"
+msgstr "Imagen/Logotipo"
 
-#: mod/credits.php:16
-msgid "Credits"
-msgstr "Creditos"
+#: mod/admin.php:983
+msgid "Shortcut icon"
+msgstr "Icono de atajo"
 
-#: mod/credits.php:17
-msgid ""
-"Friendica is a community project, that would not be possible without the "
-"help of many people. Here is a list of those who have contributed to the "
-"code or the translation of Friendica. Thank you all!"
-msgstr "Friendica es un proyecto comunitario, que no seria posible sin la ayuda de mucha gente. Aquí una lista de de aquellos que aportaron al código o la traducción de friendica.\nGracias a todos! "
+#: mod/admin.php:983
+msgid "Link to an icon that will be used for browsers."
+msgstr "Enlace hacia un icono que sera usado para el navegador."
 
-#: mod/filer.php:30
-msgid "- select -"
-msgstr "- seleccionar -"
+#: mod/admin.php:984
+msgid "Touch icon"
+msgstr "Icono touch"
+
+#: mod/admin.php:984
+msgid "Link to an icon that will be used for tablets and mobiles."
+msgstr "Enlace para un icono que sera usado para tablets y moviles."
+
+#: mod/admin.php:985
+msgid "Additional Info"
+msgstr "Información adicional"
 
-#: mod/subthread.php:103
+#: mod/admin.php:985
 #, php-format
-msgid "%1$s is following %2$s's %3$s"
-msgstr "%1$s está siguiendo las %3$s de %2$s"
+msgid ""
+"For public servers: you can add additional information here that will be "
+"listed at %s/siteinfo."
+msgstr "Para servidores públicos: información adicional  que sera publicado en %s/siteinfo."
 
-#: mod/attach.php:8
-msgid "Item not available."
-msgstr "Elemento no disponible."
+#: mod/admin.php:986
+msgid "System language"
+msgstr "Idioma"
 
-#: mod/attach.php:20
-msgid "Item was not found."
-msgstr "Elemento no encontrado."
+#: mod/admin.php:987
+msgid "System theme"
+msgstr "Tema"
 
-#: mod/apps.php:7 index.php:244
-msgid "You must be logged in to use addons. "
-msgstr "Tienes que estar registrado para tener acceso a los accesorios."
+#: mod/admin.php:987
+msgid ""
+"Default system theme - may be over-ridden by user profiles - <a href='#' "
+"id='cnftheme'>change theme settings</a>"
+msgstr "Tema por defecto del sistema, los usuarios podrán elegir el suyo propio en su configuración <a href='#' id='cnftheme'>cambiar configuración del tema</a>"
 
-#: mod/apps.php:11
-msgid "Applications"
-msgstr "Aplicaciones"
+#: mod/admin.php:988
+msgid "Mobile system theme"
+msgstr "Tema de sistema móvil"
 
-#: mod/apps.php:14
-msgid "No installed applications."
-msgstr "Sin aplicaciones"
+#: mod/admin.php:988
+msgid "Theme for mobile devices"
+msgstr "Tema para dispositivos móviles"
 
-#: mod/p.php:9
-msgid "Not Extended"
-msgstr "No extendido"
+#: mod/admin.php:989
+msgid "SSL link policy"
+msgstr "Política de enlaces SSL"
 
-#: mod/newmember.php:6
-msgid "Welcome to Friendica"
-msgstr "Bienvenido a Friendica "
+#: mod/admin.php:989
+msgid "Determines whether generated links should be forced to use SSL"
+msgstr "Determina si los enlaces generados deben ser forzados a utilizar SSL"
 
-#: mod/newmember.php:8
-msgid "New Member Checklist"
-msgstr "Listado de nuevos miembros"
+#: mod/admin.php:990
+msgid "Force SSL"
+msgstr "Forzar SSL"
 
-#: mod/newmember.php:12
+#: mod/admin.php:990
 msgid ""
-"We would like to offer some tips and links to help make your experience "
-"enjoyable. Click any item to visit the relevant page. A link to this page "
-"will be visible from your home page for two weeks after your initial "
-"registration and then will quietly disappear."
-msgstr "Nos gustaría ofrecerte algunos consejos y enlaces para ayudar a hacer tu experiencia más amena. Pulsa en cualquier elemento para visitar la página correspondiente. Un enlace a esta página será visible desde tu página de inicio durante las dos semanas siguientes a tu inscripción y luego desaparecerá."
-
-#: mod/newmember.php:14
-msgid "Getting Started"
-msgstr "Empezando"
+"Force all Non-SSL requests to SSL - Attention: on some systems it could lead"
+" to endless loops."
+msgstr "Forzar todos las consultas No-SSL a SSL. - ATENCIÓN: en algunos sistemas esto puede generar comportamiento recursivo interminable."
 
-#: mod/newmember.php:18
-msgid "Friendica Walk-Through"
-msgstr "Visita guiada a Friendica"
+#: mod/admin.php:991
+msgid "Hide help entry from navigation menu"
+msgstr "Ocultar la ayuda en el menú de navegación"
 
-#: mod/newmember.php:18
+#: mod/admin.php:991
 msgid ""
-"On your <em>Quick Start</em> page - find a brief introduction to your "
-"profile and network tabs, make some new connections, and find some groups to"
-" join."
-msgstr "En tu página de <em>Inicio Rápido</em> - busca una introducción breve para tus pestañas de perfil y red, haz algunas conexiones nuevas, y busca algunos grupos a los que unirte."
-
-#: mod/newmember.php:26
-msgid "Go to Your Settings"
-msgstr "Ir a tus ajustes"
+"Hides the menu entry for the Help pages from the navigation menu. You can "
+"still access it calling /help directly."
+msgstr "Oculta la entrada de las páginas de Ayuda en el menú de navegación. Todavía se puede acceder escribiendo /ayuda directamente."
 
-#: mod/newmember.php:26
-msgid ""
-"On your <em>Settings</em> page -  change your initial password. Also make a "
-"note of your Identity Address. This looks just like an email address - and "
-"will be useful in making friends on the free social web."
-msgstr "En la página de <em>Configuración</em> puedes cambiar tu contraseña inicial. También aparece tu ID (Identity Address). Es parecida a una dirección de correo y te servirá para conectar con gente de redes sociales libres."
+#: mod/admin.php:992
+msgid "Single user instance"
+msgstr "Sesión de usuario único"
 
-#: mod/newmember.php:28
-msgid ""
-"Review the other settings, particularly the privacy settings. An unpublished"
-" directory listing is like having an unlisted phone number. In general, you "
-"should probably publish your listing - unless all of your friends and "
-"potential friends know exactly how to find you."
-msgstr "Revisa las otras configuraciones, especialmente la configuración de privacidad. Un listado de directorio sin publicar es como tener un número de teléfono sin publicar. Normalmente querrás publicar tu listado, a menos que tus amigos y amigos potenciales sepan cómo ponerse en contacto contigo."
+#: mod/admin.php:992
+msgid "Make this instance multi-user or single-user for the named user"
+msgstr "Haz esta sesión multi-usuario o usuario único para el usuario"
 
-#: mod/newmember.php:36 mod/profile_photo.php:250 mod/profiles.php:707
-msgid "Upload Profile Photo"
-msgstr "Subir foto del Perfil"
+#: mod/admin.php:993
+msgid "Maximum image size"
+msgstr "Tamaño máximo de la imagen"
 
-#: mod/newmember.php:36
+#: mod/admin.php:993
 msgid ""
-"Upload a profile photo if you have not done so already. Studies have shown "
-"that people with real photos of themselves are ten times more likely to make"
-" friends than people who do not."
-msgstr "Sube una foto para tu perfil si no lo has hecho aún. Los estudios han demostrado que la gente que usa fotos suyas reales tienen diez veces más éxito a la hora de entablar amistad que las que no."
+"Maximum size in bytes of uploaded images. Default is 0, which means no "
+"limits."
+msgstr "Tamaño máximo en bytes de las imágenes a subir. Por defecto es 0, que quiere decir que no hay límite."
 
-#: mod/newmember.php:38
-msgid "Edit Your Profile"
-msgstr "Editar tu perfil"
+#: mod/admin.php:994
+msgid "Maximum image length"
+msgstr "Largo máximo de imagen"
 
-#: mod/newmember.php:38
+#: mod/admin.php:994
 msgid ""
-"Edit your <strong>default</strong> profile to your liking. Review the "
-"settings for hiding your list of friends and hiding the profile from unknown"
-" visitors."
-msgstr "Edita tu perfil <strong>predeterminado</strong> como quieras. Revisa la configuración para ocultar tu lista de amigos o tu perfil a los visitantes desconocidos."
+"Maximum length in pixels of the longest side of uploaded images. Default is "
+"-1, which means no limits."
+msgstr "Longitud máxima en píxeles del lado más largo de las imágenes subidas. Por defecto es -1, que significa que no hay límites."
 
-#: mod/newmember.php:40
-msgid "Profile Keywords"
-msgstr "Palabras clave del perfil"
+#: mod/admin.php:995
+msgid "JPEG image quality"
+msgstr "Calidad de imagen JPEG"
 
-#: mod/newmember.php:40
+#: mod/admin.php:995
 msgid ""
-"Set some public keywords for your default profile which describe your "
-"interests. We may be able to find other people with similar interests and "
-"suggest friendships."
-msgstr "Define en tu perfil público algunas palabras que describan tus intereses. Así podremos buscar otras personas con los mismos gustos y sugerirte posibles amigos."
+"Uploaded JPEGS will be saved at this quality setting [0-100]. Default is "
+"100, which is full quality."
+msgstr "Los archivos JPEG subidos se guardarán con este ajuste de calidad [0-100]. Por defecto es 100, que es calidad máxima."
 
-#: mod/newmember.php:44
-msgid "Connecting"
-msgstr "Conectando"
+#: mod/admin.php:997
+msgid "Register policy"
+msgstr "Política de registros"
 
-#: mod/newmember.php:51
-msgid "Importing Emails"
-msgstr "Importando correos electrónicos"
+#: mod/admin.php:998
+msgid "Maximum Daily Registrations"
+msgstr "Registros Máximos Diarios"
 
-#: mod/newmember.php:51
+#: mod/admin.php:998
 msgid ""
-"Enter your email access information on your Connector Settings page if you "
-"wish to import and interact with friends or mailing lists from your email "
-"INBOX"
-msgstr "Introduce la información para acceder a tu correo en la página de Configuración del conector si quieres importar e interactuar con amigos o listas de correos del buzón de entrada de tu correo electrónico."
+"If registration is permitted above, this sets the maximum number of new user"
+" registrations to accept per day.  If register is set to closed, this "
+"setting has no effect."
+msgstr "Si anteriormente se ha permitido el registro, esto establece el número máximo de registro de nuevos usuarios aceptados por día. Si el registro se establece como cerrado, esta opción no tiene efecto."
 
-#: mod/newmember.php:53
-msgid "Go to Your Contacts Page"
-msgstr "Ir a tu página de contactos"
+#: mod/admin.php:999
+msgid "Register text"
+msgstr "Términos"
 
-#: mod/newmember.php:53
-msgid ""
-"Your Contacts page is your gateway to managing friendships and connecting "
-"with friends on other networks. Typically you enter their address or site "
-"URL in the <em>Add New Contact</em> dialog."
-msgstr "Tu página de Contactos es el portal desde donde podrás manejar tus amistades y conectarte con amigos de otras redes. Normalmente introduces su dirección o la dirección de su sitio web en el recuadro \"Añadir contacto nuevo\"."
+#: mod/admin.php:999
+msgid "Will be displayed prominently on the registration page."
+msgstr "Se mostrará en un lugar destacado en la página de registro."
 
-#: mod/newmember.php:55
-msgid "Go to Your Site's Directory"
-msgstr "Ir al directorio de tu sitio"
+#: mod/admin.php:1000
+msgid "Accounts abandoned after x days"
+msgstr "Cuentas abandonadas después de x días"
 
-#: mod/newmember.php:55
+#: mod/admin.php:1000
 msgid ""
-"The Directory page lets you find other people in this network or other "
-"federated sites. Look for a <em>Connect</em> or <em>Follow</em> link on "
-"their profile page. Provide your own Identity Address if requested."
-msgstr "El Directorio te permite encontrar otras personas en esta red o en cualquier otro sitio federado. Busca algún enlace de <em>Conectar</em> o <em>Seguir</em> en su perfil. Proporciona tu direción personal si es necesario."
+"Will not waste system resources polling external sites for abandonded "
+"accounts. Enter 0 for no time limit."
+msgstr "No gastará recursos del sistema creando sondeos a sitios externos para cuentas abandonadas. Introduce 0 para ningún límite temporal."
 
-#: mod/newmember.php:57
-msgid "Finding New People"
-msgstr "Encontrando nueva gente"
+#: mod/admin.php:1001
+msgid "Allowed friend domains"
+msgstr "Dominios amigos permitidos"
 
-#: mod/newmember.php:57
+#: mod/admin.php:1001
 msgid ""
-"On the side panel of the Contacts page are several tools to find new "
-"friends. We can match people by interest, look up people by name or "
-"interest, and provide suggestions based on network relationships. On a brand"
-" new site, friend suggestions will usually begin to be populated within 24 "
-"hours."
-msgstr "En el panel lateral de la página de Contactos existen varias herramientas para encontrar nuevos amigos. Podemos filtrar personas por sus intereses, buscar personas por nombre o por sus intereses, y ofrecerte sugerencias basadas en sus relaciones de la red. En un sitio nuevo, las sugerencias de amigos por lo general comienzan pasadas las 24 horas."
+"Comma separated list of domains which are allowed to establish friendships "
+"with this site. Wildcards are accepted. Empty to allow any domains"
+msgstr "Lista separada por comas de los dominios que están autorizados para establecer conexiones con este sitio. Se aceptan comodines. Dejar en blanco para permitir cualquier dominio"
 
-#: mod/newmember.php:65
-msgid "Group Your Contacts"
-msgstr "Agrupa tus contactos"
+#: mod/admin.php:1002
+msgid "Allowed email domains"
+msgstr "Dominios de correo permitidos"
 
-#: mod/newmember.php:65
+#: mod/admin.php:1002
 msgid ""
-"Once you have made some friends, organize them into private conversation "
-"groups from the sidebar of your Contacts page and then you can interact with"
-" each group privately on your Network page."
-msgstr "Una vez que tengas algunos amigos, puedes organizarlos en grupos privados de conversación mediante el memnú en tu página de Contactos y luego puedes interactuar con cada grupo por separado desde tu página de Red."
+"Comma separated list of domains which are allowed in email addresses for "
+"registrations to this site. Wildcards are accepted. Empty to allow any "
+"domains"
+msgstr "Lista separada por comas de los dominios que están autorizados en las direcciones de correo para registrarse en este sitio. Se aceptan comodines. Dejar en blanco para permitir cualquier dominio"
 
-#: mod/newmember.php:68
-msgid "Why Aren't My Posts Public?"
-msgstr "¿Por qué mis publicaciones no son públicas?"
+#: mod/admin.php:1003
+msgid "Block public"
+msgstr "Bloqueo público"
 
-#: mod/newmember.php:68
+#: mod/admin.php:1003
 msgid ""
-"Friendica respects your privacy. By default, your posts will only show up to"
-" people you've added as friends. For more information, see the help section "
-"from the link above."
-msgstr "Friendica respeta tu privacidad. Por defecto, tus publicaciones solo se mostrarán a personas que hayas añadido como amistades. Para más información, mira la sección de ayuda en el enlace de más arriba."
-
-#: mod/newmember.php:73
-msgid "Getting Help"
-msgstr "Consiguiendo ayuda"
+"Check to block public access to all otherwise public personal pages on this "
+"site unless you are currently logged in."
+msgstr "Marca para bloquear el acceso público a todas las páginas personales, aún siendo públicas, hasta que no hayas iniciado tu sesión."
 
-#: mod/newmember.php:77
-msgid "Go to the Help Section"
-msgstr "Ir a la sección de ayuda"
+#: mod/admin.php:1004
+msgid "Force publish"
+msgstr "Forzar publicación"
 
-#: mod/newmember.php:77
+#: mod/admin.php:1004
 msgid ""
-"Our <strong>help</strong> pages may be consulted for detail on other program"
-" features and resources."
-msgstr "Puedes consultar nuestra página de <strong>Ayuda</strong> para más información y recursos de ayuda."
+"Check to force all profiles on this site to be listed in the site directory."
+msgstr "Marca para forzar que todos los perfiles de este sitio sean listados en el directorio del sitio."
 
-#: mod/removeme.php:46 mod/removeme.php:49
-msgid "Remove My Account"
-msgstr "Eliminar mi cuenta"
+#: mod/admin.php:1005
+msgid "Global directory URL"
+msgstr "URL del directorio global."
 
-#: mod/removeme.php:47
+#: mod/admin.php:1005
 msgid ""
-"This will completely remove your account. Once this has been done it is not "
-"recoverable."
-msgstr "Esto eliminará por completo tu cuenta. Una vez hecho no se puede deshacer."
-
-#: mod/removeme.php:48
-msgid "Please enter your password for verification:"
-msgstr "Por favor, introduce tu contraseña para la verificación:"
+"URL to the global directory. If this is not set, the global directory is "
+"completely unavailable to the application."
+msgstr "URL del directorio global. Si se deja este campo vacío, el directorio global sera completamente inaccesible para la instancia."
 
-#: mod/editpost.php:17 mod/editpost.php:27
-msgid "Item not found"
-msgstr "Elemento no encontrado"
+#: mod/admin.php:1006
+msgid "Allow threaded items"
+msgstr "Permitir elementos en hilo"
 
-#: mod/editpost.php:40
-msgid "Edit post"
-msgstr "Editar publicación"
+#: mod/admin.php:1006
+msgid "Allow infinite level threading for items on this site."
+msgstr "Permitir infinitos niveles de hilo para los elementos de este sitio."
 
-#: mod/localtime.php:24
-msgid "Time Conversion"
-msgstr "Conversión horária"
+#: mod/admin.php:1007
+msgid "Private posts by default for new users"
+msgstr "Publicaciones privadas por defecto para usuarios nuevos"
 
-#: mod/localtime.php:26
+#: mod/admin.php:1007
 msgid ""
-"Friendica provides this service for sharing events with other networks and "
-"friends in unknown timezones."
-msgstr "Friendica ofrece este servicio para compartir eventos con otros servidores de la red friendica y amigos en zonas de horarios desconocidos."
+"Set default post permissions for all new members to the default privacy "
+"group rather than public."
+msgstr "Ajusta los permisos de publicación por defecto a los miembros nuevos al grupo privado por defecto en vez del público."
 
-#: mod/localtime.php:30
-#, php-format
-msgid "UTC time: %s"
-msgstr "Tiempo UTC: %s"
+#: mod/admin.php:1008
+msgid "Don't include post content in email notifications"
+msgstr "No incluir el contenido del post en las notificaciones de correo electrónico"
 
-#: mod/localtime.php:33
-#, php-format
-msgid "Current timezone: %s"
-msgstr "Zona horaria actual: %s"
+#: mod/admin.php:1008
+msgid ""
+"Don't include the content of a post/comment/private message/etc. in the "
+"email notifications that are sent out from this site, as a privacy measure."
+msgstr "No incluye el contenido de un mensaje/comentario/mensaje privado/etc. en las notificaciones de correo electrónico que se envían desde este sitio, como una medida de privacidad."
 
-#: mod/localtime.php:36
-#, php-format
-msgid "Converted localtime: %s"
-msgstr "Zona horaria local convertida: %s"
+#: mod/admin.php:1009
+msgid "Disallow public access to addons listed in the apps menu."
+msgstr "Deshabilitar acceso a addons listados en el menú de aplicaciones."
 
-#: mod/localtime.php:41
-msgid "Please select your timezone:"
-msgstr "Por favor, selecciona tu zona horaria:"
+#: mod/admin.php:1009
+msgid ""
+"Checking this box will restrict addons listed in the apps menu to members "
+"only."
+msgstr "Habilitando esta opción restringe el acceso a addons en el menú de aplicaciones a usuarios identificados."
 
-#: mod/bookmarklet.php:41
-msgid "The post was created"
-msgstr "La publicación fue creada"
+#: mod/admin.php:1010
+msgid "Don't embed private images in posts"
+msgstr "No agregar imágenes privados en las publicaciones"
 
-#: mod/group.php:29
-msgid "Group created."
-msgstr "Grupo creado."
+#: mod/admin.php:1010
+msgid ""
+"Don't replace locally-hosted private photos in posts with an embedded copy "
+"of the image. This means that contacts who receive posts containing private "
+"photos will have to authenticate and load each image, which may take a "
+"while."
+msgstr "No reemplazar imágenes privadas guardadas localmente en el servidor con imágenes integrados en los envíos. Esto significa que contactos que reciben publicaciones tendrán que autenticarse y cargar cada imagen, lo que puede demorar."
 
-#: mod/group.php:35
-msgid "Could not create group."
-msgstr "Imposible crear el grupo."
+#: mod/admin.php:1011
+msgid "Allow Users to set remote_self"
+msgstr "Permitir a los usuarios de definir perfiles_remotos"
 
-#: mod/group.php:47 mod/group.php:140
-msgid "Group not found."
-msgstr "Grupo no encontrado."
+#: mod/admin.php:1011
+msgid ""
+"With checking this, every user is allowed to mark every contact as a "
+"remote_self in the repair contact dialog. Setting this flag on a contact "
+"causes mirroring every posting of that contact in the users stream."
+msgstr "Al habilitar esta opción, cada perfil tiene el permiso de marcar cualquiera de sus contactos como un perfil_remoto. Habilitar la opción perfil_remoto para un contacto genera que todas las publicaciones  de este contacto seran re-publicado  en el muro del perfil."
 
-#: mod/group.php:60
-msgid "Group name changed."
-msgstr "El nombre del grupo ha cambiado."
+#: mod/admin.php:1012
+msgid "Block multiple registrations"
+msgstr "Bloquear registros multiples"
 
-#: mod/group.php:87
-msgid "Save Group"
-msgstr "Guardar grupo"
+#: mod/admin.php:1012
+msgid "Disallow users to register additional accounts for use as pages."
+msgstr "Impedir que los usuarios registren cuentas adicionales para su uso como páginas."
 
-#: mod/group.php:93
-msgid "Create a group of contacts/friends."
-msgstr "Crea un grupo de contactos/amigos."
+#: mod/admin.php:1013
+msgid "OpenID support"
+msgstr "Soporte OpenID"
 
-#: mod/group.php:113
-msgid "Group removed."
-msgstr "Grupo eliminado."
+#: mod/admin.php:1013
+msgid "OpenID support for registration and logins."
+msgstr "Soporte OpenID para registros y accesos."
 
-#: mod/group.php:115
-msgid "Unable to remove group."
-msgstr "No se puede eliminar el grupo."
+#: mod/admin.php:1014
+msgid "Fullname check"
+msgstr "Comprobar Nombre completo"
 
-#: mod/group.php:177
-msgid "Group Editor"
-msgstr "Editor de grupos"
+#: mod/admin.php:1014
+msgid ""
+"Force users to register with a space between firstname and lastname in Full "
+"name, as an antispam measure"
+msgstr "Fuerza a los usuarios a registrarse con un espacio entre su nombre y su apellido en el campo Nombre completo como medida anti-spam"
 
-#: mod/group.php:190
-msgid "Members"
-msgstr "Miembros"
+#: mod/admin.php:1015
+msgid "UTF-8 Regular expressions"
+msgstr "Expresiones regulares UTF-8"
 
-#: mod/group.php:192 mod/contacts.php:692
-msgid "All Contacts"
-msgstr "Todos los contactos"
+#: mod/admin.php:1015
+msgid "Use PHP UTF8 regular expressions"
+msgstr "Usar expresiones regulares de UTF8 en PHP"
 
-#: mod/group.php:193 mod/content.php:130 mod/network.php:496
-msgid "Group is empty"
-msgstr "El grupo está vacío"
+#: mod/admin.php:1016
+msgid "Community Page Style"
+msgstr "Estilo de pagina de comunidad"
 
-#: mod/wallmessage.php:42 mod/wallmessage.php:112
-#, php-format
-msgid "Number of daily wall messages for %s exceeded. Message failed."
-msgstr "Excedido el número máximo de mensajes para %s. El mensaje no se ha enviado."
+#: mod/admin.php:1016
+msgid ""
+"Type of community page to show. 'Global community' shows every public "
+"posting from an open distributed network that arrived on this server."
+msgstr "Tipo de pagina de comunidad a visualizar. 'Comunidad global' muestra todas las publicaciones publicas de la red abierta federada que llega a este servidor."
 
-#: mod/wallmessage.php:56 mod/message.php:71
-msgid "No recipient selected."
-msgstr "Ningún destinatario seleccionado"
+#: mod/admin.php:1017
+msgid "Posts per user on community page"
+msgstr "Publicaciones por usuario en la pagina de comunidad"
 
-#: mod/wallmessage.php:59
-msgid "Unable to check your home location."
-msgstr "Imposible comprobar tu servidor de inicio."
+#: mod/admin.php:1017
+msgid ""
+"The maximum number of posts per user on the community page. (Not valid for "
+"'Global Community')"
+msgstr "El numero máximo de publicaciones por usuario que aparecerán en la pagina de comunidad. (No valido para 'comunidad global')"
 
-#: mod/wallmessage.php:62 mod/message.php:78
-msgid "Message could not be sent."
-msgstr "El mensaje no ha podido ser enviado."
+#: mod/admin.php:1018
+msgid "Enable OStatus support"
+msgstr "Permitir soporte OStatus"
 
-#: mod/wallmessage.php:65 mod/message.php:81
-msgid "Message collection failure."
-msgstr "Fallo en la recolección de mensajes."
+#: mod/admin.php:1018
+msgid ""
+"Provide built-in OStatus (StatusNet, GNU Social etc.) compatibility. All "
+"communications in OStatus are public, so privacy warnings will be "
+"occasionally displayed."
+msgstr "Proporcionar OStatus compatibilidad integrada (StatusNet, GNU Social, Quitter etc.). Todas las comunicaciones en OStatus son publicas así que eventuales advertencias serán ocasionalmente desplegadas."
 
-#: mod/wallmessage.php:68 mod/message.php:84
-msgid "Message sent."
-msgstr "Mensaje enviado."
+#: mod/admin.php:1019
+msgid "OStatus conversation completion interval"
+msgstr "Intervalo de actualización de conversaciones OStatus"
 
-#: mod/wallmessage.php:86 mod/wallmessage.php:95
-msgid "No recipient."
-msgstr "Sin receptor."
+#: mod/admin.php:1019
+msgid ""
+"How often shall the poller check for new entries in OStatus conversations? "
+"This can be a very ressource task."
+msgstr "Cuan seguido el recolector deberá buscar nuevas entradas en OStatus? Esto puede ser un trabajo de mucha carga para los recursos del servidor."
 
-#: mod/wallmessage.php:142 mod/message.php:341
-msgid "Send Private Message"
-msgstr "Enviar mensaje privado"
+#: mod/admin.php:1020
+msgid "Only import OStatus threads from our contacts"
+msgstr "Solo importar OStatus temas de nuestros (?) contactos."
 
-#: mod/wallmessage.php:143
-#, php-format
+#: mod/admin.php:1020
 msgid ""
-"If you wish for %s to respond, please check that the privacy settings on "
-"your site allow private mail from unknown senders."
-msgstr "Si quieres que %s te responda, asegúrate de que la configuración de privacidad permite enviar correo privado a desconocidos."
+"Normally we import every content from our OStatus contacts. With this option"
+" we only store threads that are started by a contact that is known on our "
+"system."
+msgstr "Normalmente importamos todo el contenido de los contactos de OStatus. Con esta opción solamente se guardan temas que fueron iniciados por contactos que son conocidos de la instancia.\n(nota de traducción, no se entiende muy bien la función en base al texto original)"
 
-#: mod/wallmessage.php:144 mod/message.php:342 mod/message.php:536
-msgid "To:"
-msgstr "Para:"
+#: mod/admin.php:1021
+msgid "OStatus support can only be enabled if threading is enabled."
+msgstr "Solo se puede habilitar el soporte OStatus  si threading (comentarios en fila) se encuentra habilitado."
 
-#: mod/wallmessage.php:145 mod/message.php:347 mod/message.php:538
-msgid "Subject:"
-msgstr "Asunto:"
+#: mod/admin.php:1023
+msgid ""
+"Diaspora support can't be enabled because Friendica was installed into a sub"
+" directory."
+msgstr "El soporte para Diaspora* no se puede habilitar porque friendica se instalo en un directorio subalterno (sub directory)."
 
-#: mod/share.php:38
-msgid "link"
-msgstr "enlace"
+#: mod/admin.php:1024
+msgid "Enable Diaspora support"
+msgstr "Habilitar el soporte para Diaspora*"
 
-#: mod/api.php:76 mod/api.php:102
-msgid "Authorize application connection"
-msgstr "Autorizar la conexión de la aplicación"
+#: mod/admin.php:1024
+msgid "Provide built-in Diaspora network compatibility."
+msgstr "Provee una compatibilidad con la red de Diaspora."
 
-#: mod/api.php:77
-msgid "Return to your app and insert this Securty Code:"
-msgstr "Regresa a tu aplicación e introduce este código de seguridad:"
+#: mod/admin.php:1025
+msgid "Only allow Friendica contacts"
+msgstr "Permitir solo contactos de Friendica"
 
-#: mod/api.php:89
-msgid "Please login to continue."
-msgstr "Inicia sesión para continuar."
+#: mod/admin.php:1025
+msgid ""
+"All contacts must use Friendica protocols. All other built-in communication "
+"protocols disabled."
+msgstr "Todos los contactos deben usar protocolos de Friendica. El resto de protocolos serán desactivados."
+
+#: mod/admin.php:1026
+msgid "Verify SSL"
+msgstr "Verificar SSL"
 
-#: mod/api.php:104
+#: mod/admin.php:1026
 msgid ""
-"Do you want to authorize this application to access your posts and contacts,"
-" and/or create new posts for you?"
-msgstr "¿Quieres autorizar a esta aplicación el acceso a tus mensajes y contactos, y/o crear nuevas publicaciones para ti?"
+"If you wish, you can turn on strict certificate checking. This will mean you"
+" cannot connect (at all) to self-signed SSL sites."
+msgstr "Si quieres puedes activar la comprobación estricta de certificados. Esto significa que serás incapaz de conectar con ningún sitio que use certificados SSL autofirmados."
 
-#: mod/api.php:106 mod/profiles.php:648 mod/profiles.php:652
-#: mod/profiles.php:677 mod/register.php:246 mod/settings.php:1163
-#: mod/settings.php:1169 mod/settings.php:1177 mod/settings.php:1181
-#: mod/settings.php:1186 mod/settings.php:1192 mod/settings.php:1198
-#: mod/settings.php:1204 mod/settings.php:1230 mod/settings.php:1231
-#: mod/settings.php:1232 mod/settings.php:1233 mod/settings.php:1234
-#: mod/dfrn_request.php:862 mod/follow.php:110
-msgid "No"
-msgstr "No"
+#: mod/admin.php:1027
+msgid "Proxy user"
+msgstr "Usuario proxy"
 
-#: mod/babel.php:17
-msgid "Source (bbcode) text:"
-msgstr "Texto fuente (bbcode):"
+#: mod/admin.php:1028
+msgid "Proxy URL"
+msgstr "Dirección proxy"
 
-#: mod/babel.php:23
-msgid "Source (Diaspora) text to convert to BBcode:"
-msgstr "Fuente (Diaspora) para pasar a BBcode:"
+#: mod/admin.php:1029
+msgid "Network timeout"
+msgstr "Tiempo de espera de red"
 
-#: mod/babel.php:31
-msgid "Source input: "
-msgstr "Entrada: "
+#: mod/admin.php:1029
+msgid "Value is in seconds. Set to 0 for unlimited (not recommended)."
+msgstr "Valor en segundos. Usar 0 para dejarlo sin límites (no se recomienda)."
 
-#: mod/babel.php:35
-msgid "bb2html (raw HTML): "
-msgstr "bb2html (raw HTML): "
+#: mod/admin.php:1030
+msgid "Maximum Load Average"
+msgstr "Promedio de carga máxima"
 
-#: mod/babel.php:39
-msgid "bb2html: "
-msgstr "bb2html: "
+#: mod/admin.php:1030
+msgid ""
+"Maximum system load before delivery and poll processes are deferred - "
+"default 50."
+msgstr "Carga máxima del sistema antes de que la entrega y los procesos de sondeo sean retrasados - por defecto 50."
 
-#: mod/babel.php:43
-msgid "bb2html2bb: "
-msgstr "bb2html2bb: "
+#: mod/admin.php:1031
+msgid "Maximum Load Average (Frontend)"
+msgstr "Carga máxima promedio (frontend)"
 
-#: mod/babel.php:47
-msgid "bb2md: "
-msgstr "bb2md: "
+#: mod/admin.php:1031
+msgid "Maximum system load before the frontend quits service - default 50."
+msgstr "Carga máxima del sistema antes de que el frontend cancele el servicio - por defecto 50."
 
-#: mod/babel.php:51
-msgid "bb2md2html: "
-msgstr "bb2md2html: "
+#: mod/admin.php:1032
+msgid "Maximum table size for optimization"
+msgstr "Tamaño máximo de las tablas para la optimización."
 
-#: mod/babel.php:55
-msgid "bb2dia2bb: "
-msgstr "bb2dia2bb: "
+#: mod/admin.php:1032
+msgid ""
+"Maximum table size (in MB) for the automatic optimization - default 100 MB. "
+"Enter -1 to disable it."
+msgstr "Tamaño máximo de tablas (en MB) para la optimización automática - por defecto 100MB. Ingrese -1 para deshabilitar."
 
-#: mod/babel.php:59
-msgid "bb2md2html2bb: "
-msgstr "bb2md2html2bb: "
+#: mod/admin.php:1033
+msgid "Minimum level of fragmentation"
+msgstr "Nivel mínimo de fragmentación "
 
-#: mod/babel.php:69
-msgid "Source input (Diaspora format): "
-msgstr "Fuente (formato Diaspora): "
+#: mod/admin.php:1033
+msgid ""
+"Minimum fragmenation level to start the automatic optimization - default "
+"value is 30%."
+msgstr "Nivel mínimo de fragmentación para para comenzar la optimización - valor por defecto es 30%. "
 
-#: mod/babel.php:74
-msgid "diaspora2bb: "
-msgstr "diaspora2bb: "
+#: mod/admin.php:1035
+msgid "Periodical check of global contacts"
+msgstr "Verificación periódica de los contactos globales."
 
-#: mod/ostatus_subscribe.php:14
-msgid "Subscribing to OStatus contacts"
-msgstr "Subscribir a los contactos de OStatus"
+#: mod/admin.php:1035
+msgid ""
+"If enabled, the global contacts are checked periodically for missing or "
+"outdated data and the vitality of the contacts and servers."
+msgstr "Habilitado los contactos globales son verificado periódicamente  por datos faltantes o datos obsoletos como también por la vitalidad de los contactos y servidores."
 
-#: mod/ostatus_subscribe.php:25
-msgid "No contact provided."
-msgstr "Sin suministro de datos de contacto."
+#: mod/admin.php:1036
+msgid "Days between requery"
+msgstr "Días entre búsquedas"
 
-#: mod/ostatus_subscribe.php:30
-msgid "Couldn't fetch information for contact."
-msgstr "No se ha podido conseguir la información del contacto."
+#: mod/admin.php:1036
+msgid "Number of days after which a server is requeried for his contacts."
+msgstr "Cantidad de días hasta que un servidor es consultado por sus contactos."
 
-#: mod/ostatus_subscribe.php:38
-msgid "Couldn't fetch friends for contact."
-msgstr "No se ha podido conseguir datos de amigos para contactar."
+#: mod/admin.php:1037
+msgid "Discover contacts from other servers"
+msgstr "Descubrir contactos de otros servidores"
 
-#: mod/ostatus_subscribe.php:65
-msgid "success"
-msgstr "exito!"
+#: mod/admin.php:1037
+msgid ""
+"Periodically query other servers for contacts. You can choose between "
+"'users': the users on the remote system, 'Global Contacts': active contacts "
+"that are known on the system. The fallback is meant for Redmatrix servers "
+"and older friendica servers, where global contacts weren't available. The "
+"fallback increases the server load, so the recommened setting is 'Users, "
+"Global Contacts'."
+msgstr "Recoger periódicamente información sobre perfiles en otros servidores. Puede elegir entre 'usuarios': perfiles de un sistema remoto, 'contactos globales': contactos activos que son conocidos por el servidor. El fallback es para servidors redmatrix y instalaciones viejas de friendica en las que los contactos no estaban a disposición. El fallback aumenta la carga del servidor, asi que la configuración recomendada es 'usuarios, contactos globales'"
 
-#: mod/ostatus_subscribe.php:67
-msgid "failed"
-msgstr "fallido!"
+#: mod/admin.php:1038
+msgid "Timeframe for fetching global contacts"
+msgstr "Intervalos de tiempo para revisar contactos globales."
 
-#: mod/ostatus_subscribe.php:69 mod/content.php:792 object/Item.php:245
-msgid "ignored"
-msgstr "ignorado"
+#: mod/admin.php:1038
+msgid ""
+"When the discovery is activated, this value defines the timeframe for the "
+"activity of the global contacts that are fetched from other servers."
+msgstr "Cuando la revisacion es activada, este valor define el intervalo de tiempo de la actividad de los contactos globales que son recolectados de los servidores. (?)"
 
-#: mod/dfrn_poll.php:104 mod/dfrn_poll.php:537
-#, php-format
-msgid "%1$s welcomes %2$s"
-msgstr "%1$s te da la bienvenida a %2$s"
+#: mod/admin.php:1039
+msgid "Search the local directory"
+msgstr "Buscar el directorio local"
 
-#: mod/message.php:75
-msgid "Unable to locate contact information."
-msgstr "No se puede encontrar información del contacto."
+#: mod/admin.php:1039
+msgid ""
+"Search the local directory instead of the global directory. When searching "
+"locally, every search will be executed on the global directory in the "
+"background. This improves the search results when the search is repeated."
+msgstr "Buscar en el directorio local en vez del directorio global. Cuando se busca localmente, cada busqueda sera efectuada en el directorio global en el background. Esto mejora los resultados de la busqueda cuando la misma es repetida."
 
-#: mod/message.php:215
-msgid "Do you really want to delete this message?"
-msgstr "¿Estás seguro de que quieres borrar este mensaje?"
+#: mod/admin.php:1041
+msgid "Publish server information"
+msgstr "Publicar información del servidor"
 
-#: mod/message.php:235
-msgid "Message deleted."
-msgstr "Mensaje eliminado."
+#: mod/admin.php:1041
+msgid ""
+"If enabled, general server and usage data will be published. The data "
+"contains the name and version of the server, number of users with public "
+"profiles, number of posts and the activated protocols and connectors. See <a"
+" href='http://the-federation.info/'>the-federation.info</a> for details."
+msgstr "Si habilitado, datos generales del servidor y estadisticas de uso serán publicados. Los datos contienen el nombre y la versión del servidor, numero de usuarios con perfiles públicos, cantidad de temas publicados y los protocolos y conectores activados. Vea <a href='http://the-federation.info/'>the-federation.info</a> por detalles."
 
-#: mod/message.php:266
-msgid "Conversation removed."
-msgstr "Conversación eliminada."
+#: mod/admin.php:1043
+msgid "Use MySQL full text engine"
+msgstr "Usar motor MySQL de texto completo"
 
-#: mod/message.php:383
-msgid "No messages."
-msgstr "No hay mensajes."
+#: mod/admin.php:1043
+msgid ""
+"Activates the full text engine. Speeds up search - but can only search for "
+"four and more characters."
+msgstr "Activa el motor de texto completo. Agiliza las búsquedas, pero solo busca cuatro o más caracteres."
 
-#: mod/message.php:426
-msgid "Message not available."
-msgstr "Mensaje no disponibile."
+#: mod/admin.php:1044
+msgid "Suppress Tags"
+msgstr "Suprimir tags"
 
-#: mod/message.php:503
-msgid "Delete message"
-msgstr "Borrar mensaje"
+#: mod/admin.php:1044
+msgid "Suppress showing a list of hashtags at the end of the posting."
+msgstr "Suprimir la lista de tags al final de una publicación."
 
-#: mod/message.php:529 mod/message.php:609
-msgid "Delete conversation"
-msgstr "Eliminar conversación"
+#: mod/admin.php:1045
+msgid "Path to item cache"
+msgstr "Ruta a la caché del objeto"
 
-#: mod/message.php:531
-msgid ""
-"No secure communications available. You <strong>may</strong> be able to "
-"respond from the sender's profile page."
-msgstr "No hay comunicaciones seguras disponibles. <strong>Podrías</strong> responder desde la página de perfil del remitente. "
+#: mod/admin.php:1045
+msgid "The item caches buffers generated bbcode and external images."
+msgstr "El buffer de cache de items generado para bbcodes e imágenes externas. "
 
-#: mod/message.php:535
-msgid "Send Reply"
-msgstr "Enviar respuesta"
+#: mod/admin.php:1046
+msgid "Cache duration in seconds"
+msgstr "Duración de la caché en segundos"
 
-#: mod/message.php:579
-#, php-format
-msgid "Unknown sender - %s"
-msgstr "Remitente desconocido - %s"
+#: mod/admin.php:1046
+msgid ""
+"How long should the cache files be hold? Default value is 86400 seconds (One"
+" day). To disable the item cache, set the value to -1."
+msgstr "¿Por cuanto tiempo deberían los archives ser almacenados en el cache? Valor por defecto 86400 segundos (un día). Para deshabilita el item cache, ajuste el valor a -1."
 
-#: mod/message.php:581
-#, php-format
-msgid "You and %s"
-msgstr "Tú y %s"
+#: mod/admin.php:1047
+msgid "Maximum numbers of comments per post"
+msgstr "Numero máximo de respuestas por tema"
 
-#: mod/message.php:583
-#, php-format
-msgid "%s and You"
-msgstr "%s y Tú"
+#: mod/admin.php:1047
+msgid "How much comments should be shown for each post? Default value is 100."
+msgstr "¿Cuantos comentarios deberían ser mostrados por tema? Valor por defecto es 100."
 
-#: mod/message.php:612
-msgid "D, d M Y - g:i A"
-msgstr "D, d M Y - g:i A"
+#: mod/admin.php:1048
+msgid "Temp path"
+msgstr "Ruta a los temporales"
 
-#: mod/message.php:615
-#, php-format
-msgid "%d message"
-msgid_plural "%d messages"
-msgstr[0] "%d mensaje"
-msgstr[1] "%d mensajes"
+#: mod/admin.php:1048
+msgid ""
+"If you have a restricted system where the webserver can't access the system "
+"temp path, enter another path here."
+msgstr "Si tiene un sistema restringido en donde el servidor web no puede acceder la dirección del sistema temp, ingrese una dirección alternativa aquí. "
 
-#: mod/manage.php:139
-msgid "Manage Identities and/or Pages"
-msgstr "Administrar identidades y/o páginas"
+#: mod/admin.php:1049
+msgid "Base path to installation"
+msgstr "Ruta base para la instalación"
 
-#: mod/manage.php:140
+#: mod/admin.php:1049
 msgid ""
-"Toggle between different identities or community/group pages which share "
-"your account details or which you have been granted \"manage\" permissions"
-msgstr "Cambia entre diferentes identidades o páginas de Comunidad/Grupos que comparten los detalles de tu cuenta o sobre los que tienes permisos para administrar"
+"If the system cannot detect the correct path to your installation, enter the"
+" correct path here. This setting should only be set if you are using a "
+"restricted system and symbolic links to your webroot."
+msgstr "Si el sistema no puede detectar el acceso correcto a la instalación, ingrese la dirección correcta aquí. Esta configuración solo debería utilizarse si si usa un sistema restringido y enlaces simbolicos a su webroot."
 
-#: mod/manage.php:141
-msgid "Select an identity to manage: "
-msgstr "Selecciona una identidad a gestionar:"
+#: mod/admin.php:1050
+msgid "Disable picture proxy"
+msgstr "Deshabilitar proxy de imagen"
 
-#: mod/crepair.php:87
-msgid "Contact settings applied."
-msgstr "Contacto configurado con éxito."
+#: mod/admin.php:1050
+msgid ""
+"The picture proxy increases performance and privacy. It shouldn't be used on"
+" systems with very low bandwith."
+msgstr "El proxy de imagen mejora el performance y privacidad. No debería ser usado en sistemas con poco ancho de banda."
 
-#: mod/crepair.php:89
-msgid "Contact update failed."
-msgstr "Error al actualizar el Contacto."
+#: mod/admin.php:1051
+msgid "Only search in tags"
+msgstr "Solo buscar en tags"
 
-#: mod/crepair.php:114 mod/fsuggest.php:20 mod/fsuggest.php:92
-#: mod/dfrn_confirm.php:126
-msgid "Contact not found."
-msgstr "Contacto no encontrado."
+#: mod/admin.php:1051
+msgid "On large systems the text search can slow down the system extremely."
+msgstr "En sistemas grandes, la búsqueda de texto puede enlentecer el sistema gravemente."
 
-#: mod/crepair.php:120
-msgid ""
-"<strong>WARNING: This is highly advanced</strong> and if you enter incorrect"
-" information your communications with this contact may stop working."
-msgstr "<strong>ADVERTENCIA: Esto es muy avanzado</strong> y si se introduce información incorrecta tu conexión con este contacto puede dejar de funcionar."
+#: mod/admin.php:1053
+msgid "New base url"
+msgstr "Nueva URLbase"
 
-#: mod/crepair.php:121
+#: mod/admin.php:1053
 msgid ""
-"Please use your browser 'Back' button <strong>now</strong> if you are "
-"uncertain what to do on this page."
-msgstr "Por favor usa el botón 'Atás' de tu navegador <strong>ahora</strong> si no tienes claro qué hacer en esta página."
+"Change base url for this server. Sends relocate message to all DFRN contacts"
+" of all users."
+msgstr "Cambiar base URL para este servidor. Envía mensajes de relocalisación a todos los contactos DFRN."
 
-#: mod/crepair.php:134 mod/crepair.php:136
-msgid "No mirroring"
-msgstr "No espejar"
+#: mod/admin.php:1055
+msgid "RINO Encryption"
+msgstr "Encryptado RINO"
 
-#: mod/crepair.php:134
-msgid "Mirror as forwarded posting"
-msgstr "Espejar como reenvio"
+#: mod/admin.php:1055
+msgid "Encryption layer between nodes."
+msgstr "Capa de encryptación entre nodos."
 
-#: mod/crepair.php:134 mod/crepair.php:136
-msgid "Mirror as my own posting"
-msgstr "Espejar como publicación propia"
+#: mod/admin.php:1056
+msgid "Embedly API key"
+msgstr "Embedly llave de API (API key) "
 
-#: mod/crepair.php:150
-msgid "Return to contact editor"
-msgstr "Volver al editor de contactos"
+#: mod/admin.php:1056
+msgid ""
+"<a href='http://embed.ly'>Embedly</a> is used to fetch additional data for "
+"web pages. This is an optional parameter."
+msgstr "<a href='http://embed.ly'>Embedly</a> es usado para recolectar datos adicionales para paginas web. Esto es un parámetro opcional."
 
-#: mod/crepair.php:152
-msgid "Refetch contact data"
-msgstr "Volver a solicitar datos del contacto."
+#: mod/admin.php:1058
+msgid "Maximum number of parallel workers"
+msgstr "Numero máximo de trabajos paralelos de fondo."
 
-#: mod/crepair.php:156
-msgid "Remote Self"
-msgstr "Perfil remoto"
+#: mod/admin.php:1058
+msgid ""
+"On shared hosters set this to 2. On larger systems, values of 10 are great. "
+"Default value is 4."
+msgstr "Ajustar a 2 en un servidor compartido (shared hosting).\nEn sistemas grandes valores como 10 son excelentes.\nValor por defecto es 4."
 
-#: mod/crepair.php:159
-msgid "Mirror postings from this contact"
-msgstr "Espejar publicaciones de este contacto"
+#: mod/admin.php:1059
+msgid "Don't use 'proc_open' with the worker"
+msgstr "No use 'proc_open' junto al \"trabajador\"!"
 
-#: mod/crepair.php:161
+#: mod/admin.php:1059
 msgid ""
-"Mark this contact as remote_self, this will cause friendica to repost new "
-"entries from this contact."
-msgstr "Marcar este contacto como perfil_remoto, esto generara que friendica reenvía nuevas publicaciones desde esta cuenta."
+"Enable this if your system doesn't allow the use of 'proc_open'. This can "
+"happen on shared hosters. If this is enabled you should increase the "
+"frequency of poller calls in your crontab."
+msgstr "Habilite esta función si el sistema no permite el uso de 'proc_open'. Esto suelo suceder en servidores compartidos (shared hosting). Si esta función se habilita se debería incrementar la frecuencia de llamadas del poller (poller calls) en la pestaña de trabajos cron. (¡en el hosting?)"
 
-#: mod/crepair.php:165 mod/settings.php:680 mod/settings.php:706
-#: mod/admin.php:1396 mod/admin.php:1409 mod/admin.php:1422 mod/admin.php:1438
-msgid "Name"
-msgstr "Nombre"
+#: mod/admin.php:1060
+msgid "Enable fastlane"
+msgstr "Habilitar ascenso rápido"
 
-#: mod/crepair.php:166
-msgid "Account Nickname"
-msgstr "Apodo de la cuenta"
+#: mod/admin.php:1060
+msgid ""
+"When enabed, the fastlane mechanism starts an additional worker if processes"
+" with higher priority are blocked by processes of lower priority."
+msgstr "Cuando está habilitado, el mecanismo ascenso rápido inicia un trabajador adicional si los procesos de mayor prioridad son bloqueados por prcesos de menor prioridad."
 
-#: mod/crepair.php:167
-msgid "@Tagname - overrides Name/Nickname"
-msgstr "@Etiqueta - Sobrescribe el Nombre/Apodo"
+#: mod/admin.php:1061
+msgid "Enable frontend worker"
+msgstr "Habilitar trabajador de interfaz"
 
-#: mod/crepair.php:168
-msgid "Account URL"
-msgstr "Dirección de la cuenta"
+#: mod/admin.php:1061
+msgid ""
+"When enabled the Worker process is triggered when backend access is "
+"performed (e.g. messages being delivered). On smaller sites you might want "
+"to call yourdomain.tld/worker on a regular basis via an external cron job. "
+"You should only enable this option if you cannot utilize cron/scheduled jobs"
+" on your server. The worker background process needs to be activated for "
+"this."
+msgstr "Cuando está habilitado, el proceso de Trabajador se activa cuando se ejecuta el acceso de respaldo (ej. mensajes siendo entregados). En páginas más pequeñas usted puede querer llamar a yourdomain.tld/worker en una base regular mediante un trabajo cron externo. Sólo debería habilitar esta opción si no puede utilizar trabajos cron/scheduled en su servidor. El proceso de trabajador en segundo plano necesita ser activado para eso."
 
-#: mod/crepair.php:169
-msgid "Friend Request URL"
-msgstr "Dirección de la solicitud de amistad"
+#: mod/admin.php:1091
+msgid "Update has been marked successful"
+msgstr "La actualización se ha completado con éxito"
 
-#: mod/crepair.php:170
-msgid "Friend Confirm URL"
-msgstr "Dirección de confirmación de tu amigo "
+#: mod/admin.php:1099
+#, php-format
+msgid "Database structure update %s was successfully applied."
+msgstr "Actualización de base de datos %s fue aplicada con éxito."
 
-#: mod/crepair.php:171
-msgid "Notification Endpoint URL"
-msgstr "Dirección URL de la notificación"
+#: mod/admin.php:1102
+#, php-format
+msgid "Executing of database structure update %s failed with error: %s"
+msgstr "El paso de actualización de la estructura de la base de datos %s fallo con el mensaje de error: %s"
 
-#: mod/crepair.php:172
-msgid "Poll/Feed URL"
-msgstr "Dirección del Sondeo/Fuentes"
+#: mod/admin.php:1116
+#, php-format
+msgid "Executing %s failed with error: %s"
+msgstr "Paso %s fallo con el error: %s"
 
-#: mod/crepair.php:173
-msgid "New photo from this URL"
-msgstr "Nueva foto de esta dirección"
+#: mod/admin.php:1119
+#, php-format
+msgid "Update %s was successfully applied."
+msgstr "Actualización %s aplicada con éxito."
 
-#: mod/content.php:119 mod/network.php:469
-msgid "No such group"
-msgstr "Ningún grupo"
+#: mod/admin.php:1122
+#, php-format
+msgid "Update %s did not return a status. Unknown if it succeeded."
+msgstr "La actualización %s no ha informado, se desconoce el estado."
 
-#: mod/content.php:135 mod/network.php:500
+#: mod/admin.php:1125
 #, php-format
-msgid "Group: %s"
-msgstr "Grupo: %s"
+msgid "There was no additional update function %s that needed to be called."
+msgstr "No había función adicional de actualización %s que necesitaba ser requerida."
 
-#: mod/content.php:325 object/Item.php:95
-msgid "This entry was edited"
-msgstr "Esta entrada fue editada"
+#: mod/admin.php:1145
+msgid "No failed updates."
+msgstr "Actualizaciones sin fallos."
 
-#: mod/content.php:621 object/Item.php:429
-#, php-format
-msgid "%d comment"
-msgid_plural "%d comments"
-msgstr[0] "%d comentario"
-msgstr[1] "%d comentarios"
+#: mod/admin.php:1146
+msgid "Check database structure"
+msgstr "Revisar estructura de la base de datos"
 
-#: mod/content.php:638 mod/photos.php:1379 object/Item.php:117
-msgid "Private Message"
-msgstr "Mensaje privado"
+#: mod/admin.php:1151
+msgid "Failed Updates"
+msgstr "Actualizaciones fallidas"
 
-#: mod/content.php:702 mod/photos.php:1567 object/Item.php:263
-msgid "I like this (toggle)"
-msgstr "Me gusta esto (cambiar)"
+#: mod/admin.php:1152
+msgid ""
+"This does not include updates prior to 1139, which did not return a status."
+msgstr "No se incluyen las anteriores a la 1139, que no indicaban su estado."
 
-#: mod/content.php:702 object/Item.php:263
-msgid "like"
-msgstr "me gusta"
+#: mod/admin.php:1153
+msgid "Mark success (if update was manually applied)"
+msgstr "Marcar como correcta (si actualizaste manualmente)"
 
-#: mod/content.php:703 mod/photos.php:1568 object/Item.php:264
-msgid "I don't like this (toggle)"
-msgstr "No me gusta esto (cambiar)"
+#: mod/admin.php:1154
+msgid "Attempt to execute this update step automatically"
+msgstr "Intentando ejecutar este paso automáticamente"
 
-#: mod/content.php:703 object/Item.php:264
-msgid "dislike"
-msgstr "no me gusta"
+#: mod/admin.php:1188
+#, php-format
+msgid ""
+"\n"
+"\t\t\tDear %1$s,\n"
+"\t\t\t\tthe administrator of %2$s has set up an account for you."
+msgstr "\n\t\t\tEstimado %1$s,\n\t\t\t\tel administrador de %2$s ha creado una cuenta para usted."
 
-#: mod/content.php:705 object/Item.php:266
-msgid "Share this"
-msgstr "Compartir esto"
+#: mod/admin.php:1191
+#, php-format
+msgid ""
+"\n"
+"\t\t\tThe login details are as follows:\n"
+"\n"
+"\t\t\tSite Location:\t%1$s\n"
+"\t\t\tLogin Name:\t\t%2$s\n"
+"\t\t\tPassword:\t\t%3$s\n"
+"\n"
+"\t\t\tYou may change your password from your account \"Settings\" page after logging\n"
+"\t\t\tin.\n"
+"\n"
+"\t\t\tPlease take a few moments to review the other account settings on that page.\n"
+"\n"
+"\t\t\tYou may also wish to add some basic information to your default profile\n"
+"\t\t\t(on the \"Profiles\" page) so that other people can easily find you.\n"
+"\n"
+"\t\t\tWe recommend setting your full name, adding a profile photo,\n"
+"\t\t\tadding some profile \"keywords\" (very useful in making new friends) - and\n"
+"\t\t\tperhaps what country you live in; if you do not wish to be more specific\n"
+"\t\t\tthan that.\n"
+"\n"
+"\t\t\tWe fully respect your right to privacy, and none of these items are necessary.\n"
+"\t\t\tIf you are new and do not know anybody here, they may help\n"
+"\t\t\tyou to make some new and interesting friends.\n"
+"\n"
+"\t\t\tThank you and welcome to %4$s."
+msgstr "\n\t\t\tLos detalles de acceso son las siguientes:\n\n\t\t\tDirección del sitio:\t%1$s\n\t\t\tNombre de la cuenta:\t\t%2$s\n\t\t\tContraseña:\t\t%3$s\n\n\t\t\tPodrá cambiar la contraseña desde la pagina de configuración de su cuenta después de acceder a la misma\n\t\t\ten.\n\n\t\t\tPor favor tome unos minutos para revisar las opciones demás de la cuenta en dicha pagina de configuración.\n\n\t\t\tTambién podrá agregar informaciones adicionales a su pagina de perfil predeterminado. \n\t\t\t(en la pagina \"Perfiles\") para que otras personas pueden encontrarlo fácilmente.\n\n\t\t\tRecomendamos que elija un nombre apropiado, agregando una imagen de perfil,\n\t\t\tagregando algunas palabras claves de la cuenta (muy útil para hacer nuevos amigos) - y \n\t\t\tquizás el país en donde vive; si no quiere ser mas especifico\n\t\t\tque eso.\n\n\t\t\tRespetamos absolutamente su derecho a la privacidad y ninguno de estos detalles es necesario.\n\t\t\tSi eres nuevo aquí y no conoces a nadie, estos detalles pueden ayudarte\n\t\t\tpara hacer nuevas e interesantes amistades.\n\n\t\t\tGracias y bienvenido a  %4$s."
 
-#: mod/content.php:705 object/Item.php:266
-msgid "share"
-msgstr "compartir"
+#: mod/admin.php:1235
+#, php-format
+msgid "%s user blocked/unblocked"
+msgid_plural "%s users blocked/unblocked"
+msgstr[0] "%s usuario bloqueado/desbloqueado"
+msgstr[1] "%s usuarios bloqueados/desbloqueados"
 
-#: mod/content.php:725 mod/photos.php:1587 mod/photos.php:1635
-#: mod/photos.php:1721 object/Item.php:717
-msgid "This is you"
-msgstr "Este eres tú"
+#: mod/admin.php:1242
+#, php-format
+msgid "%s user deleted"
+msgid_plural "%s users deleted"
+msgstr[0] "%s usuario eliminado"
+msgstr[1] "%s usuarios eliminados"
 
-#: mod/content.php:727 mod/content.php:945 mod/photos.php:1589
-#: mod/photos.php:1637 mod/photos.php:1723 object/Item.php:403
-#: object/Item.php:719 boot.php:971
-msgid "Comment"
-msgstr "Comentar"
+#: mod/admin.php:1289
+#, php-format
+msgid "User '%s' deleted"
+msgstr "Usuario '%s' eliminado"
 
-#: mod/content.php:729 object/Item.php:721
-msgid "Bold"
-msgstr "Negrita"
+#: mod/admin.php:1297
+#, php-format
+msgid "User '%s' unblocked"
+msgstr "Usuario '%s' desbloqueado"
 
-#: mod/content.php:730 object/Item.php:722
-msgid "Italic"
-msgstr "Cursiva"
+#: mod/admin.php:1297
+#, php-format
+msgid "User '%s' blocked"
+msgstr "Usuario '%s' bloqueado'"
 
-#: mod/content.php:731 object/Item.php:723
-msgid "Underline"
-msgstr "Subrayado"
+#: mod/admin.php:1405 mod/admin.php:1418 mod/admin.php:1431 mod/admin.php:1447
+#: mod/crepair.php:167 mod/settings.php:683 mod/settings.php:709
+msgid "Name"
+msgstr "Nombre"
 
-#: mod/content.php:732 object/Item.php:724
-msgid "Quote"
-msgstr "Cita"
+#: mod/admin.php:1405 mod/admin.php:1431
+msgid "Register date"
+msgstr "Fecha de registro"
 
-#: mod/content.php:733 object/Item.php:725
-msgid "Code"
-msgstr "Código"
+#: mod/admin.php:1405 mod/admin.php:1431
+msgid "Last login"
+msgstr "Último acceso"
 
-#: mod/content.php:734 object/Item.php:726
-msgid "Image"
-msgstr "Imagen"
+#: mod/admin.php:1405 mod/admin.php:1431
+msgid "Last item"
+msgstr "Último elemento"
 
-#: mod/content.php:735 object/Item.php:727
-msgid "Link"
-msgstr "Enlace"
+#: mod/admin.php:1405 mod/settings.php:43
+msgid "Account"
+msgstr "Cuenta"
 
-#: mod/content.php:736 object/Item.php:728
-msgid "Video"
-msgstr "Vídeo"
+#: mod/admin.php:1414
+msgid "Add User"
+msgstr "Agregar usuario"
+
+#: mod/admin.php:1415
+msgid "select all"
+msgstr "seleccionar todo"
+
+#: mod/admin.php:1416
+msgid "User registrations waiting for confirm"
+msgstr "Registro de usuarios esperando confirmación"
 
-#: mod/content.php:746 mod/settings.php:740 object/Item.php:122
-#: object/Item.php:124
-msgid "Edit"
-msgstr "Editar"
+#: mod/admin.php:1417
+msgid "User waiting for permanent deletion"
+msgstr "Usuario esperando anulación permanente."
 
-#: mod/content.php:771 object/Item.php:227
-msgid "add star"
-msgstr "Añadir estrella"
+#: mod/admin.php:1418
+msgid "Request date"
+msgstr "Solicitud de fecha"
 
-#: mod/content.php:772 object/Item.php:228
-msgid "remove star"
-msgstr "Quitar estrella"
+#: mod/admin.php:1419
+msgid "No registrations."
+msgstr "Sin registros."
 
-#: mod/content.php:773 object/Item.php:229
-msgid "toggle star status"
-msgstr "Añadir a destacados"
+#: mod/admin.php:1420
+msgid "Note from the user"
+msgstr "Nota para el usuario"
 
-#: mod/content.php:776 object/Item.php:232
-msgid "starred"
-msgstr "marcados con estrellas"
+#: mod/admin.php:1421 mod/notifications.php:176 mod/notifications.php:255
+msgid "Approve"
+msgstr "Aprobar"
 
-#: mod/content.php:777 mod/content.php:798 object/Item.php:252
-msgid "add tag"
-msgstr "añadir etiqueta"
+#: mod/admin.php:1422
+msgid "Deny"
+msgstr "Denegado"
 
-#: mod/content.php:787 object/Item.php:240
-msgid "ignore thread"
-msgstr "ignorar publicación"
+#: mod/admin.php:1424 mod/contacts.php:613 mod/contacts.php:813
+#: mod/contacts.php:991
+msgid "Block"
+msgstr "Bloquear"
 
-#: mod/content.php:788 object/Item.php:241
-msgid "unignore thread"
-msgstr "revertir ignorar publicacion"
+#: mod/admin.php:1425 mod/contacts.php:613 mod/contacts.php:813
+#: mod/contacts.php:991
+msgid "Unblock"
+msgstr "Desbloquear"
 
-#: mod/content.php:789 object/Item.php:242
-msgid "toggle ignore status"
-msgstr "cambiar estatus de observación"
+#: mod/admin.php:1426
+msgid "Site admin"
+msgstr "Administrador de la web"
 
-#: mod/content.php:803 object/Item.php:137
-msgid "save to folder"
-msgstr "grabado en directorio"
+#: mod/admin.php:1427
+msgid "Account expired"
+msgstr "Cuenta caducada"
 
-#: mod/content.php:848 object/Item.php:201
-msgid "I will attend"
-msgstr "Voy a estar presente"
+#: mod/admin.php:1430
+msgid "New User"
+msgstr "Nuevo usuario"
 
-#: mod/content.php:848 object/Item.php:201
-msgid "I will not attend"
-msgstr "No voy a estar presente"
+#: mod/admin.php:1431
+msgid "Deleted since"
+msgstr "Borrado desde"
 
-#: mod/content.php:848 object/Item.php:201
-msgid "I might attend"
-msgstr "Puede que voy a estar presente"
+#: mod/admin.php:1436
+msgid ""
+"Selected users will be deleted!\\n\\nEverything these users had posted on "
+"this site will be permanently deleted!\\n\\nAre you sure?"
+msgstr "¡Los usuarios seleccionados serán eliminados!\\n\\n¡Todo lo que hayan publicado en este sitio se borrará para siempre!\\n\\n¿Estás seguro?"
 
-#: mod/content.php:912 object/Item.php:369
-msgid "to"
-msgstr "a"
+#: mod/admin.php:1437
+msgid ""
+"The user {0} will be deleted!\\n\\nEverything this user has posted on this "
+"site will be permanently deleted!\\n\\nAre you sure?"
+msgstr "¡El usuario {0} será eliminado!\\n\\n¡Todo lo que haya publicado en este sitio se borrará para siempre!\\n\\n¿Estás seguro?"
 
-#: mod/content.php:913 object/Item.php:371
-msgid "Wall-to-Wall"
-msgstr "Muro-A-Muro"
+#: mod/admin.php:1447
+msgid "Name of the new user."
+msgstr "Nombre del nuevo usuario"
 
-#: mod/content.php:914 object/Item.php:372
-msgid "via Wall-To-Wall:"
-msgstr "via Muro-A-Muro:"
+#: mod/admin.php:1448
+msgid "Nickname"
+msgstr "Apodo"
 
-#: mod/fsuggest.php:63
-msgid "Friend suggestion sent."
-msgstr "Solicitud de amistad enviada."
+#: mod/admin.php:1448
+msgid "Nickname of the new user."
+msgstr "Apodo del nuevo perfil."
 
-#: mod/fsuggest.php:97
-msgid "Suggest Friends"
-msgstr "Sugerencias de amistad"
+#: mod/admin.php:1449
+msgid "Email address of the new user."
+msgstr "Dirección de correo del nuevo perfil."
 
-#: mod/fsuggest.php:99
+#: mod/admin.php:1492
 #, php-format
-msgid "Suggest a friend for %s"
-msgstr "Recomienda un amigo a %s"
-
-#: mod/mood.php:133
-msgid "Mood"
-msgstr "Ánimo"
+msgid "Plugin %s disabled."
+msgstr "Módulo %s deshabilitado."
 
-#: mod/mood.php:134
-msgid "Set your current mood and tell your friends"
-msgstr "Coloca tu ánimo actual y cuéntaselo a tus amigos"
+#: mod/admin.php:1496
+#, php-format
+msgid "Plugin %s enabled."
+msgstr "Módulo %s habilitado."
 
-#: mod/poke.php:192
-msgid "Poke/Prod"
-msgstr "Toque/Empujón"
+#: mod/admin.php:1507 mod/admin.php:1759
+msgid "Disable"
+msgstr "Desactivado"
 
-#: mod/poke.php:193
-msgid "poke, prod or do other things to somebody"
-msgstr "da un toque, empujón o similar a alguien"
+#: mod/admin.php:1509 mod/admin.php:1761
+msgid "Enable"
+msgstr "Activado"
 
-#: mod/poke.php:194
-msgid "Recipient"
-msgstr "Receptor"
+#: mod/admin.php:1532 mod/admin.php:1808
+msgid "Toggle"
+msgstr "Activar"
 
-#: mod/poke.php:195
-msgid "Choose what you wish to do to recipient"
-msgstr "Elige qué desea hacer con el receptor"
+#: mod/admin.php:1540 mod/admin.php:1817
+msgid "Author: "
+msgstr "Autor:"
 
-#: mod/poke.php:198
-msgid "Make this post private"
-msgstr "Hacer esta publicación privada"
+#: mod/admin.php:1541 mod/admin.php:1818
+msgid "Maintainer: "
+msgstr "Mantenedor: "
 
-#: mod/profile_photo.php:44
-msgid "Image uploaded but image cropping failed."
-msgstr "Imagen recibida, pero ha fallado al recortarla."
+#: mod/admin.php:1596
+msgid "Reload active plugins"
+msgstr "Recargar plugins activos"
 
-#: mod/profile_photo.php:77 mod/profile_photo.php:84 mod/profile_photo.php:91
-#: mod/profile_photo.php:314
+#: mod/admin.php:1601
 #, php-format
-msgid "Image size reduction [%s] failed."
-msgstr "Ha fallado la reducción de las dimensiones de la imagen [%s]."
-
-#: mod/profile_photo.php:124
 msgid ""
-"Shift-reload the page or clear browser cache if the new photo does not "
-"display immediately."
-msgstr "Recarga la página o limpia la caché del navegador si la foto nueva no aparece inmediatamente."
+"There are currently no plugins available on your node. You can find the "
+"official plugin repository at %1$s and might find other interesting plugins "
+"in the open plugin registry at %2$s"
+msgstr "No ay plugins habilitados en este nodo. Encontrara los repositorios oficiales de plugins en %1$s y posiblemente encontrara mas plugins interesantes en el registro abierto de plugins aquí %2$s ."
 
-#: mod/profile_photo.php:134
-msgid "Unable to process image"
-msgstr "Imposible procesar la imagen"
+#: mod/admin.php:1720
+msgid "No themes found."
+msgstr "No se encontraron temas."
+
+#: mod/admin.php:1799
+msgid "Screenshot"
+msgstr "Captura de pantalla"
 
-#: mod/profile_photo.php:150 mod/photos.php:786 mod/wall_upload.php:151
+#: mod/admin.php:1859
+msgid "Reload active themes"
+msgstr "Recargar interfaces de usuario activos"
+
+#: mod/admin.php:1864
 #, php-format
-msgid "Image exceeds size limit of %s"
-msgstr "La imagen excede el limite de %s"
+msgid "No themes found on the system. They should be paced in %1$s"
+msgstr "No se encuentran interfaces en el sistema. Deberían estar localizados (paced) en  %1$s"
 
-#: mod/profile_photo.php:159 mod/photos.php:826 mod/wall_upload.php:188
-msgid "Unable to process image."
-msgstr "Imposible procesar la imagen."
+#: mod/admin.php:1865
+msgid "[Experimental]"
+msgstr "[Experimental]"
 
-#: mod/profile_photo.php:248
-msgid "Upload File:"
-msgstr "Subir archivo:"
+#: mod/admin.php:1866
+msgid "[Unsupported]"
+msgstr "[Sin soporte]"
 
-#: mod/profile_photo.php:249
-msgid "Select a profile:"
-msgstr "Elige un perfil:"
+#: mod/admin.php:1890
+msgid "Log settings updated."
+msgstr "Configuración de registro actualizada."
 
-#: mod/profile_photo.php:251
-msgid "Upload"
-msgstr "Subir"
+#: mod/admin.php:1922
+msgid "PHP log currently enabled."
+msgstr "Registro PHP actualmente disponible."
 
-#: mod/profile_photo.php:254
-msgid "or"
-msgstr "o"
+#: mod/admin.php:1924
+msgid "PHP log currently disabled."
+msgstr "Registro PHP actualmente deshabilitado."
 
-#: mod/profile_photo.php:254
-msgid "skip this step"
-msgstr "saltar este paso"
+#: mod/admin.php:1933
+msgid "Clear"
+msgstr "Limpiar"
 
-#: mod/profile_photo.php:254
-msgid "select a photo from your photo albums"
-msgstr "elige una foto de tus álbumes"
+#: mod/admin.php:1938
+msgid "Enable Debugging"
+msgstr "Habilitar debugging"
 
-#: mod/profile_photo.php:268
-msgid "Crop Image"
-msgstr "Recortar imagen"
+#: mod/admin.php:1939
+msgid "Log file"
+msgstr "Archivo de registro"
 
-#: mod/profile_photo.php:269
-msgid "Please adjust the image cropping for optimum viewing."
-msgstr "Por favor, ajusta el recorte de la imagen para optimizarla."
+#: mod/admin.php:1939
+msgid ""
+"Must be writable by web server. Relative to your Friendica top-level "
+"directory."
+msgstr "Debes tener permiso de escritura en el servidor. Relacionado con tu directorio de inicio de Friendica."
 
-#: mod/profile_photo.php:271
-msgid "Done Editing"
-msgstr "Editado"
+#: mod/admin.php:1940
+msgid "Log level"
+msgstr "Nivel de registro"
 
-#: mod/profile_photo.php:305
-msgid "Image uploaded successfully."
-msgstr "Imagen subida con éxito."
+#: mod/admin.php:1943
+msgid "PHP logging"
+msgstr "PHP logging"
 
-#: mod/profile_photo.php:307 mod/photos.php:853 mod/wall_upload.php:221
-msgid "Image upload failed."
-msgstr "Error al subir la imagen."
+#: mod/admin.php:1944
+msgid ""
+"To enable logging of PHP errors and warnings you can add the following to "
+"the .htconfig.php file of your installation. The filename set in the "
+"'error_log' line is relative to the friendica top-level directory and must "
+"be writeable by the web server. The option '1' for 'log_errors' and "
+"'display_errors' is to enable these options, set to '0' to disable them."
+msgstr "Para habilitar la documentación de los errores PHP y las advertencias se puede agregar lo siguiente al archivo .htconfig.php de la instalación (ftp). La dirección definido en el 'error_log' es relativo al directorio friendica principal (top-level directory) y debe de ser habilitado para la escritura por el servidor web. La opción '1' para 'log_errors' y 'display_errors' es para habilitar estas opciones, '0' para deshabilitarlo."
 
-#: mod/regmod.php:55
-msgid "Account approved."
-msgstr "Cuenta aprobada."
+#: mod/admin.php:2074 mod/admin.php:2075 mod/settings.php:782
+msgid "Off"
+msgstr "Apagado"
+
+#: mod/admin.php:2074 mod/admin.php:2075 mod/settings.php:782
+msgid "On"
+msgstr "Encendido"
 
-#: mod/regmod.php:92
+#: mod/admin.php:2075
 #, php-format
-msgid "Registration revoked for %s"
-msgstr "Registro anulado para %s"
+msgid "Lock feature %s"
+msgstr "Trancar opción %s "
 
-#: mod/regmod.php:104
-msgid "Please login."
-msgstr "Por favor accede."
+#: mod/admin.php:2083
+msgid "Manage Additional Features"
+msgstr "Administrar opciones adicionales"
 
-#: mod/notifications.php:35
-msgid "Invalid request identifier."
-msgstr "Solicitud de identificación no válida."
+#: mod/allfriends.php:46
+msgid "No friends to display."
+msgstr "No hay amigos para mostrar."
 
-#: mod/notifications.php:44 mod/notifications.php:180
-#: mod/notifications.php:252
-msgid "Discard"
-msgstr "Descartar"
+#: mod/api.php:76 mod/api.php:102
+msgid "Authorize application connection"
+msgstr "Autorizar la conexión de la aplicación"
 
-#: mod/notifications.php:60 mod/notifications.php:179
-#: mod/notifications.php:251 mod/contacts.php:606 mod/contacts.php:806
-#: mod/contacts.php:991
-msgid "Ignore"
-msgstr "Ignorar"
+#: mod/api.php:77
+msgid "Return to your app and insert this Securty Code:"
+msgstr "Regresa a tu aplicación e introduce este código de seguridad:"
 
-#: mod/notifications.php:105
-msgid "Network Notifications"
-msgstr "Notificaciones de Red"
+#: mod/api.php:89
+msgid "Please login to continue."
+msgstr "Inicia sesión para continuar."
+
+#: mod/api.php:104
+msgid ""
+"Do you want to authorize this application to access your posts and contacts,"
+" and/or create new posts for you?"
+msgstr "¿Quieres autorizar a esta aplicación el acceso a tus mensajes y contactos, y/o crear nuevas publicaciones para ti?"
+
+#: mod/api.php:106 mod/dfrn_request.php:875 mod/follow.php:113
+#: mod/profiles.php:640 mod/profiles.php:644 mod/profiles.php:669
+#: mod/register.php:246 mod/settings.php:1171 mod/settings.php:1177
+#: mod/settings.php:1184 mod/settings.php:1188 mod/settings.php:1193
+#: mod/settings.php:1198 mod/settings.php:1203 mod/settings.php:1208
+#: mod/settings.php:1234 mod/settings.php:1235 mod/settings.php:1236
+#: mod/settings.php:1237 mod/settings.php:1238
+msgid "No"
+msgstr "No"
+
+#: mod/apps.php:11
+msgid "Applications"
+msgstr "Aplicaciones"
 
-#: mod/notifications.php:117
-msgid "Personal Notifications"
-msgstr "Notificaciones personales"
+#: mod/apps.php:14
+msgid "No installed applications."
+msgstr "Sin aplicaciones"
 
-#: mod/notifications.php:123
-msgid "Home Notifications"
-msgstr "Notificaciones de Inicio"
+#: mod/attach.php:8
+msgid "Item not available."
+msgstr "Elemento no disponible."
 
-#: mod/notifications.php:152
-msgid "Show Ignored Requests"
-msgstr "Mostrar peticiones ignoradas"
+#: mod/attach.php:20
+msgid "Item was not found."
+msgstr "Elemento no encontrado."
 
-#: mod/notifications.php:152
-msgid "Hide Ignored Requests"
-msgstr "Ocultar peticiones ignoradas"
+#: mod/babel.php:17
+msgid "Source (bbcode) text:"
+msgstr "Texto fuente (bbcode):"
 
-#: mod/notifications.php:164 mod/notifications.php:222
-msgid "Notification type: "
-msgstr "Tipo de notificación: "
+#: mod/babel.php:23
+msgid "Source (Diaspora) text to convert to BBcode:"
+msgstr "Fuente (Diaspora) para pasar a BBcode:"
 
-#: mod/notifications.php:167
-#, php-format
-msgid "suggested by %s"
-msgstr "sugerido por %s"
+#: mod/babel.php:31
+msgid "Source input: "
+msgstr "Entrada: "
 
-#: mod/notifications.php:172 mod/notifications.php:239 mod/contacts.php:613
-msgid "Hide this contact from others"
-msgstr "Ocultar este contacto a los demás."
+#: mod/babel.php:35
+msgid "bb2html (raw HTML): "
+msgstr "bb2html (raw HTML): "
 
-#: mod/notifications.php:173 mod/notifications.php:240
-msgid "Post a new friend activity"
-msgstr "Publica tu nueva amistad"
+#: mod/babel.php:39
+msgid "bb2html: "
+msgstr "bb2html: "
 
-#: mod/notifications.php:173 mod/notifications.php:240
-msgid "if applicable"
-msgstr "Si corresponde"
+#: mod/babel.php:43
+msgid "bb2html2bb: "
+msgstr "bb2html2bb: "
 
-#: mod/notifications.php:176 mod/notifications.php:249 mod/admin.php:1412
-msgid "Approve"
-msgstr "Aprobar"
+#: mod/babel.php:47
+msgid "bb2md: "
+msgstr "bb2md: "
 
-#: mod/notifications.php:195
-msgid "Claims to be known to you: "
-msgstr "Dice conocerte: "
+#: mod/babel.php:51
+msgid "bb2md2html: "
+msgstr "bb2md2html: "
 
-#: mod/notifications.php:196
-msgid "yes"
-msgstr ""
+#: mod/babel.php:55
+msgid "bb2dia2bb: "
+msgstr "bb2dia2bb: "
 
-#: mod/notifications.php:196
-msgid "no"
-msgstr "no"
+#: mod/babel.php:59
+msgid "bb2md2html2bb: "
+msgstr "bb2md2html2bb: "
 
-#: mod/notifications.php:197
-msgid ""
-"Shall your connection be bidirectional or not? \"Friend\" implies that you "
-"allow to read and you subscribe to their posts. \"Fan/Admirer\" means that "
-"you allow to read but you do not want to read theirs. Approve as: "
-msgstr "¿Deberá la coneccion ser bidireccional?\n\"Amigo\" implica que permitas la lectura y subscribas a las publicaciones del contacto.\n\"Admirador\" significa que permitas la lectura de tus publicaciones pero que no quieras ver sus publicaciones.\n\nAprobar como:"
+#: mod/babel.php:69
+msgid "Source input (Diaspora format): "
+msgstr "Fuente (formato Diaspora): "
 
-#: mod/notifications.php:200
-msgid ""
-"Shall your connection be bidirectional or not? \"Friend\" implies that you "
-"allow to read and you subscribe to their posts. \"Sharer\" means that you "
-"allow to read but you do not want to read theirs. Approve as: "
-msgstr "¿Deberá la coneccion ser bidireccional?\n\"Amigo\" implica que permitas la lectura y subscribas a las publicaciones del contacto.\n\"Sharer\" significa que permitas la lectura de tus publicaciones pero que no quieras ver sus publicaciones.\n\nAprobar como:"
+#: mod/babel.php:74
+msgid "diaspora2bb: "
+msgstr "diaspora2bb: "
 
-#: mod/notifications.php:209
-msgid "Friend"
-msgstr "Amigo"
+#: mod/bookmarklet.php:41
+msgid "The post was created"
+msgstr "La publicación fue creada"
 
-#: mod/notifications.php:210
-msgid "Sharer"
-msgstr "Lector"
+#: mod/cal.php:143 mod/display.php:328 mod/profile.php:154
+msgid "Access to this profile has been restricted."
+msgstr "El acceso a este perfil ha sido restringido."
 
-#: mod/notifications.php:210
-msgid "Fan/Admirer"
-msgstr "Fan/Admirador"
+#: mod/cal.php:271 mod/events.php:387
+msgid "View"
+msgstr "Vista"
 
-#: mod/notifications.php:243 mod/contacts.php:624 mod/follow.php:126
-msgid "Profile URL"
-msgstr "URL Perfil"
+#: mod/cal.php:272 mod/events.php:389
+msgid "Previous"
+msgstr "Previo"
 
-#: mod/notifications.php:260
-msgid "No introductions."
-msgstr "Sin presentaciones."
+#: mod/cal.php:273 mod/events.php:390 mod/install.php:235
+msgid "Next"
+msgstr "Siguiente"
 
-#: mod/notifications.php:299
-msgid "Show unread"
-msgstr "Mostrar no leído"
+#: mod/cal.php:282 mod/events.php:399
+msgid "list"
+msgstr "lista"
 
-#: mod/notifications.php:299
-msgid "Show all"
-msgstr "Mostrar todo"
+#: mod/cal.php:292
+msgid "User not found"
+msgstr "Usuario no encontrado"
 
-#: mod/notifications.php:305
-#, php-format
-msgid "No more %s notifications."
-msgstr "No más notificaciones de %s."
+#: mod/cal.php:308
+msgid "This calendar format is not supported"
+msgstr "Este formato de calendario no se soporta"
 
-#: mod/profiles.php:19 mod/profiles.php:134 mod/profiles.php:180
-#: mod/profiles.php:617 mod/dfrn_confirm.php:70
-msgid "Profile not found."
-msgstr "Perfil no encontrado."
+#: mod/cal.php:310
+msgid "No exportable data found"
+msgstr "No se ha encontrado información exportable"
 
-#: mod/profiles.php:38
-msgid "Profile deleted."
-msgstr "Perfil eliminado."
+#: mod/cal.php:325
+msgid "calendar"
+msgstr "calendario"
 
-#: mod/profiles.php:56 mod/profiles.php:90
-msgid "Profile-"
-msgstr "Perfil-"
+#: mod/common.php:91
+msgid "No contacts in common."
+msgstr "Sin contactos en común."
 
-#: mod/profiles.php:75 mod/profiles.php:118
-msgid "New profile created."
-msgstr "Nuevo perfil creado."
+#: mod/common.php:141 mod/contacts.php:871
+msgid "Common Friends"
+msgstr "Amigos comunes"
 
-#: mod/profiles.php:96
-msgid "Profile unavailable to clone."
-msgstr "Imposible duplicar el perfil."
+#: mod/community.php:22 mod/dfrn_request.php:799 mod/directory.php:37
+#: mod/display.php:200 mod/photos.php:964 mod/search.php:93 mod/search.php:99
+#: mod/videos.php:198 mod/viewcontacts.php:36
+msgid "Public access denied."
+msgstr "Acceso público denegado."
 
-#: mod/profiles.php:190
-msgid "Profile Name is required."
-msgstr "Se necesita un nombre de perfil."
+#: mod/community.php:27
+msgid "Not available."
+msgstr "No disponible"
 
-#: mod/profiles.php:338
-msgid "Marital Status"
-msgstr "Estado civil"
+#: mod/community.php:54 mod/search.php:224
+msgid "No results."
+msgstr "Sin resultados."
 
-#: mod/profiles.php:342
-msgid "Romantic Partner"
-msgstr "Pareja sentimental"
+#: mod/contacts.php:134
+#, php-format
+msgid "%d contact edited."
+msgid_plural "%d contacts edited."
+msgstr[0] "%d contacto editado."
+msgstr[1] "%d contacts edited."
 
-#: mod/profiles.php:354
-msgid "Work/Employment"
-msgstr "Trabajo/estudios"
+#: mod/contacts.php:169 mod/contacts.php:378
+msgid "Could not access contact record."
+msgstr "No se pudo acceder a los datos del contacto."
 
-#: mod/profiles.php:357
-msgid "Religion"
-msgstr "Religión"
+#: mod/contacts.php:183
+msgid "Could not locate selected profile."
+msgstr "No se pudo encontrar el perfil seleccionado."
 
-#: mod/profiles.php:361
-msgid "Political Views"
-msgstr "Preferencias políticas"
+#: mod/contacts.php:216
+msgid "Contact updated."
+msgstr "Contacto actualizado."
 
-#: mod/profiles.php:365
-msgid "Gender"
-msgstr "Género"
+#: mod/contacts.php:218 mod/dfrn_request.php:588
+msgid "Failed to update contact record."
+msgstr "Error al actualizar el contacto."
 
-#: mod/profiles.php:369
-msgid "Sexual Preference"
-msgstr "Orientación sexual"
+#: mod/contacts.php:399
+msgid "Contact has been blocked"
+msgstr "El contacto ha sido bloqueado"
 
-#: mod/profiles.php:373
-msgid "XMPP"
-msgstr "XMPP"
+#: mod/contacts.php:399
+msgid "Contact has been unblocked"
+msgstr "El contacto ha sido desbloqueado"
 
-#: mod/profiles.php:377
-msgid "Homepage"
-msgstr "Página de inicio"
+#: mod/contacts.php:410
+msgid "Contact has been ignored"
+msgstr "El contacto ha sido ignorado"
 
-#: mod/profiles.php:381 mod/profiles.php:702
-msgid "Interests"
-msgstr "Intereses"
+#: mod/contacts.php:410
+msgid "Contact has been unignored"
+msgstr "El contacto ya no está ignorado"
 
-#: mod/profiles.php:385
-msgid "Address"
-msgstr "Dirección"
+#: mod/contacts.php:422
+msgid "Contact has been archived"
+msgstr "El contacto ha sido archivado"
 
-#: mod/profiles.php:392 mod/profiles.php:698
-msgid "Location"
-msgstr "Ubicación"
+#: mod/contacts.php:422
+msgid "Contact has been unarchived"
+msgstr "El contacto ya no está archivado"
 
-#: mod/profiles.php:477
-msgid "Profile updated."
-msgstr "Perfil actualizado."
+#: mod/contacts.php:447
+msgid "Drop contact"
+msgstr "Eliminar contacto"
 
-#: mod/profiles.php:564
-msgid " and "
-msgstr " y "
+#: mod/contacts.php:450 mod/contacts.php:809
+msgid "Do you really want to delete this contact?"
+msgstr "¿Estás seguro de que quieres eliminar este contacto?"
 
-#: mod/profiles.php:572
-msgid "public profile"
-msgstr "perfil público"
+#: mod/contacts.php:469
+msgid "Contact has been removed."
+msgstr "El contacto ha sido eliminado"
 
-#: mod/profiles.php:575
+#: mod/contacts.php:506
 #, php-format
-msgid "%1$s changed %2$s to &ldquo;%3$s&rdquo;"
-msgstr "%1$s cambió su %2$s a &ldquo;%3$s&rdquo;"
+msgid "You are mutual friends with %s"
+msgstr "Ahora tienes una amistad mutua con %s"
 
-#: mod/profiles.php:576
+#: mod/contacts.php:510
 #, php-format
-msgid " - Visit %1$s's %2$s"
-msgstr " - Visita %1$s's %2$s"
+msgid "You are sharing with %s"
+msgstr "Estás compartiendo con %s"
 
-#: mod/profiles.php:579
+#: mod/contacts.php:515
 #, php-format
-msgid "%1$s has an updated %2$s, changing %3$s."
-msgstr "%1$s tiene una actualización %2$s, cambiando %3$s."
-
-#: mod/profiles.php:645
-msgid "Hide contacts and friends:"
-msgstr "Ocultar contactos y amigos"
-
-#: mod/profiles.php:650
-msgid "Hide your contact/friend list from viewers of this profile?"
-msgstr "¿Ocultar tu lista de contactos/amigos en este perfil?"
+msgid "%s is sharing with you"
+msgstr "%s está compartiendo contigo"
 
-#: mod/profiles.php:674
-msgid "Show more profile fields:"
-msgstr "Mostrar mas campos del perfil:"
+#: mod/contacts.php:535
+msgid "Private communications are not available for this contact."
+msgstr "Las comunicaciones privadas no está disponibles para este contacto."
 
-#: mod/profiles.php:686
-msgid "Profile Actions"
-msgstr "Acciones de perfil"
+#: mod/contacts.php:542
+msgid "(Update was successful)"
+msgstr "(La actualización se ha completado)"
 
-#: mod/profiles.php:687
-msgid "Edit Profile Details"
-msgstr "Editar detalles de tu perfil"
+#: mod/contacts.php:542
+msgid "(Update was not successful)"
+msgstr "(La actualización no se ha completado)"
 
-#: mod/profiles.php:689
-msgid "Change Profile Photo"
-msgstr "Cambiar imagen del Perfil"
+#: mod/contacts.php:544 mod/contacts.php:972
+msgid "Suggest friends"
+msgstr "Sugerir amigos"
 
-#: mod/profiles.php:690
-msgid "View this profile"
-msgstr "Ver este perfil"
+#: mod/contacts.php:548
+#, php-format
+msgid "Network type: %s"
+msgstr "Tipo de red: %s"
 
-#: mod/profiles.php:692
-msgid "Create a new profile using these settings"
-msgstr "¿Crear un nuevo perfil con esta configuración?"
+#: mod/contacts.php:561
+msgid "Communications lost with this contact!"
+msgstr "¡Se ha perdido la comunicación con este contacto!"
 
-#: mod/profiles.php:693
-msgid "Clone this profile"
-msgstr "Clonar este perfil"
+#: mod/contacts.php:564
+msgid "Fetch further information for feeds"
+msgstr "Recaudar informacion complementaria de los feeds"
 
-#: mod/profiles.php:694
-msgid "Delete this profile"
-msgstr "Eliminar este perfil"
+#: mod/contacts.php:565
+msgid "Fetch information"
+msgstr "Recaudar informacion"
 
-#: mod/profiles.php:696
-msgid "Basic information"
-msgstr "Información básica"
+#: mod/contacts.php:565
+msgid "Fetch information and keywords"
+msgstr "Recaudar informacion y palabras claves"
 
-#: mod/profiles.php:697
-msgid "Profile picture"
-msgstr "Imagen del perfil"
+#: mod/contacts.php:583
+msgid "Contact"
+msgstr "Contacto"
 
-#: mod/profiles.php:699
-msgid "Preferences"
-msgstr "Preferencias"
+#: mod/contacts.php:585 mod/content.php:728 mod/crepair.php:156
+#: mod/events.php:513 mod/fsuggest.php:108 mod/install.php:276
+#: mod/install.php:316 mod/invite.php:142 mod/localtime.php:45
+#: mod/manage.php:145 mod/message.php:338 mod/message.php:521 mod/mood.php:138
+#: mod/photos.php:1124 mod/photos.php:1246 mod/photos.php:1562
+#: mod/photos.php:1612 mod/photos.php:1660 mod/photos.php:1746
+#: mod/poke.php:203 mod/profiles.php:680 object/Item.php:705
+#: view/theme/duepuntozero/config.php:61 view/theme/frio/config.php:64
+#: view/theme/quattro/config.php:67 view/theme/vier/config.php:112
+msgid "Submit"
+msgstr "Envíar"
 
-#: mod/profiles.php:700
-msgid "Status information"
-msgstr "Información del estatus"
+#: mod/contacts.php:586
+msgid "Profile Visibility"
+msgstr "Visibilidad del Perfil"
 
-#: mod/profiles.php:701
-msgid "Additional information"
-msgstr "Información addicional"
+#: mod/contacts.php:587
+#, php-format
+msgid ""
+"Please choose the profile you would like to display to %s when viewing your "
+"profile securely."
+msgstr "Por favor, selecciona el perfil que quieras mostrar a %s cuando esté viendo tu perfil de forma segura."
 
-#: mod/profiles.php:704
-msgid "Relation"
-msgstr "Relación"
+#: mod/contacts.php:588
+msgid "Contact Information / Notes"
+msgstr "Información del Contacto / Notas"
 
-#: mod/profiles.php:708
-msgid "Your Gender:"
-msgstr "Género:"
+#: mod/contacts.php:589
+msgid "Edit contact notes"
+msgstr "Editar notas del contacto"
 
-#: mod/profiles.php:709
-msgid "<span class=\"heart\">&hearts;</span> Marital Status:"
-msgstr "<span class=\"heart\"&hearts;</span> Estado civil:"
+#: mod/contacts.php:594 mod/contacts.php:938 mod/nogroup.php:43
+#: mod/viewcontacts.php:102
+#, php-format
+msgid "Visit %s's profile [%s]"
+msgstr "Ver el perfil de %s [%s]"
 
-#: mod/profiles.php:711
-msgid "Example: fishing photography software"
-msgstr "Ejemplo: pesca fotografía software"
+#: mod/contacts.php:595
+msgid "Block/Unblock contact"
+msgstr "Boquear/Desbloquear contacto"
 
-#: mod/profiles.php:716
-msgid "Profile Name:"
-msgstr "Nombres del perfil:"
+#: mod/contacts.php:596
+msgid "Ignore contact"
+msgstr "Ignorar contacto"
 
-#: mod/profiles.php:716 mod/events.php:484 mod/events.php:496
-msgid "Required"
-msgstr "Obligatorio"
+#: mod/contacts.php:597
+msgid "Repair URL settings"
+msgstr "Configuración de reparación de la dirección"
 
-#: mod/profiles.php:718
-msgid ""
-"This is your <strong>public</strong> profile.<br />It <strong>may</strong> "
-"be visible to anybody using the internet."
-msgstr "Éste es tu perfil <strong>público</strong>.<br /><strong>Puede</strong> ser visto por cualquier usuario de internet."
+#: mod/contacts.php:598
+msgid "View conversations"
+msgstr "Ver conversaciones"
 
-#: mod/profiles.php:719
-msgid "Your Full Name:"
-msgstr "Tu nombre completo:"
+#: mod/contacts.php:604
+msgid "Last update:"
+msgstr "Última actualización:"
 
-#: mod/profiles.php:720
-msgid "Title/Description:"
-msgstr "Título/Descrición:"
+#: mod/contacts.php:606
+msgid "Update public posts"
+msgstr "Actualizar publicaciones públicas"
 
-#: mod/profiles.php:723
-msgid "Street Address:"
-msgstr "Dirección"
+#: mod/contacts.php:608 mod/contacts.php:982
+msgid "Update now"
+msgstr "Actualizar ahora"
 
-#: mod/profiles.php:724
-msgid "Locality/City:"
-msgstr "Localidad/Ciudad:"
+#: mod/contacts.php:614 mod/contacts.php:814 mod/contacts.php:999
+msgid "Unignore"
+msgstr "Quitar de Ignorados"
 
-#: mod/profiles.php:725
-msgid "Region/State:"
-msgstr "Región/Estado:"
+#: mod/contacts.php:614 mod/contacts.php:814 mod/contacts.php:999
+#: mod/notifications.php:60 mod/notifications.php:179
+#: mod/notifications.php:257
+msgid "Ignore"
+msgstr "Ignorar"
 
-#: mod/profiles.php:726
-msgid "Postal/Zip Code:"
-msgstr "Código postal:"
+#: mod/contacts.php:618
+msgid "Currently blocked"
+msgstr "Bloqueados"
 
-#: mod/profiles.php:727
-msgid "Country:"
-msgstr "País"
+#: mod/contacts.php:619
+msgid "Currently ignored"
+msgstr "Ignorados"
 
-#: mod/profiles.php:731
-msgid "Who: (if applicable)"
-msgstr "¿Quién? (si es aplicable)"
+#: mod/contacts.php:620
+msgid "Currently archived"
+msgstr "Archivados"
 
-#: mod/profiles.php:731
-msgid "Examples: cathy123, Cathy Williams, cathy@example.com"
-msgstr "Ejemplos: cathy123, Cathy Williams, cathy@example.com"
+#: mod/contacts.php:621 mod/notifications.php:172 mod/notifications.php:245
+msgid "Hide this contact from others"
+msgstr "Ocultar este contacto a los demás."
 
-#: mod/profiles.php:732
-msgid "Since [date]:"
-msgstr "Desde [fecha]:"
+#: mod/contacts.php:621
+msgid ""
+"Replies/likes to your public posts <strong>may</strong> still be visible"
+msgstr "Los comentarios o \"me gusta\" en tus publicaciones públicas todavía <strong>pueden</strong> ser visibles."
 
-#: mod/profiles.php:734
-msgid "Tell us about yourself..."
-msgstr "Háblanos sobre ti..."
+#: mod/contacts.php:622
+msgid "Notification for new posts"
+msgstr "Notificacion de nuevos temas."
 
-#: mod/profiles.php:735
-msgid "XMPP (Jabber) address:"
-msgstr "Dirección XMPP (Jabber):"
+#: mod/contacts.php:622
+msgid "Send a notification of every new post of this contact"
+msgstr "Enviar una notificacion por nuevos temas de este contacto."
+
+#: mod/contacts.php:625
+msgid "Blacklisted keywords"
+msgstr "Lista negra de palabras"
 
-#: mod/profiles.php:735
+#: mod/contacts.php:625
 msgid ""
-"The XMPP address will be propagated to your contacts so that they can follow"
-" you."
-msgstr "La dirección XMPP será propagada entre sus contactos para que puedan seguirle."
+"Comma separated list of keywords that should not be converted to hashtags, "
+"when \"Fetch information and keywords\" is selected"
+msgstr "Lista separada por comas de palabras claves que no deberian ser convertido en #hashtags cuando \"Recaudar informacion y palabras claves\" es seleccionado"
 
-#: mod/profiles.php:736
-msgid "Homepage URL:"
-msgstr "Dirección de tu página:"
+#: mod/contacts.php:632 mod/follow.php:129 mod/notifications.php:249
+msgid "Profile URL"
+msgstr "URL Perfil"
 
-#: mod/profiles.php:739
-msgid "Religious Views:"
-msgstr "Creencias religiosas:"
+#: mod/contacts.php:643
+msgid "Actions"
+msgstr "Acciones"
 
-#: mod/profiles.php:740
-msgid "Public Keywords:"
-msgstr "Palabras clave públicas:"
+#: mod/contacts.php:646
+msgid "Contact Settings"
+msgstr "Ajustes del contacto"
 
-#: mod/profiles.php:740
-msgid "(Used for suggesting potential friends, can be seen by others)"
-msgstr "(Utilizadas para sugerir amigos potenciales, otros pueden verlo)"
+#: mod/contacts.php:692
+msgid "Suggestions"
+msgstr "Sugerencias"
 
-#: mod/profiles.php:741
-msgid "Private Keywords:"
-msgstr "Palabras clave privadas:"
+#: mod/contacts.php:695
+msgid "Suggest potential friends"
+msgstr "Amistades potenciales sugeridas"
 
-#: mod/profiles.php:741
-msgid "(Used for searching profiles, never shown to others)"
-msgstr "(Utilizadas para buscar perfiles, nunca se muestra a otros)"
+#: mod/contacts.php:700 mod/group.php:202
+msgid "All Contacts"
+msgstr "Todos los contactos"
 
-#: mod/profiles.php:744
-msgid "Musical interests"
-msgstr "Gustos musicales"
+#: mod/contacts.php:703
+msgid "Show all contacts"
+msgstr "Mostrar todos los contactos"
 
-#: mod/profiles.php:745
-msgid "Books, literature"
-msgstr "Libros, literatura"
+#: mod/contacts.php:708
+msgid "Unblocked"
+msgstr "Desbloqueados"
 
-#: mod/profiles.php:746
-msgid "Television"
-msgstr "Televisión"
+#: mod/contacts.php:711
+msgid "Only show unblocked contacts"
+msgstr "Mostrar solo contactos sin bloquear"
 
-#: mod/profiles.php:747
-msgid "Film/dance/culture/entertainment"
-msgstr "Películas/baile/cultura/entretenimiento"
+#: mod/contacts.php:717
+msgid "Blocked"
+msgstr "Bloqueados"
 
-#: mod/profiles.php:748
-msgid "Hobbies/Interests"
-msgstr "Aficiones/Intereses"
+#: mod/contacts.php:720
+msgid "Only show blocked contacts"
+msgstr "Mostrar solo contactos bloqueados"
 
-#: mod/profiles.php:749
-msgid "Love/romance"
-msgstr "Amor/Romance"
+#: mod/contacts.php:726
+msgid "Ignored"
+msgstr "Ignorados"
 
-#: mod/profiles.php:750
-msgid "Work/employment"
-msgstr "Trabajo/ocupación"
+#: mod/contacts.php:729
+msgid "Only show ignored contacts"
+msgstr "Mostrar solo contactos ignorados"
 
-#: mod/profiles.php:751
-msgid "School/education"
-msgstr "Escuela/estudios"
+#: mod/contacts.php:735
+msgid "Archived"
+msgstr "Archivados"
 
-#: mod/profiles.php:752
-msgid "Contact information and Social Networks"
-msgstr "Informacioń de contacto y Redes sociales"
+#: mod/contacts.php:738
+msgid "Only show archived contacts"
+msgstr "Mostrar solo contactos archivados"
 
-#: mod/profiles.php:794
-msgid "Edit/Manage Profiles"
-msgstr "Editar/Administrar perfiles"
+#: mod/contacts.php:744
+msgid "Hidden"
+msgstr "Ocultos"
 
-#: mod/allfriends.php:43
-msgid "No friends to display."
-msgstr "No hay amigos para mostrar."
+#: mod/contacts.php:747
+msgid "Only show hidden contacts"
+msgstr "Mostrar solo contactos ocultos"
 
-#: mod/cal.php:149 mod/display.php:328 mod/profile.php:155
-msgid "Access to this profile has been restricted."
-msgstr "El acceso a este perfil ha sido restringido."
+#: mod/contacts.php:804
+msgid "Search your contacts"
+msgstr "Buscar en tus contactos"
 
-#: mod/cal.php:276 mod/events.php:380
-msgid "View"
-msgstr "Vista"
+#: mod/contacts.php:805 mod/network.php:145 mod/search.php:232
+#, php-format
+msgid "Results for: %s"
+msgstr "Resultados para: %s"
 
-#: mod/cal.php:277 mod/events.php:382
-msgid "Previous"
-msgstr "Previo"
+#: mod/contacts.php:812 mod/settings.php:160 mod/settings.php:707
+msgid "Update"
+msgstr "Actualizar"
 
-#: mod/cal.php:278 mod/events.php:383 mod/install.php:231
-msgid "Next"
-msgstr "Siguiente"
+#: mod/contacts.php:815 mod/contacts.php:1007
+msgid "Archive"
+msgstr "Archivo"
 
-#: mod/cal.php:287 mod/events.php:392
-msgid "list"
-msgstr "lista"
+#: mod/contacts.php:815 mod/contacts.php:1007
+msgid "Unarchive"
+msgstr "Sin archivar"
+
+#: mod/contacts.php:818
+msgid "Batch Actions"
+msgstr "Accones en lote"
+
+#: mod/contacts.php:864
+msgid "View all contacts"
+msgstr "Ver todos los contactos"
 
-#: mod/cal.php:297
-msgid "User not found"
-msgstr "Usuario no encontrado"
+#: mod/contacts.php:874
+msgid "View all common friends"
+msgstr "Ver todos los conocidos en común "
 
-#: mod/cal.php:313
-msgid "This calendar format is not supported"
-msgstr "Este formato de calendario no se soporta"
+#: mod/contacts.php:881
+msgid "Advanced Contact Settings"
+msgstr "Configuración avanzada"
 
-#: mod/cal.php:315
-msgid "No exportable data found"
-msgstr "No se ha encontrado información exportable"
+#: mod/contacts.php:915
+msgid "Mutual Friendship"
+msgstr "Amistad recíproca"
 
-#: mod/cal.php:330
-msgid "calendar"
-msgstr "calendario"
+#: mod/contacts.php:919
+msgid "is a fan of yours"
+msgstr "es tu fan"
 
-#: mod/common.php:86
-msgid "No contacts in common."
-msgstr "Sin contactos en común."
+#: mod/contacts.php:923
+msgid "you are a fan of"
+msgstr "eres fan de"
 
-#: mod/common.php:134 mod/contacts.php:863
-msgid "Common Friends"
-msgstr "Amigos comunes"
+#: mod/contacts.php:939 mod/nogroup.php:44
+msgid "Edit contact"
+msgstr "Modificar contacto"
 
-#: mod/community.php:27
-msgid "Not available."
-msgstr "No disponible"
+#: mod/contacts.php:993
+msgid "Toggle Blocked status"
+msgstr "Cambiar bloqueados"
 
-#: mod/directory.php:197 view/theme/vier/theme.php:201
-msgid "Global Directory"
-msgstr "Directorio global"
+#: mod/contacts.php:1001
+msgid "Toggle Ignored status"
+msgstr "Cambiar ignorados"
 
-#: mod/directory.php:199
-msgid "Find on this site"
-msgstr "Buscar en este sitio"
+#: mod/contacts.php:1009
+msgid "Toggle Archive status"
+msgstr "Cambiar archivados"
 
-#: mod/directory.php:201
-msgid "Results for:"
-msgstr "Resultados para:"
+#: mod/contacts.php:1017
+msgid "Delete contact"
+msgstr "Eliminar contacto"
 
-#: mod/directory.php:203
-msgid "Site Directory"
-msgstr "Directorio del sitio"
+#: mod/content.php:119 mod/network.php:468
+msgid "No such group"
+msgstr "Ningún grupo"
 
-#: mod/directory.php:210
-msgid "No entries (some entries may be hidden)."
-msgstr "Sin entradas (algunas pueden que estén ocultas)."
+#: mod/content.php:130 mod/group.php:203 mod/network.php:495
+msgid "Group is empty"
+msgstr "El grupo está vacío"
 
-#: mod/dirfind.php:36
+#: mod/content.php:135 mod/network.php:499
 #, php-format
-msgid "People Search - %s"
-msgstr "Buscar perfiles - %s"
+msgid "Group: %s"
+msgstr "Grupo: %s"
+
+#: mod/content.php:325 object/Item.php:96
+msgid "This entry was edited"
+msgstr "Esta entrada fue editada"
 
-#: mod/dirfind.php:47
+#: mod/content.php:621 object/Item.php:417
 #, php-format
-msgid "Forum Search - %s"
-msgstr "Búsqueda de foro - %s"
+msgid "%d comment"
+msgid_plural "%d comments"
+msgstr[0] "%d comentario"
+msgstr[1] "%d comentarios"
 
-#: mod/dirfind.php:240 mod/match.php:107
-msgid "No matches"
-msgstr "Sin conincidencias"
+#: mod/content.php:638 mod/photos.php:1402 object/Item.php:117
+msgid "Private Message"
+msgstr "Mensaje privado"
 
-#: mod/display.php:473
-msgid "Item has been removed."
-msgstr "El elemento ha sido eliminado."
+#: mod/content.php:702 mod/photos.php:1590 object/Item.php:274
+msgid "I like this (toggle)"
+msgstr "Me gusta esto (cambiar)"
 
-#: mod/events.php:95 mod/events.php:97
-msgid "Event can not end before it has started."
-msgstr "Un evento no puede terminar antes de su comienzo."
+#: mod/content.php:702 object/Item.php:274
+msgid "like"
+msgstr "me gusta"
 
-#: mod/events.php:104 mod/events.php:106
-msgid "Event title and start time are required."
-msgstr "Título del evento y hora de inicio requeridas."
+#: mod/content.php:703 mod/photos.php:1591 object/Item.php:275
+msgid "I don't like this (toggle)"
+msgstr "No me gusta esto (cambiar)"
 
-#: mod/events.php:381
-msgid "Create New Event"
-msgstr "Crea un evento nuevo"
+#: mod/content.php:703 object/Item.php:275
+msgid "dislike"
+msgstr "no me gusta"
 
-#: mod/events.php:482
-msgid "Event details"
-msgstr "Detalles del evento"
+#: mod/content.php:705 object/Item.php:278
+msgid "Share this"
+msgstr "Compartir esto"
 
-#: mod/events.php:483
-msgid "Starting date and Title are required."
-msgstr "Se requiere fecha de comienzo y titulo"
+#: mod/content.php:705 object/Item.php:278
+msgid "share"
+msgstr "compartir"
 
-#: mod/events.php:484 mod/events.php:485
-msgid "Event Starts:"
-msgstr "Inicio del evento:"
+#: mod/content.php:725 mod/photos.php:1609 mod/photos.php:1657
+#: mod/photos.php:1743 object/Item.php:702
+msgid "This is you"
+msgstr "Este eres tú"
 
-#: mod/events.php:486 mod/events.php:502
-msgid "Finish date/time is not known or not relevant"
-msgstr "La fecha/hora de finalización no es conocida o es irrelevante."
+#: mod/content.php:727 mod/content.php:950 mod/photos.php:1611
+#: mod/photos.php:1659 mod/photos.php:1745 object/Item.php:392
+#: object/Item.php:704
+msgid "Comment"
+msgstr "Comentar"
 
-#: mod/events.php:488 mod/events.php:489
-msgid "Event Finishes:"
-msgstr "Finalización del evento:"
+#: mod/content.php:729 object/Item.php:706
+msgid "Bold"
+msgstr "Negrita"
 
-#: mod/events.php:490 mod/events.php:503
-msgid "Adjust for viewer timezone"
-msgstr "Ajuste de zona horaria"
+#: mod/content.php:730 object/Item.php:707
+msgid "Italic"
+msgstr "Cursiva"
 
-#: mod/events.php:492
-msgid "Description:"
-msgstr "Descripción:"
+#: mod/content.php:731 object/Item.php:708
+msgid "Underline"
+msgstr "Subrayado"
 
-#: mod/events.php:496 mod/events.php:498
-msgid "Title:"
-msgstr "Título:"
+#: mod/content.php:732 object/Item.php:709
+msgid "Quote"
+msgstr "Cita"
 
-#: mod/events.php:499 mod/events.php:500
-msgid "Share this event"
-msgstr "Comparte este evento"
+#: mod/content.php:733 object/Item.php:710
+msgid "Code"
+msgstr "Código"
 
-#: mod/maintenance.php:9
-msgid "System down for maintenance"
-msgstr "Servicio suspendido por mantenimiento"
+#: mod/content.php:734 object/Item.php:711
+msgid "Image"
+msgstr "Imagen"
 
-#: mod/match.php:33
-msgid "No keywords to match. Please add keywords to your default profile."
-msgstr "No hay palabras clave que coincidan. Por favor, agrega algunas palabras claves en tu perfil predeterminado."
+#: mod/content.php:735 object/Item.php:712
+msgid "Link"
+msgstr "Enlace"
 
-#: mod/match.php:86
-msgid "is interested in:"
-msgstr "estás interesado en:"
+#: mod/content.php:736 object/Item.php:713
+msgid "Video"
+msgstr "Vídeo"
 
-#: mod/match.php:100
-msgid "Profile Match"
-msgstr "Coincidencias de Perfil"
+#: mod/content.php:746 mod/settings.php:743 object/Item.php:122
+#: object/Item.php:124
+msgid "Edit"
+msgstr "Editar"
 
-#: mod/profile.php:179
-msgid "Tips for New Members"
-msgstr "Consejos para nuevos miembros"
+#: mod/content.php:772 object/Item.php:238
+msgid "add star"
+msgstr "Añadir estrella"
 
-#: mod/suggest.php:27
-msgid "Do you really want to delete this suggestion?"
-msgstr "¿Estás seguro de que quieres borrar esta sugerencia?"
+#: mod/content.php:773 object/Item.php:239
+msgid "remove star"
+msgstr "Quitar estrella"
 
-#: mod/suggest.php:71
-msgid ""
-"No suggestions available. If this is a new site, please try again in 24 "
-"hours."
-msgstr "No hay sugerencias disponibles. Si el sitio web es nuevo inténtalo de nuevo dentro de 24 horas."
+#: mod/content.php:774 object/Item.php:240
+msgid "toggle star status"
+msgstr "Añadir a destacados"
 
-#: mod/suggest.php:84 mod/suggest.php:104
-msgid "Ignore/Hide"
-msgstr "Ignorar/Ocultar"
+#: mod/content.php:777 object/Item.php:243
+msgid "starred"
+msgstr "marcados con estrellas"
 
-#: mod/update_community.php:19 mod/update_display.php:23
-#: mod/update_network.php:27 mod/update_notes.php:36 mod/update_profile.php:35
-msgid "[Embedded content - reload page to view]"
-msgstr "[Contenido incrustado - recarga la página para verlo]"
+#: mod/content.php:778 mod/content.php:800 object/Item.php:263
+msgid "add tag"
+msgstr "añadir etiqueta"
 
-#: mod/photos.php:88 mod/photos.php:1856
-msgid "Recent Photos"
-msgstr "Fotos recientes"
+#: mod/content.php:789 object/Item.php:251
+msgid "ignore thread"
+msgstr "ignorar publicación"
 
-#: mod/photos.php:91 mod/photos.php:1283 mod/photos.php:1858
-msgid "Upload New Photos"
-msgstr "Subir nuevas fotos"
+#: mod/content.php:790 object/Item.php:252
+msgid "unignore thread"
+msgstr "revertir ignorar publicacion"
 
-#: mod/photos.php:105 mod/settings.php:36
-msgid "everybody"
-msgstr "todos"
+#: mod/content.php:791 object/Item.php:253
+msgid "toggle ignore status"
+msgstr "cambiar estatus de observación"
 
-#: mod/photos.php:169
-msgid "Contact information unavailable"
-msgstr "Información del contacto no disponible"
+#: mod/content.php:794 mod/ostatus_subscribe.php:73 object/Item.php:256
+msgid "ignored"
+msgstr "ignorado"
 
-#: mod/photos.php:190
-msgid "Album not found."
-msgstr "Álbum no encontrado."
+#: mod/content.php:805 object/Item.php:141
+msgid "save to folder"
+msgstr "grabado en directorio"
 
-#: mod/photos.php:220 mod/photos.php:232 mod/photos.php:1227
-msgid "Delete Album"
-msgstr "Eliminar álbum"
+#: mod/content.php:853 object/Item.php:212
+msgid "I will attend"
+msgstr "Voy a estar presente"
 
-#: mod/photos.php:230
-msgid "Do you really want to delete this photo album and all its photos?"
-msgstr "¿Estás seguro de quieres borrar este álbum y todas sus fotos?"
+#: mod/content.php:853 object/Item.php:212
+msgid "I will not attend"
+msgstr "No voy a estar presente"
 
-#: mod/photos.php:308 mod/photos.php:319 mod/photos.php:1540
-msgid "Delete Photo"
-msgstr "Eliminar foto"
+#: mod/content.php:853 object/Item.php:212
+msgid "I might attend"
+msgstr "Puede que voy a estar presente"
 
-#: mod/photos.php:317
-msgid "Do you really want to delete this photo?"
-msgstr "¿Estás seguro de que quieres borrar esta foto?"
+#: mod/content.php:917 object/Item.php:358
+msgid "to"
+msgstr "a"
 
-#: mod/photos.php:688
-#, php-format
-msgid "%1$s was tagged in %2$s by %3$s"
-msgstr "%1$s fue etiquetado en %2$s por %3$s"
+#: mod/content.php:918 object/Item.php:360
+msgid "Wall-to-Wall"
+msgstr "Muro-A-Muro"
 
-#: mod/photos.php:688
-msgid "a photo"
-msgstr "una foto"
+#: mod/content.php:919 object/Item.php:361
+msgid "via Wall-To-Wall:"
+msgstr "via Muro-A-Muro:"
 
-#: mod/photos.php:794
-msgid "Image file is empty."
-msgstr "El archivo de imagen está vacío."
+#: mod/credits.php:16
+msgid "Credits"
+msgstr "Creditos"
 
-#: mod/photos.php:954
-msgid "No photos selected"
-msgstr "Ninguna foto seleccionada"
+#: mod/credits.php:17
+msgid ""
+"Friendica is a community project, that would not be possible without the "
+"help of many people. Here is a list of those who have contributed to the "
+"code or the translation of Friendica. Thank you all!"
+msgstr "Friendica es un proyecto comunitario, que no seria posible sin la ayuda de mucha gente. Aquí una lista de de aquellos que aportaron al código o la traducción de friendica.\nGracias a todos! "
 
-#: mod/photos.php:1054 mod/videos.php:305
-msgid "Access to this item is restricted."
-msgstr "El acceso a este elemento está restringido."
+#: mod/crepair.php:89
+msgid "Contact settings applied."
+msgstr "Contacto configurado con éxito."
 
-#: mod/photos.php:1114
-#, php-format
-msgid "You have used %1$.2f Mbytes of %2$.2f Mbytes photo storage."
-msgstr "Has usado %1$.2f MB de %2$.2f MB de tu álbum de fotos."
+#: mod/crepair.php:91
+msgid "Contact update failed."
+msgstr "Error al actualizar el Contacto."
 
-#: mod/photos.php:1148
-msgid "Upload Photos"
-msgstr "Subir fotos"
+#: mod/crepair.php:116 mod/dfrn_confirm.php:126 mod/fsuggest.php:21
+#: mod/fsuggest.php:93
+msgid "Contact not found."
+msgstr "Contacto no encontrado."
+
+#: mod/crepair.php:122
+msgid ""
+"<strong>WARNING: This is highly advanced</strong> and if you enter incorrect"
+" information your communications with this contact may stop working."
+msgstr "<strong>ADVERTENCIA: Esto es muy avanzado</strong> y si se introduce información incorrecta tu conexión con este contacto puede dejar de funcionar."
+
+#: mod/crepair.php:123
+msgid ""
+"Please use your browser 'Back' button <strong>now</strong> if you are "
+"uncertain what to do on this page."
+msgstr "Por favor usa el botón 'Atás' de tu navegador <strong>ahora</strong> si no tienes claro qué hacer en esta página."
+
+#: mod/crepair.php:136 mod/crepair.php:138
+msgid "No mirroring"
+msgstr "No espejar"
+
+#: mod/crepair.php:136
+msgid "Mirror as forwarded posting"
+msgstr "Espejar como reenvio"
 
-#: mod/photos.php:1152 mod/photos.php:1222
-msgid "New album name: "
-msgstr "Nombre del nuevo álbum: "
+#: mod/crepair.php:136 mod/crepair.php:138
+msgid "Mirror as my own posting"
+msgstr "Espejar como publicación propia"
 
-#: mod/photos.php:1153
-msgid "or existing album name: "
-msgstr "o nombre de un álbum existente: "
+#: mod/crepair.php:152
+msgid "Return to contact editor"
+msgstr "Volver al editor de contactos"
 
-#: mod/photos.php:1154
-msgid "Do not show a status post for this upload"
-msgstr "No actualizar tu estado con este envío"
+#: mod/crepair.php:154
+msgid "Refetch contact data"
+msgstr "Volver a solicitar datos del contacto."
 
-#: mod/photos.php:1165 mod/photos.php:1544 mod/settings.php:1300
-msgid "Show to Groups"
-msgstr "Mostrar a los Grupos"
+#: mod/crepair.php:158
+msgid "Remote Self"
+msgstr "Perfil remoto"
 
-#: mod/photos.php:1166 mod/photos.php:1545 mod/settings.php:1301
-msgid "Show to Contacts"
-msgstr "Mostrar a los Contactos"
+#: mod/crepair.php:161
+msgid "Mirror postings from this contact"
+msgstr "Espejar publicaciones de este contacto"
 
-#: mod/photos.php:1167
-msgid "Private Photo"
-msgstr "Foto Privada"
+#: mod/crepair.php:163
+msgid ""
+"Mark this contact as remote_self, this will cause friendica to repost new "
+"entries from this contact."
+msgstr "Marcar este contacto como perfil_remoto, esto generara que friendica reenvía nuevas publicaciones desde esta cuenta."
 
-#: mod/photos.php:1168
-msgid "Public Photo"
-msgstr "Foto Pública"
+#: mod/crepair.php:168
+msgid "Account Nickname"
+msgstr "Apodo de la cuenta"
 
-#: mod/photos.php:1234
-msgid "Edit Album"
-msgstr "Modificar álbum"
+#: mod/crepair.php:169
+msgid "@Tagname - overrides Name/Nickname"
+msgstr "@Etiqueta - Sobrescribe el Nombre/Apodo"
 
-#: mod/photos.php:1240
-msgid "Show Newest First"
-msgstr "Mostrar más nuevos primero"
+#: mod/crepair.php:170
+msgid "Account URL"
+msgstr "Dirección de la cuenta"
 
-#: mod/photos.php:1242
-msgid "Show Oldest First"
-msgstr "Mostrar más antiguos primero"
+#: mod/crepair.php:171
+msgid "Friend Request URL"
+msgstr "Dirección de la solicitud de amistad"
 
-#: mod/photos.php:1269 mod/photos.php:1841
-msgid "View Photo"
-msgstr "Ver foto"
+#: mod/crepair.php:172
+msgid "Friend Confirm URL"
+msgstr "Dirección de confirmación de tu amigo "
 
-#: mod/photos.php:1315
-msgid "Permission denied. Access to this item may be restricted."
-msgstr "Permiso denegado. El acceso a este elemento puede estar restringido."
+#: mod/crepair.php:173
+msgid "Notification Endpoint URL"
+msgstr "Dirección URL de la notificación"
 
-#: mod/photos.php:1317
-msgid "Photo not available"
-msgstr "Foto no disponible"
+#: mod/crepair.php:174
+msgid "Poll/Feed URL"
+msgstr "Dirección del Sondeo/Fuentes"
 
-#: mod/photos.php:1372
-msgid "View photo"
-msgstr "Ver foto"
+#: mod/crepair.php:175
+msgid "New photo from this URL"
+msgstr "Nueva foto de esta dirección"
 
-#: mod/photos.php:1372
-msgid "Edit photo"
-msgstr "Modificar foto"
+#: mod/delegate.php:101
+msgid "No potential page delegates located."
+msgstr "No se han localizado delegados potenciales de la página."
 
-#: mod/photos.php:1373
-msgid "Use as profile photo"
-msgstr "Usar como foto del perfil"
+#: mod/delegate.php:132
+msgid ""
+"Delegates are able to manage all aspects of this account/page except for "
+"basic account settings. Please do not delegate your personal account to "
+"anybody that you do not trust completely."
+msgstr "Los delegados tienen la capacidad de gestionar todos los aspectos de esta cuenta/página, excepto los ajustes básicos de la cuenta. Por favor, no delegues tu cuenta personal a nadie en quien no confíes completamente."
 
-#: mod/photos.php:1398
-msgid "View Full Size"
-msgstr "Ver a tamaño completo"
+#: mod/delegate.php:133
+msgid "Existing Page Managers"
+msgstr "Administradores actuales de la página"
 
-#: mod/photos.php:1484
-msgid "Tags: "
-msgstr "Etiquetas: "
+#: mod/delegate.php:135
+msgid "Existing Page Delegates"
+msgstr "Delegados actuales de la página"
 
-#: mod/photos.php:1487
-msgid "[Remove any tag]"
-msgstr "[Borrar todas las etiquetas]"
+#: mod/delegate.php:137
+msgid "Potential Delegates"
+msgstr "Delegados potenciales"
 
-#: mod/photos.php:1526
-msgid "New album name"
-msgstr "Nuevo nombre del álbum"
+#: mod/delegate.php:139 mod/tagrm.php:95
+msgid "Remove"
+msgstr "Eliminar"
 
-#: mod/photos.php:1527
-msgid "Caption"
-msgstr "Título"
+#: mod/delegate.php:140
+msgid "Add"
+msgstr "Añadir"
 
-#: mod/photos.php:1528
-msgid "Add a Tag"
-msgstr "Añadir una etiqueta"
+#: mod/delegate.php:141
+msgid "No entries."
+msgstr "Sin entradas."
 
-#: mod/photos.php:1528
-msgid ""
-"Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping"
-msgstr "Ejemplo: @juan, @Barbara_Ruiz, @julia@example.com, #California, #camping"
+#: mod/dfrn_confirm.php:70 mod/profiles.php:19 mod/profiles.php:134
+#: mod/profiles.php:180 mod/profiles.php:619
+msgid "Profile not found."
+msgstr "Perfil no encontrado."
 
-#: mod/photos.php:1529
-msgid "Do not rotate"
-msgstr "No rotar"
+#: mod/dfrn_confirm.php:127
+msgid ""
+"This may occasionally happen if contact was requested by both persons and it"
+" has already been approved."
+msgstr "Esto puede ocurrir a veces si la conexión fue solicitada por ambas personas y ya hubiera sido aprobada."
 
-#: mod/photos.php:1530
-msgid "Rotate CW (right)"
-msgstr "Girar a la derecha"
+#: mod/dfrn_confirm.php:244
+msgid "Response from remote site was not understood."
+msgstr "La respuesta desde el sitio remoto no ha sido entendida."
 
-#: mod/photos.php:1531
-msgid "Rotate CCW (left)"
-msgstr "Girar a la izquierda"
+#: mod/dfrn_confirm.php:253 mod/dfrn_confirm.php:258
+msgid "Unexpected response from remote site: "
+msgstr "Respuesta inesperada desde el sitio remoto: "
 
-#: mod/photos.php:1546
-msgid "Private photo"
-msgstr "Foto privada"
+#: mod/dfrn_confirm.php:267
+msgid "Confirmation completed successfully."
+msgstr "Confirmación completada con éxito."
 
-#: mod/photos.php:1547
-msgid "Public photo"
-msgstr "Foto pública"
+#: mod/dfrn_confirm.php:269 mod/dfrn_confirm.php:283 mod/dfrn_confirm.php:290
+msgid "Remote site reported: "
+msgstr "El sito remoto informó: "
 
-#: mod/photos.php:1770
-msgid "Map"
-msgstr "Mapa"
+#: mod/dfrn_confirm.php:281
+msgid "Temporary failure. Please wait and try again."
+msgstr "Error temporal. Por favor, espere y vuelva a intentarlo."
 
-#: mod/photos.php:1847 mod/videos.php:387
-msgid "View Album"
-msgstr "Ver Álbum"
+#: mod/dfrn_confirm.php:288
+msgid "Introduction failed or was revoked."
+msgstr "La presentación ha fallado o ha sido anulada."
 
-#: mod/register.php:93
-msgid ""
-"Registration successful. Please check your email for further instructions."
-msgstr "Te has registrado con éxito. Por favor, consulta tu correo para más información."
+#: mod/dfrn_confirm.php:418
+msgid "Unable to set contact photo."
+msgstr "Imposible establecer la foto del contacto."
 
-#: mod/register.php:98
+#: mod/dfrn_confirm.php:559
 #, php-format
-msgid ""
-"Failed to send email message. Here your accout details:<br> login: %s<br> "
-"password: %s<br><br>You can change your password after login."
-msgstr "Error al intentar de enviar mensaje de correo. Aquí los detalles de su cuenta: <br> login: %s<br> contraseña: %s<br><br>Puede cambiar su contraseña después de ingresar al sitio."
+msgid "No user record found for '%s' "
+msgstr "No se ha encontrado a ningún '%s' "
 
-#: mod/register.php:105
-msgid "Registration successful."
-msgstr "Registro exitoso."
+#: mod/dfrn_confirm.php:569
+msgid "Our site encryption key is apparently messed up."
+msgstr "Nuestra clave de cifrado del sitio es aparentemente un lío."
 
-#: mod/register.php:111
-msgid "Your registration can not be processed."
-msgstr "Tu registro no se puede procesar."
+#: mod/dfrn_confirm.php:580
+msgid "Empty site URL was provided or URL could not be decrypted by us."
+msgstr "Se ha proporcionado una dirección vacía o no hemos podido descifrarla."
 
-#: mod/register.php:160
-msgid "Your registration is pending approval by the site owner."
-msgstr "Tu registro está pendiente de aprobación por el propietario del sitio."
+#: mod/dfrn_confirm.php:601
+msgid "Contact record was not found for you on our site."
+msgstr "El contacto no se ha encontrado en nuestra base de datos."
 
-#: mod/register.php:226
-msgid ""
-"You may (optionally) fill in this form via OpenID by supplying your OpenID "
-"and clicking 'Register'."
-msgstr "Puedes (opcionalmente) rellenar este formulario a través de OpenID escribiendo tu OpenID y pulsando en \"Registrar\"."
+#: mod/dfrn_confirm.php:615
+#, php-format
+msgid "Site public key not available in contact record for URL %s."
+msgstr "La clave pública del sitio no está disponible en los datos del contacto para %s."
 
-#: mod/register.php:227
+#: mod/dfrn_confirm.php:635
 msgid ""
-"If you are not familiar with OpenID, please leave that field blank and fill "
-"in the rest of the items."
-msgstr "Si no estás familiarizado con OpenID, por favor deja ese campo en blanco y rellena el resto de los elementos."
+"The ID provided by your system is a duplicate on our system. It should work "
+"if you try again."
+msgstr "La identificación proporcionada por el sistema es un duplicado de nuestro sistema. Debería funcionar si lo intentas de nuevo."
 
-#: mod/register.php:228
-msgid "Your OpenID (optional): "
-msgstr "Tu OpenID (opcional):"
+#: mod/dfrn_confirm.php:646
+msgid "Unable to set your contact credentials on our system."
+msgstr "No se puede establecer las credenciales de tu contacto en nuestro sistema."
 
-#: mod/register.php:242
-msgid "Include your profile in member directory?"
-msgstr "¿Incluir tu perfil en el directorio de miembros?"
+#: mod/dfrn_confirm.php:708
+msgid "Unable to update your contact profile details on our system"
+msgstr "No se puede actualizar los datos de tu perfil de contacto en nuestro sistema"
 
-#: mod/register.php:267
-msgid "Note for the admin"
-msgstr "Nota para el administrador"
+#: mod/dfrn_confirm.php:780
+#, php-format
+msgid "%1$s has joined %2$s"
+msgstr "%1$s se ha unido a %2$s"
 
-#: mod/register.php:267
-msgid "Leave a message for the admin, why you want to join this node"
-msgstr "Deje un mensaje para el administrador sobre por qué quiere unirse a este nodo"
+#: mod/dfrn_poll.php:104 mod/dfrn_poll.php:539
+#, php-format
+msgid "%1$s welcomes %2$s"
+msgstr "%1$s te da la bienvenida a %2$s"
 
-#: mod/register.php:268
-msgid "Membership on this site is by invitation only."
-msgstr "Sitio solo accesible mediante invitación."
+#: mod/dfrn_request.php:101
+msgid "This introduction has already been accepted."
+msgstr "Esta presentación ya ha sido aceptada."
 
-#: mod/register.php:269
-msgid "Your invitation ID: "
-msgstr "ID de tu invitación: "
+#: mod/dfrn_request.php:124 mod/dfrn_request.php:523
+msgid "Profile location is not valid or does not contain profile information."
+msgstr "La dirección del perfil no es válida o no contiene información del perfil."
 
-#: mod/register.php:272 mod/admin.php:956
-msgid "Registration"
-msgstr "Registro"
+#: mod/dfrn_request.php:129 mod/dfrn_request.php:528
+msgid "Warning: profile location has no identifiable owner name."
+msgstr "Aviso: La dirección del perfil no tiene un nombre de propietario identificable."
 
-#: mod/register.php:280
-msgid "Your Full Name (e.g. Joe Smith, real or real-looking): "
-msgstr "Nombre completo (ej. Joe Smith, real o real aparente):"
+#: mod/dfrn_request.php:132 mod/dfrn_request.php:531
+msgid "Warning: profile location has no profile photo."
+msgstr "Aviso: la dirección del perfil no tiene foto de perfil."
 
-#: mod/register.php:281
-msgid "Your Email Address: "
-msgstr "Tu dirección de correo: "
+#: mod/dfrn_request.php:136 mod/dfrn_request.php:535
+#, php-format
+msgid "%d required parameter was not found at the given location"
+msgid_plural "%d required parameters were not found at the given location"
+msgstr[0] "no se encontró %d parámetro requerido en el lugar determinado"
+msgstr[1] "no se encontraron %d parámetros requeridos en el lugar determinado"
 
-#: mod/register.php:283 mod/settings.php:1271
-msgid "New Password:"
-msgstr "Contraseña nueva:"
+#: mod/dfrn_request.php:180
+msgid "Introduction complete."
+msgstr "Presentación completa."
 
-#: mod/register.php:283
-msgid "Leave empty for an auto generated password."
-msgstr "Dejar vacío para autogenerar una contraseña"
+#: mod/dfrn_request.php:225
+msgid "Unrecoverable protocol error."
+msgstr "Error de protocolo irrecuperable."
 
-#: mod/register.php:284 mod/settings.php:1272
-msgid "Confirm:"
-msgstr "Confirmar:"
+#: mod/dfrn_request.php:253
+msgid "Profile unavailable."
+msgstr "Perfil no disponible."
+
+#: mod/dfrn_request.php:280
+#, php-format
+msgid "%s has received too many connection requests today."
+msgstr "%s ha recibido demasiadas solicitudes de conexión hoy."
 
-#: mod/register.php:285
-msgid ""
-"Choose a profile nickname. This must begin with a text character. Your "
-"profile address on this site will then be "
-"'<strong>nickname@$sitename</strong>'."
-msgstr "Elije un apodo. Debe comenzar con una letra. Tu dirección de perfil en este sitio va a ser \"<strong>apodo@$nombredelsitio</strong>\"."
+#: mod/dfrn_request.php:281
+msgid "Spam protection measures have been invoked."
+msgstr "Han sido activadas las medidas de protección contra spam."
 
-#: mod/register.php:286
-msgid "Choose a nickname: "
-msgstr "Escoge un apodo: "
+#: mod/dfrn_request.php:282
+msgid "Friends are advised to please try again in 24 hours."
+msgstr "Tus amigos serán avisados para que lo intenten de nuevo pasadas 24 horas."
 
-#: mod/register.php:296
-msgid "Import your profile to this friendica instance"
-msgstr "Importar tu perfil a esta instancia de friendica"
+#: mod/dfrn_request.php:344
+msgid "Invalid locator"
+msgstr "Localizador no válido"
 
-#: mod/settings.php:43 mod/admin.php:1396
-msgid "Account"
-msgstr "Cuenta"
+#: mod/dfrn_request.php:353
+msgid "Invalid email address."
+msgstr "Dirección de correo incorrecta"
 
-#: mod/settings.php:52 mod/admin.php:160
-msgid "Additional features"
-msgstr "Características adicionales"
+#: mod/dfrn_request.php:378
+msgid "This account has not been configured for email. Request failed."
+msgstr "Esta cuenta no ha sido configurada para el correo. Fallo de solicitud."
 
-#: mod/settings.php:60
-msgid "Display"
-msgstr "Interfaz del usuario"
+#: mod/dfrn_request.php:481
+msgid "You have already introduced yourself here."
+msgstr "Ya te has presentado aquí."
 
-#: mod/settings.php:67 mod/settings.php:886
-msgid "Social Networks"
-msgstr "Redes sociales"
+#: mod/dfrn_request.php:485
+#, php-format
+msgid "Apparently you are already friends with %s."
+msgstr "Al parecer, ya eres amigo de %s."
 
-#: mod/settings.php:74 mod/admin.php:158 mod/admin.php:1522 mod/admin.php:1582
-msgid "Plugins"
-msgstr "Módulos"
+#: mod/dfrn_request.php:506
+msgid "Invalid profile URL."
+msgstr "Dirección de perfil no válida."
 
-#: mod/settings.php:88
-msgid "Connected apps"
-msgstr "Aplicaciones conectadas"
+#: mod/dfrn_request.php:609
+msgid "Your introduction has been sent."
+msgstr "Tu presentación ha sido enviada."
 
-#: mod/settings.php:102
-msgid "Remove account"
-msgstr "Eliminar cuenta"
+#: mod/dfrn_request.php:651
+msgid ""
+"Remote subscription can't be done for your network. Please subscribe "
+"directly on your system."
+msgstr "La subscripción remota no se podrá hacer para tu red. Por favor contacta directamente desde tu sistema."
 
-#: mod/settings.php:155
-msgid "Missing some important data!"
-msgstr "¡Faltan algunos datos importantes!"
+#: mod/dfrn_request.php:672
+msgid "Please login to confirm introduction."
+msgstr "Inicia sesión para confirmar la presentación."
 
-#: mod/settings.php:158 mod/settings.php:704 mod/contacts.php:804
-msgid "Update"
-msgstr "Actualizar"
+#: mod/dfrn_request.php:682
+msgid ""
+"Incorrect identity currently logged in. Please login to "
+"<strong>this</strong> profile."
+msgstr "Sesión iniciada con la identificación incorrecta. Entra en <strong>este</strong> perfil."
 
-#: mod/settings.php:269
-msgid "Failed to connect with email account using the settings provided."
-msgstr "Error al conectar con la cuenta de correo mediante la configuración suministrada."
+#: mod/dfrn_request.php:696 mod/dfrn_request.php:713
+msgid "Confirm"
+msgstr "Confirmar"
 
-#: mod/settings.php:274
-msgid "Email settings updated."
-msgstr "Configuración de correo actualizada."
+#: mod/dfrn_request.php:708
+msgid "Hide this contact"
+msgstr "Ocultar este contacto"
 
-#: mod/settings.php:289
-msgid "Features updated"
-msgstr "Actualizaciones"
+#: mod/dfrn_request.php:711
+#, php-format
+msgid "Welcome home %s."
+msgstr "Bienvenido a casa %s"
 
-#: mod/settings.php:359
-msgid "Relocate message has been send to your contacts"
-msgstr "Mensaje de reubicación ha sido enviado a sus contactos."
+#: mod/dfrn_request.php:712
+#, php-format
+msgid "Please confirm your introduction/connection request to %s."
+msgstr "Por favor, confirma tu solicitud de presentación/conexión con %s."
 
-#: mod/settings.php:378
-msgid "Empty passwords are not allowed. Password unchanged."
-msgstr "No se permiten contraseñas vacías. La contraseña no ha sido modificada."
+#: mod/dfrn_request.php:843
+msgid ""
+"Please enter your 'Identity Address' from one of the following supported "
+"communications networks:"
+msgstr "Por favor introduce tu dirección ID de una de las siguientes redes sociales soportadas:"
 
-#: mod/settings.php:386
-msgid "Wrong password."
-msgstr "Contraseña incorrecta"
+#: mod/dfrn_request.php:867
+#, php-format
+msgid ""
+"If you are not yet a member of the free social web, <a "
+"href=\"%s/siteinfo\">follow this link to find a public Friendica site and "
+"join us today</a>."
+msgstr "Si aun no eres miembro de la red social libre  <a href=\"%s/siteinfo\">seguí este enlace para encontrara un sitio disponible de friendica y acompañanos hoy mismo</a>"
 
-#: mod/settings.php:397
-msgid "Password changed."
-msgstr "Contraseña modificada."
+#: mod/dfrn_request.php:872
+msgid "Friend/Connection Request"
+msgstr "Solicitud de Amistad/Conexión"
 
-#: mod/settings.php:399
-msgid "Password update failed. Please try again."
-msgstr "La actualización de la contraseña ha fallado. Por favor, prueba otra vez."
+#: mod/dfrn_request.php:873
+msgid ""
+"Examples: jojo@demo.friendica.com, http://demo.friendica.com/profile/jojo, "
+"testuser@identi.ca"
+msgstr "Ejemplos: jojo@demo.friendica.com, http://demo.friendica.com/profile/jojo, testuser@identi.ca"
 
-#: mod/settings.php:479
-msgid " Please use a shorter name."
-msgstr " Usa un nombre más corto."
+#: mod/dfrn_request.php:874 mod/follow.php:112
+msgid "Please answer the following:"
+msgstr "Por favor responde lo siguiente:"
 
-#: mod/settings.php:481
-msgid " Name too short."
-msgstr " Nombre demasiado corto."
+#: mod/dfrn_request.php:875 mod/follow.php:113
+#, php-format
+msgid "Does %s know you?"
+msgstr "¿%s te conoce?"
 
-#: mod/settings.php:490
-msgid "Wrong Password"
-msgstr "Contraseña incorrecta"
+#: mod/dfrn_request.php:879 mod/follow.php:114
+msgid "Add a personal note:"
+msgstr "Añade una nota personal:"
 
-#: mod/settings.php:495
-msgid " Not valid email."
-msgstr " Correo no válido."
+#: mod/dfrn_request.php:882
+msgid "StatusNet/Federated Social Web"
+msgstr "StatusNet/Web Social Federada"
 
-#: mod/settings.php:501
-msgid " Cannot change to that email."
-msgstr " No se puede usar ese correo."
+#: mod/dfrn_request.php:884
+#, php-format
+msgid ""
+" - please do not use this form.  Instead, enter %s into your Diaspora search"
+" bar."
+msgstr "(En vez de usar este formulario, introduce %s en la barra de búsqueda de Diaspora."
 
-#: mod/settings.php:557
-msgid "Private forum has no privacy permissions. Using default privacy group."
-msgstr "El foro privado no tiene permisos de privacidad. Usando el grupo de privacidad por defecto."
+#: mod/dfrn_request.php:885 mod/follow.php:120
+msgid "Your Identity Address:"
+msgstr "Dirección de tu perfil:"
 
-#: mod/settings.php:561
-msgid "Private forum has no privacy permissions and no default privacy group."
-msgstr "El foro privado no tiene permisos de privacidad ni grupo por defecto de privacidad."
+#: mod/dfrn_request.php:888 mod/follow.php:19
+msgid "Submit Request"
+msgstr "Enviar solicitud"
 
-#: mod/settings.php:601
-msgid "Settings updated."
-msgstr "Configuración actualizada."
+#: mod/directory.php:199 view/theme/vier/theme.php:196
+msgid "Global Directory"
+msgstr "Directorio global"
 
-#: mod/settings.php:677 mod/settings.php:703 mod/settings.php:739
-msgid "Add application"
-msgstr "Agregar aplicación"
+#: mod/directory.php:201
+msgid "Find on this site"
+msgstr "Buscar en este sitio"
 
-#: mod/settings.php:678 mod/settings.php:788 mod/settings.php:835
-#: mod/settings.php:904 mod/settings.php:996 mod/settings.php:1264
-#: mod/admin.php:955 mod/admin.php:1583 mod/admin.php:1831 mod/admin.php:1905
-#: mod/admin.php:2055
-msgid "Save Settings"
-msgstr "Guardar configuración"
+#: mod/directory.php:203
+msgid "Results for:"
+msgstr "Resultados para:"
 
-#: mod/settings.php:681 mod/settings.php:707
-msgid "Consumer Key"
-msgstr "Clave del consumidor"
+#: mod/directory.php:205
+msgid "Site Directory"
+msgstr "Directorio del sitio"
 
-#: mod/settings.php:682 mod/settings.php:708
-msgid "Consumer Secret"
-msgstr "Secreto del consumidor"
+#: mod/directory.php:212
+msgid "No entries (some entries may be hidden)."
+msgstr "Sin entradas (algunas pueden que estén ocultas)."
 
-#: mod/settings.php:683 mod/settings.php:709
-msgid "Redirect"
-msgstr "Redirigir"
+#: mod/dirfind.php:37
+#, php-format
+msgid "People Search - %s"
+msgstr "Buscar perfiles - %s"
 
-#: mod/settings.php:684 mod/settings.php:710
-msgid "Icon url"
-msgstr "Dirección del ícono"
+#: mod/dirfind.php:48
+#, php-format
+msgid "Forum Search - %s"
+msgstr "Búsqueda de foro - %s"
 
-#: mod/settings.php:695
-msgid "You can't edit this application."
-msgstr "No puedes editar esta aplicación."
+#: mod/dirfind.php:245 mod/match.php:109
+msgid "No matches"
+msgstr "Sin conincidencias"
 
-#: mod/settings.php:738
-msgid "Connected Apps"
-msgstr "Aplicaciones conectadas"
+#: mod/display.php:479
+msgid "Item has been removed."
+msgstr "El elemento ha sido eliminado."
 
-#: mod/settings.php:742
-msgid "Client key starts with"
-msgstr "Clave de cliente comienza por"
+#: mod/editpost.php:17 mod/editpost.php:27
+msgid "Item not found"
+msgstr "Elemento no encontrado"
 
-#: mod/settings.php:743
-msgid "No name"
-msgstr "Sin nombre"
+#: mod/editpost.php:32
+msgid "Edit post"
+msgstr "Editar publicación"
 
-#: mod/settings.php:744
-msgid "Remove authorization"
-msgstr "Suprimir la autorización"
+#: mod/events.php:100 mod/events.php:102
+msgid "Event can not end before it has started."
+msgstr "Un evento no puede terminar antes de su comienzo."
 
-#: mod/settings.php:756
-msgid "No Plugin settings configured"
-msgstr "No se ha configurado ningún módulo"
+#: mod/events.php:109 mod/events.php:111
+msgid "Event title and start time are required."
+msgstr "Título del evento y hora de inicio requeridas."
 
-#: mod/settings.php:764
-msgid "Plugin Settings"
-msgstr "Configuración de los módulos"
+#: mod/events.php:388
+msgid "Create New Event"
+msgstr "Crea un evento nuevo"
 
-#: mod/settings.php:778 mod/admin.php:2044 mod/admin.php:2045
-msgid "Off"
-msgstr "Apagado"
+#: mod/events.php:489
+msgid "Event details"
+msgstr "Detalles del evento"
 
-#: mod/settings.php:778 mod/admin.php:2044 mod/admin.php:2045
-msgid "On"
-msgstr "Encendido"
+#: mod/events.php:490
+msgid "Starting date and Title are required."
+msgstr "Se requiere fecha de comienzo y titulo"
 
-#: mod/settings.php:786
-msgid "Additional Features"
-msgstr "Características adicionales"
+#: mod/events.php:491 mod/events.php:492
+msgid "Event Starts:"
+msgstr "Inicio del evento:"
 
-#: mod/settings.php:796 mod/settings.php:800
-msgid "General Social Media Settings"
-msgstr "Configuración general de social media "
+#: mod/events.php:491 mod/events.php:503 mod/profiles.php:708
+msgid "Required"
+msgstr "Obligatorio"
 
-#: mod/settings.php:806
-msgid "Disable intelligent shortening"
-msgstr "Deshabilitar recorte inteligente de URL"
+#: mod/events.php:493 mod/events.php:509
+msgid "Finish date/time is not known or not relevant"
+msgstr "La fecha/hora de finalización no es conocida o es irrelevante."
 
-#: mod/settings.php:808
-msgid ""
-"Normally the system tries to find the best link to add to shortened posts. "
-"If this option is enabled then every shortened post will always point to the"
-" original friendica post."
-msgstr "Normalemente el sistema intenta de encontrara el mejor enlace para agregar a envíos recortados (twitter, OStatus). Si esta opción se encuentra habilitado, todo envío recortado apuntara siempre al tema original en friendica."
+#: mod/events.php:495 mod/events.php:496
+msgid "Event Finishes:"
+msgstr "Finalización del evento:"
 
-#: mod/settings.php:814
-msgid "Automatically follow any GNU Social (OStatus) followers/mentioners"
-msgstr "Automáticamente seguir cualquier GNUsocial (OStatus) seguidores o menciones "
+#: mod/events.php:497 mod/events.php:510
+msgid "Adjust for viewer timezone"
+msgstr "Ajuste de zona horaria"
 
-#: mod/settings.php:816
-msgid ""
-"If you receive a message from an unknown OStatus user, this option decides "
-"what to do. If it is checked, a new contact will be created for every "
-"unknown user."
-msgstr "Cuando se recibe un mensaje de un perfil desconocido de OStatus, esta opción define que hacer.\nSi es habilitado, un nuevo contacto sera creado para cada usuario."
+#: mod/events.php:499
+msgid "Description:"
+msgstr "Descripción:"
 
-#: mod/settings.php:822
-msgid "Default group for OStatus contacts"
-msgstr "Grupo por defecto para contactos OStatus"
+#: mod/events.php:503 mod/events.php:505
+msgid "Title:"
+msgstr "Título:"
 
-#: mod/settings.php:828
-msgid "Your legacy GNU Social account"
-msgstr "Tu cuenta GNU social conectada"
+#: mod/events.php:506 mod/events.php:507
+msgid "Share this event"
+msgstr "Comparte este evento"
 
-#: mod/settings.php:830
-msgid ""
-"If you enter your old GNU Social/Statusnet account name here (in the format "
-"user@domain.tld), your contacts will be added automatically. The field will "
-"be emptied when done."
-msgstr "Si agrega su viejo nombre de perfil  GNUsocial/Statusnet aqui (en el formato de usuario@dominio.tld), sus contactos serán añadidos automáticamente.\nEl campo sera vaciado cuando termine el proceso. "
+#: mod/fbrowser.php:132
+msgid "Files"
+msgstr "Archivos"
+
+#: mod/filer.php:30
+msgid "- select -"
+msgstr "- seleccionar -"
 
-#: mod/settings.php:833
-msgid "Repair OStatus subscriptions"
-msgstr "Reparar subscripciones de OStatus"
+#: mod/follow.php:30
+msgid "You already added this contact."
+msgstr "Ya has añadido este contacto."
 
-#: mod/settings.php:842 mod/settings.php:843
-#, php-format
-msgid "Built-in support for %s connectivity is %s"
-msgstr "El soporte integrado de conexión con %s está %s"
+#: mod/follow.php:39
+msgid "Diaspora support isn't enabled. Contact can't be added."
+msgstr "El soporte de Diaspora* no esta habilitado, el contacto no puede ser agregado."
 
-#: mod/settings.php:842 mod/settings.php:843
-msgid "enabled"
-msgstr "habilitado"
+#: mod/follow.php:46
+msgid "OStatus support is disabled. Contact can't be added."
+msgstr "El soporte de OStatus no esta habilitado, el contacto no puede ser agregado."
 
-#: mod/settings.php:842 mod/settings.php:843
-msgid "disabled"
-msgstr "deshabilitado"
+#: mod/follow.php:53
+msgid "The network type couldn't be detected. Contact can't be added."
+msgstr "No se pudo detectar el tipo de red. Contacto no puede ser agregado."
 
-#: mod/settings.php:843
-msgid "GNU Social (OStatus)"
-msgstr "GNUsocial (OStatus)"
+#: mod/follow.php:186
+msgid "Contact added"
+msgstr "Contacto añadido"
 
-#: mod/settings.php:879
-msgid "Email access is disabled on this site."
-msgstr "El acceso por correo está deshabilitado en esta web."
+#: mod/friendica.php:72
+msgid "This is Friendica, version"
+msgstr "Esto es Friendica, versión"
 
-#: mod/settings.php:891
-msgid "Email/Mailbox Setup"
-msgstr "Configuración del correo/buzón"
+#: mod/friendica.php:73
+msgid "running at web location"
+msgstr "ejecutándose en la dirección web"
 
-#: mod/settings.php:892
+#: mod/friendica.php:75
 msgid ""
-"If you wish to communicate with email contacts using this service "
-"(optional), please specify how to connect to your mailbox."
-msgstr "Si quieres comunicarte con tus contactos de correo usando este servicio (opcional), por favor, especifica cómo conectar con tu buzón."
+"Please visit <a href=\"http://friendica.com\">Friendica.com</a> to learn "
+"more about the Friendica project."
+msgstr "Por favor, visita <a href=\"http://friendica.com\">Friendica.com</a> para saber más sobre el proyecto Friendica."
 
-#: mod/settings.php:893
-msgid "Last successful email check:"
-msgstr "Última comprobación del correo con éxito:"
+#: mod/friendica.php:77
+msgid "Bug reports and issues: please visit"
+msgstr "Reporte de fallos y problemas: por favor visita"
 
-#: mod/settings.php:895
-msgid "IMAP server name:"
-msgstr "Nombre del servidor IMAP:"
+#: mod/friendica.php:77
+msgid "the bugtracker at github"
+msgstr "aviso de fallas (bugs) en github"
 
-#: mod/settings.php:896
-msgid "IMAP port:"
-msgstr "Puerto IMAP:"
+#: mod/friendica.php:78
+msgid ""
+"Suggestions, praise, donations, etc. - please email \"Info\" at Friendica - "
+"dot com"
+msgstr "Sugerencias, elogios, donaciones, etc. por favor manda un correo a Info arroba Friendica punto com"
 
-#: mod/settings.php:897
-msgid "Security:"
-msgstr "Seguridad:"
+#: mod/friendica.php:92
+msgid "Installed plugins/addons/apps:"
+msgstr "Módulos/extensiones/aplicaciones instalados:"
 
-#: mod/settings.php:897 mod/settings.php:902
-msgid "None"
-msgstr "Ninguna"
+#: mod/friendica.php:105
+msgid "No installed plugins/addons/apps"
+msgstr "Módulos/extensiones/aplicaciones no instalados"
 
-#: mod/settings.php:898
-msgid "Email login name:"
-msgstr "Nombre de usuario:"
+#: mod/fsuggest.php:64
+msgid "Friend suggestion sent."
+msgstr "Solicitud de amistad enviada."
 
-#: mod/settings.php:899
-msgid "Email password:"
-msgstr "Contraseña:"
+#: mod/fsuggest.php:98
+msgid "Suggest Friends"
+msgstr "Sugerencias de amistad"
 
-#: mod/settings.php:900
-msgid "Reply-to address:"
-msgstr "Dirección de respuesta:"
+#: mod/fsuggest.php:100
+#, php-format
+msgid "Suggest a friend for %s"
+msgstr "Recomienda un amigo a %s"
 
-#: mod/settings.php:901
-msgid "Send public posts to all email contacts:"
-msgstr "Enviar publicaciones públicas a todos los contactos de correo:"
+#: mod/group.php:29
+msgid "Group created."
+msgstr "Grupo creado."
 
-#: mod/settings.php:902
-msgid "Action after import:"
-msgstr "Acción después de importar:"
+#: mod/group.php:35
+msgid "Could not create group."
+msgstr "Imposible crear el grupo."
 
-#: mod/settings.php:902
-msgid "Move to folder"
-msgstr "Mover a un directorio"
+#: mod/group.php:49 mod/group.php:150
+msgid "Group not found."
+msgstr "Grupo no encontrado."
 
-#: mod/settings.php:903
-msgid "Move to folder:"
-msgstr "Mover al directorio:"
+#: mod/group.php:63
+msgid "Group name changed."
+msgstr "El nombre del grupo ha cambiado."
 
-#: mod/settings.php:934 mod/admin.php:862
-msgid "No special theme for mobile devices"
-msgstr "No hay tema especial para dispositivos móviles"
+#: mod/group.php:91
+msgid "Save Group"
+msgstr "Guardar grupo"
 
-#: mod/settings.php:994
-msgid "Display Settings"
-msgstr "Configuración Tema/Visualización"
+#: mod/group.php:97
+msgid "Create a group of contacts/friends."
+msgstr "Crea un grupo de contactos/amigos."
 
-#: mod/settings.php:1000 mod/settings.php:1023
-msgid "Display Theme:"
-msgstr "Utilizar tema:"
+#: mod/group.php:122
+msgid "Group removed."
+msgstr "Grupo eliminado."
 
-#: mod/settings.php:1001
-msgid "Mobile Theme:"
-msgstr "Tema móvil:"
+#: mod/group.php:124
+msgid "Unable to remove group."
+msgstr "No se puede eliminar el grupo."
 
-#: mod/settings.php:1002
-msgid "Suppress warning of insecure networks"
-msgstr "Suprimir el aviso de redes inseguras"
+#: mod/group.php:187
+msgid "Group Editor"
+msgstr "Editor de grupos"
 
-#: mod/settings.php:1002
-msgid ""
-"Should the system suppress the warning that the current group contains "
-"members of networks that can't receive non public postings."
-msgstr "Debería el sistema suprimir el aviso de que el grupo actual contiene miembros de redes que no pueden recibir publicaciones públicas."
+#: mod/group.php:200
+msgid "Members"
+msgstr "Miembros"
 
-#: mod/settings.php:1003
-msgid "Update browser every xx seconds"
-msgstr "Actualizar navegador cada xx segundos"
+#: mod/group.php:233 mod/profperm.php:107
+msgid "Click on a contact to add or remove."
+msgstr "Pulsa en un contacto para añadirlo o eliminarlo."
 
-#: mod/settings.php:1003
-msgid "Minimum of 10 seconds. Enter -1 to disable it."
-msgstr "Minimo 10 segundos. Ingrese -1 para deshabilitar."
+#: mod/hcard.php:11
+msgid "No profile"
+msgstr "Nigún perfil"
 
-#: mod/settings.php:1004
-msgid "Number of items to display per page:"
-msgstr "Número de elementos a mostrar por página:"
+#: mod/help.php:41
+msgid "Help:"
+msgstr "Ayuda:"
 
-#: mod/settings.php:1004 mod/settings.php:1005
-msgid "Maximum of 100 items"
-msgstr "Máximo 100 elementos"
+#: mod/home.php:39
+#, php-format
+msgid "Welcome to %s"
+msgstr "Bienvenido a %s"
 
-#: mod/settings.php:1005
-msgid "Number of items to display per page when viewed from mobile device:"
-msgstr "Cantidad de objetos a visualizar cuando se usa un movil"
+#: mod/install.php:140
+msgid "Friendica Communications Server - Setup"
+msgstr "Servidor de comunicación Friendica - Configuración"
 
-#: mod/settings.php:1006
-msgid "Don't show emoticons"
-msgstr "No mostrar emoticones"
+#: mod/install.php:146
+msgid "Could not connect to database."
+msgstr "No es posible la conexión con la base de datos."
 
-#: mod/settings.php:1007
-msgid "Calendar"
-msgstr "Calendario"
+#: mod/install.php:150
+msgid "Could not create table."
+msgstr "No se puede crear la tabla."
 
-#: mod/settings.php:1008
-msgid "Beginning of week:"
-msgstr "Principio de la semana:"
+#: mod/install.php:156
+msgid "Your Friendica site database has been installed."
+msgstr "La base de datos de su sitio web de Friendica ha sido instalada."
 
-#: mod/settings.php:1009
-msgid "Don't show notices"
-msgstr "No mostrara avisos"
+#: mod/install.php:161
+msgid ""
+"You may need to import the file \"database.sql\" manually using phpmyadmin "
+"or mysql."
+msgstr "Puede que tengas que importar el archivo \"Database.sql\" manualmente usando phpmyadmin o mysql."
 
-#: mod/settings.php:1010
-msgid "Infinite scroll"
-msgstr "pagina infinita (sroll)"
+#: mod/install.php:162 mod/install.php:234 mod/install.php:609
+msgid "Please see the file \"INSTALL.txt\"."
+msgstr "Por favor, consulta el archivo \"INSTALL.txt\"."
 
-#: mod/settings.php:1011
-msgid "Automatic updates only at the top of the network page"
-msgstr "Actualizaciones automaticas solo estando al principio de la pagina"
+#: mod/install.php:174
+msgid "Database already in use."
+msgstr "Base de datos ya se encuentra en uso"
 
-#: mod/settings.php:1012
-msgid "Bandwith Saver Mode"
-msgstr "Modo de guardado de ancho de banda"
+#: mod/install.php:231
+msgid "System check"
+msgstr "Verificación del sistema"
 
-#: mod/settings.php:1012
-msgid ""
-"When enabled, embedded content is not displayed on automatic updates, they "
-"only show on page reload."
-msgstr "Cuando está habilitado, el contenido incrustado no se muestra en las actualizaciones automáticas, sólo en las páginas recargadas."
+#: mod/install.php:236
+msgid "Check again"
+msgstr "Compruebalo de nuevo"
 
-#: mod/settings.php:1014
-msgid "General Theme Settings"
-msgstr "Ajustes generales de tema"
+#: mod/install.php:255
+msgid "Database connection"
+msgstr "Conexión con la base de datos"
 
-#: mod/settings.php:1015
-msgid "Custom Theme Settings"
-msgstr "Ajustes personalizados de tema"
+#: mod/install.php:256
+msgid ""
+"In order to install Friendica we need to know how to connect to your "
+"database."
+msgstr "Con el fin de poder instalar Friendica, necesitamos saber cómo conectar con tu base de datos."
 
-#: mod/settings.php:1016
-msgid "Content Settings"
-msgstr "Ajustes de contenido"
+#: mod/install.php:257
+msgid ""
+"Please contact your hosting provider or site administrator if you have "
+"questions about these settings."
+msgstr "Por favor, contacta con tu proveedor de servicios o con el administrador de la página si tienes alguna pregunta sobre estas configuraciones."
 
-#: mod/settings.php:1017 view/theme/frio/config.php:61
-#: view/theme/quattro/config.php:66 view/theme/vier/config.php:109
-#: view/theme/duepuntozero/config.php:61
-msgid "Theme settings"
-msgstr "Configuración del Tema"
+#: mod/install.php:258
+msgid ""
+"The database you specify below should already exist. If it does not, please "
+"create it before continuing."
+msgstr "La base de datos que especifiques a continuación debería existir ya. Si no es el caso, debes crearla antes de continuar."
 
-#: mod/settings.php:1099
-msgid "Account Types"
-msgstr "Tipos de cuenta"
+#: mod/install.php:262
+msgid "Database Server Name"
+msgstr "Nombre del servidor de la base de datos"
 
-#: mod/settings.php:1100
-msgid "Personal Page Subtypes"
-msgstr "Subtipos de página personal"
+#: mod/install.php:263
+msgid "Database Login Name"
+msgstr "Usuario de la base de datos"
 
-#: mod/settings.php:1101
-msgid "Community Forum Subtypes"
-msgstr "Subtipos de foro de comunidad"
+#: mod/install.php:264
+msgid "Database Login Password"
+msgstr "Contraseña de la base de datos"
 
-#: mod/settings.php:1108
-msgid "Personal Page"
-msgstr "Página personal"
+#: mod/install.php:264
+msgid "For security reasons the password must not be empty"
+msgstr "Por razones de seguridad la contraseña no debe estar vacía"
 
-#: mod/settings.php:1109
-msgid "This account is a regular personal profile"
-msgstr "Esta cuenta es un perfil personal corriente"
+#: mod/install.php:265
+msgid "Database Name"
+msgstr "Nombre de la base de datos"
 
-#: mod/settings.php:1112
-msgid "Organisation Page"
-msgstr "Página de organización"
+#: mod/install.php:266 mod/install.php:307
+msgid "Site administrator email address"
+msgstr "Dirección de correo del administrador de la web"
 
-#: mod/settings.php:1113
-msgid "This account is a profile for an organisation"
-msgstr "Esta cuenta es un perfil de una organización"
+#: mod/install.php:266 mod/install.php:307
+msgid ""
+"Your account email address must match this in order to use the web admin "
+"panel."
+msgstr "La dirección de correo de tu cuenta debe coincidir con esta para poder usar el panel de administración de la web."
 
-#: mod/settings.php:1116
-msgid "News Page"
-msgstr "Página de noticias"
+#: mod/install.php:270 mod/install.php:310
+msgid "Please select a default timezone for your website"
+msgstr "Por favor, selecciona la zona horaria predeterminada para tu web"
+
+#: mod/install.php:297
+msgid "Site settings"
+msgstr "Configuración de la página web"
 
-#: mod/settings.php:1117
-msgid "This account is a news account/reflector"
-msgstr "Esta cuenta es una cuenta de noticias/reflectora"
+#: mod/install.php:311
+msgid "System Language:"
+msgstr "Sistema de idioma:"
 
-#: mod/settings.php:1120
-msgid "Community Forum"
-msgstr "Foro de la comunidad"
+#: mod/install.php:311
+msgid ""
+"Set the default language for your Friendica installation interface and to "
+"send emails."
+msgstr "Seleccione el idioma por defecto para su interfaz de instalación de Friendica y para enviar emails."
+
+#: mod/install.php:351
+msgid "Could not find a command line version of PHP in the web server PATH."
+msgstr "No se pudo encontrar una versión de la línea de comandos de PHP en la ruta del servidor web."
 
-#: mod/settings.php:1121
+#: mod/install.php:352
 msgid ""
-"This account is a community forum where people can discuss with each other"
-msgstr "Esta cuenta es un foro de comunidad donde la gente puede debatir con otros"
+"If you don't have a command line version of PHP installed on server, you "
+"will not be able to run background polling via cron. See <a "
+"href='https://github.com/friendica/friendica/blob/master/doc/Install.md#set-"
+"up-the-poller'>'Setup the poller'</a>"
+msgstr "Si no tienes una versión de command line de php installado en el servidor, no sera posible de efectuar polling como trabajo de fondo a traves de cron. Vea <a href='https://github.com/friendica/friendica/blob/master/doc/Install.md#set-up-the-poller'>'Setup the poller'</a>"
 
-#: mod/settings.php:1124
-msgid "Normal Account Page"
-msgstr "Página de cuenta normal"
+#: mod/install.php:356
+msgid "PHP executable path"
+msgstr "Dirección al ejecutable PHP"
 
-#: mod/settings.php:1125
-msgid "This account is a normal personal profile"
-msgstr "Esta cuenta es el perfil personal normal"
+#: mod/install.php:356
+msgid ""
+"Enter full path to php executable. You can leave this blank to continue the "
+"installation."
+msgstr "Introduce la ruta completa al ejecutable php. Puedes dejarlo en blanco y seguir con la instalación."
 
-#: mod/settings.php:1128
-msgid "Soapbox Page"
-msgstr "Página de tribuna"
+#: mod/install.php:361
+msgid "Command line PHP"
+msgstr "Línea de comandos PHP"
 
-#: mod/settings.php:1129
-msgid "Automatically approve all connection/friend requests as read-only fans"
-msgstr "Acepta automáticamente todas las peticiones de conexión/amistad como seguidores de solo-lectura"
+#: mod/install.php:370
+msgid "PHP executable is not the php cli binary (could be cgi-fgci version)"
+msgstr "El ejecutable PHP no es e lphp cli binary (podria ser versión cgi-fgci)"
 
-#: mod/settings.php:1132
-msgid "Public Forum"
-msgstr "Foro público"
+#: mod/install.php:371
+msgid "Found PHP version: "
+msgstr "Versión PHP encontrada:"
 
-#: mod/settings.php:1133
-msgid "Automatically approve all contact requests"
-msgstr "Aprovar autimáticamente todas las solicitudes de contacto"
+#: mod/install.php:373
+msgid "PHP cli binary"
+msgstr "PHP cli binario"
 
-#: mod/settings.php:1136
-msgid "Automatic Friend Page"
-msgstr "Página de Amistad autómatica"
+#: mod/install.php:384
+msgid ""
+"The command line version of PHP on your system does not have "
+"\"register_argc_argv\" enabled."
+msgstr "La versión en línea de comandos de PHP en tu sistema no tiene \"register_argc_argv\" habilitado."
 
-#: mod/settings.php:1137
-msgid "Automatically approve all connection/friend requests as friends"
-msgstr "Aceptar automáticamente todas las solicitudes de conexión/amistad como amigos"
+#: mod/install.php:385
+msgid "This is required for message delivery to work."
+msgstr "Esto es necesario para que funcione la entrega de mensajes."
 
-#: mod/settings.php:1140
-msgid "Private Forum [Experimental]"
-msgstr "Foro privado [Experimental]"
+#: mod/install.php:387
+msgid "PHP register_argc_argv"
+msgstr "PHP register_argc_argv"
 
-#: mod/settings.php:1141
-msgid "Private forum - approved members only"
-msgstr "Foro privado - solo miembros"
+#: mod/install.php:410
+msgid ""
+"Error: the \"openssl_pkey_new\" function on this system is not able to "
+"generate encryption keys"
+msgstr "Error:  La función \"openssl_pkey_new\" en este sistema no es capaz de generar claves de cifrado"
 
-#: mod/settings.php:1153
-msgid "OpenID:"
-msgstr "OpenID:"
+#: mod/install.php:411
+msgid ""
+"If running under Windows, please see "
+"\"http://www.php.net/manual/en/openssl.installation.php\"."
+msgstr "Si se ejecuta en Windows, por favor consulta la sección \"http://www.php.net/manual/en/openssl.installation.php\"."
 
-#: mod/settings.php:1153
-msgid "(Optional) Allow this OpenID to login to this account."
-msgstr "(Opcional) Permitir a este OpenID acceder a esta cuenta."
+#: mod/install.php:413
+msgid "Generate encryption keys"
+msgstr "Generar claves de encriptación"
 
-#: mod/settings.php:1163
-msgid "Publish your default profile in your local site directory?"
-msgstr "¿Quieres publicar tu perfil predeterminado en el directorio local del sitio?"
+#: mod/install.php:420
+msgid "libCurl PHP module"
+msgstr "Módulo PHP libCurl"
 
-#: mod/settings.php:1169
-msgid "Publish your default profile in the global social directory?"
-msgstr "¿Quieres publicar tu perfil predeterminado en el directorio social de forma global?"
+#: mod/install.php:421
+msgid "GD graphics PHP module"
+msgstr "Módulo PHP gráficos GD"
 
-#: mod/settings.php:1177
-msgid "Hide your contact/friend list from viewers of your default profile?"
-msgstr "¿Quieres ocultar tu lista de contactos/amigos en la vista de tu perfil predeterminado?"
+#: mod/install.php:422
+msgid "OpenSSL PHP module"
+msgstr "Módulo PHP OpenSSL"
 
-#: mod/settings.php:1181
-msgid ""
-"If enabled, posting public messages to Diaspora and other networks isn't "
-"possible."
-msgstr "Si habilitado, enviar temas públicos a  a Diaspora* y otras redes no es posible. "
+#: mod/install.php:423
+msgid "mysqli PHP module"
+msgstr "Módulo PHP mysqli"
 
-#: mod/settings.php:1186
-msgid "Allow friends to post to your profile page?"
-msgstr "¿Permites que tus amigos publiquen en tu página de perfil?"
+#: mod/install.php:424
+msgid "mb_string PHP module"
+msgstr "Módulo PHP mb_string"
 
-#: mod/settings.php:1192
-msgid "Allow friends to tag your posts?"
-msgstr "¿Permites a los amigos etiquetar tus publicaciones?"
+#: mod/install.php:425
+msgid "mcrypt PHP module"
+msgstr "modulo mycrypt PHP"
 
-#: mod/settings.php:1198
-msgid "Allow us to suggest you as a potential friend to new members?"
-msgstr "¿Nos permite recomendarte como amigo potencial a los nuevos miembros?"
+#: mod/install.php:426
+msgid "XML PHP module"
+msgstr "Módulo XML PHP"
 
-#: mod/settings.php:1204
-msgid "Permit unknown people to send you private mail?"
-msgstr "¿Permites que desconocidos te manden correos privados?"
+#: mod/install.php:427
+msgid "iconv module"
+msgstr "Módulo iconv"
 
-#: mod/settings.php:1212
-msgid "Profile is <strong>not published</strong>."
-msgstr "El perfil <strong>no está publicado</strong>."
+#: mod/install.php:431 mod/install.php:433
+msgid "Apache mod_rewrite module"
+msgstr "Módulo mod_rewrite de Apache"
 
-#: mod/settings.php:1220
-#, php-format
-msgid "Your Identity Address is <strong>'%s'</strong> or '%s'."
-msgstr "Su dirección de identidad es <strong>'%s'</strong> o '%s'."
+#: mod/install.php:431
+msgid ""
+"Error: Apache webserver mod-rewrite module is required but not installed."
+msgstr "Error: El módulo de Apache mod-rewrite es necesario pero no está instalado."
 
-#: mod/settings.php:1227
-msgid "Automatically expire posts after this many days:"
-msgstr "Las publicaciones expirarán automáticamente después de estos días:"
+#: mod/install.php:439
+msgid "Error: libCURL PHP module required but not installed."
+msgstr "Error: El módulo de PHP libcurl es necesario, pero no está instalado."
 
-#: mod/settings.php:1227
-msgid "If empty, posts will not expire. Expired posts will be deleted"
-msgstr "Si lo dejas vacío no expirarán nunca. Las publicaciones que hayan expirado se borrarán"
+#: mod/install.php:443
+msgid ""
+"Error: GD graphics PHP module with JPEG support required but not installed."
+msgstr "Error: El módulo de de PHP gráficos GD con soporte JPEG es necesario, pero no está instalado."
 
-#: mod/settings.php:1228
-msgid "Advanced expiration settings"
-msgstr "Configuración avanzada de expiración"
+#: mod/install.php:447
+msgid "Error: openssl PHP module required but not installed."
+msgstr "Error: El módulo de PHP openssl es necesario, pero  no está instalado."
 
-#: mod/settings.php:1229
-msgid "Advanced Expiration"
-msgstr "Expiración avanzada"
+#: mod/install.php:451
+msgid "Error: mysqli PHP module required but not installed."
+msgstr "Error: El módulo de PHP mysqli es necesario, pero no está instalado."
 
-#: mod/settings.php:1230
-msgid "Expire posts:"
-msgstr "¿Expiran las publicaciones?"
+#: mod/install.php:455
+msgid "Error: mb_string PHP module required but not installed."
+msgstr "Error: El módulo de PHP mb_string es necesario, pero no está instalado."
 
-#: mod/settings.php:1231
-msgid "Expire personal notes:"
-msgstr "¿Expiran las notas personales?"
+#: mod/install.php:459
+msgid "Error: mcrypt PHP module required but not installed."
+msgstr "Error: modulo mycrypt PHP requerido pero no instalado."
 
-#: mod/settings.php:1232
-msgid "Expire starred posts:"
-msgstr "¿Expiran los favoritos?"
+#: mod/install.php:463
+msgid "Error: iconv PHP module required but not installed."
+msgstr "Error: módulo iconv PHP requerido pero no instalado."
 
-#: mod/settings.php:1233
-msgid "Expire photos:"
-msgstr "¿Expiran las fotografías?"
+#: mod/install.php:472
+msgid ""
+"If you are using php_cli, please make sure that mcrypt module is enabled in "
+"its config file"
+msgstr "Si está utilizando php_cli, por favor asegúrese de que el módulo mcrypt está habilitado en este archivo de configuración"
 
-#: mod/settings.php:1234
-msgid "Only expire posts by others:"
-msgstr "Solo expiran los mensajes de los demás:"
+#: mod/install.php:475
+msgid ""
+"Function mcrypt_create_iv() is not defined. This is needed to enable RINO2 "
+"encryption layer."
+msgstr "Función mycrypt_create_iv() no esta definido. Esto es preciso para habilitar RINO2 encryption layer."
 
-#: mod/settings.php:1262
-msgid "Account Settings"
-msgstr "Configuración de la cuenta"
+#: mod/install.php:477
+msgid "mcrypt_create_iv() function"
+msgstr "mcrypt_create_iv() función"
 
-#: mod/settings.php:1270
-msgid "Password Settings"
-msgstr "Configuración de la contraseña"
+#: mod/install.php:485
+msgid "Error, XML PHP module required but not installed."
+msgstr "Error, módulo XML PHP requerido pero no instalado."
 
-#: mod/settings.php:1272
-msgid "Leave password fields blank unless changing"
-msgstr "Deja la contraseña en blanco si no quieres cambiarla"
+#: mod/install.php:500
+msgid ""
+"The web installer needs to be able to create a file called \".htconfig.php\""
+" in the top folder of your web server and it is unable to do so."
+msgstr "El programa de instalación web necesita ser capaz de crear un archivo llamado \".htconfig.php\" en la carpeta principal de tu servidor web y es incapaz de hacerlo."
 
-#: mod/settings.php:1273
-msgid "Current Password:"
-msgstr "Contraseña actual:"
+#: mod/install.php:501
+msgid ""
+"This is most often a permission setting, as the web server may not be able "
+"to write files in your folder - even if you can."
+msgstr "Se trata a menudo de una configuración de permisos, pues el servidor web puede que no sea capaz de escribir archivos en la carpeta, aunque tú sí puedas."
 
-#: mod/settings.php:1273 mod/settings.php:1274
-msgid "Your current password to confirm the changes"
-msgstr "Su contraseña actual para confirmar los cambios."
+#: mod/install.php:502
+msgid ""
+"At the end of this procedure, we will give you a text to save in a file "
+"named .htconfig.php in your Friendica top folder."
+msgstr "Al final obtendremos un texto que debes guardar en un archivo llamado .htconfig.php en la carpeta de Friendica."
 
-#: mod/settings.php:1274
-msgid "Password:"
-msgstr "Contraseña:"
+#: mod/install.php:503
+msgid ""
+"You can alternatively skip this procedure and perform a manual installation."
+" Please see the file \"INSTALL.txt\" for instructions."
+msgstr "Como alternativa, puedes saltarte estos pasos y realizar una instalación manual. Por favor, consulta el archivo \"INSTALL.txt\" para las instrucciones."
 
-#: mod/settings.php:1278
-msgid "Basic Settings"
-msgstr "Configuración básica"
+#: mod/install.php:506
+msgid ".htconfig.php is writable"
+msgstr ".htconfig.php tiene permiso de escritura"
 
-#: mod/settings.php:1280
-msgid "Email Address:"
-msgstr "Dirección de correo:"
+#: mod/install.php:516
+msgid ""
+"Friendica uses the Smarty3 template engine to render its web views. Smarty3 "
+"compiles templates to PHP to speed up rendering."
+msgstr "Friendica usa el motor de templates Smarty3 para renderizar su visualisacion web. Smarty3 compila templates hacia PHP para acelerar la velocidad del renderizar."
 
-#: mod/settings.php:1281
-msgid "Your Timezone:"
-msgstr "Zona horaria:"
+#: mod/install.php:517
+msgid ""
+"In order to store these compiled templates, the web server needs to have "
+"write access to the directory view/smarty3/ under the Friendica top level "
+"folder."
+msgstr "Para poder guardar estos templates compilados, el servidor web necesita acceso de escritura en el directorio /view/smarty3/ en el árbol de raíz de la instalación friendica."
 
-#: mod/settings.php:1282
-msgid "Your Language:"
-msgstr "Tu idioma:"
+#: mod/install.php:518
+msgid ""
+"Please ensure that the user that your web server runs as (e.g. www-data) has"
+" write access to this folder."
+msgstr "Por favor asegure que el usuario que utiliza el servidor web (ejemplo: www-data) tiene permisos de escritura en esta carpeta."
 
-#: mod/settings.php:1282
+#: mod/install.php:519
 msgid ""
-"Set the language we use to show you friendica interface and to send you "
-"emails"
-msgstr "Selecciona el idioma que se usara para la interfaz del usuario y para el envío de correo."
+"Note: as a security measure, you should give the web server write access to "
+"view/smarty3/ only--not the template files (.tpl) that it contains."
+msgstr "Nota: como medida de seguridad deberia dar acceso de escritura solo a /view/smarty3 / → no al los archivos template (.tpl) que contiene."
 
-#: mod/settings.php:1283
-msgid "Default Post Location:"
-msgstr "Localización predeterminada:"
+#: mod/install.php:522
+msgid "view/smarty3 is writable"
+msgstr "Se puede escribir en /view/smarty3"
 
-#: mod/settings.php:1284
-msgid "Use Browser Location:"
-msgstr "Usar localización del navegador:"
+#: mod/install.php:538
+msgid ""
+"Url rewrite in .htaccess is not working. Check your server configuration."
+msgstr "La reescritura de la dirección en .htaccess no funcionó. Revisa la configuración."
 
-#: mod/settings.php:1287
-msgid "Security and Privacy Settings"
-msgstr "Configuración de seguridad y privacidad"
+#: mod/install.php:540
+msgid "Url rewrite is working"
+msgstr "Reescribiendo la dirección..."
 
-#: mod/settings.php:1289
-msgid "Maximum Friend Requests/Day:"
-msgstr "Máximo número de peticiones de amistad por día:"
+#: mod/install.php:559
+msgid "ImageMagick PHP extension is not installed"
+msgstr "No está instalada la extensión ImageMagick PHP"
 
-#: mod/settings.php:1289 mod/settings.php:1319
-msgid "(to prevent spam abuse)"
-msgstr "(para prevenir el abuso de spam)"
+#: mod/install.php:561
+msgid "ImageMagick PHP extension is installed"
+msgstr "ImageMagick PHP extension is installed"
 
-#: mod/settings.php:1290
-msgid "Default Post Permissions"
-msgstr "Permisos por defecto para las publicaciones"
+#: mod/install.php:563
+msgid "ImageMagick supports GIF"
+msgstr "ImageMagick supporta GIF"
 
-#: mod/settings.php:1291
-msgid "(click to open/close)"
-msgstr "(pulsa para abrir/cerrar)"
+#: mod/install.php:570
+msgid ""
+"The database configuration file \".htconfig.php\" could not be written. "
+"Please use the enclosed text to create a configuration file in your web "
+"server root."
+msgstr "El archivo de configuración de base de datos \".htconfig.php\" no se pudo escribir. Por favor, utiliza el texto adjunto para crear un archivo de configuración en la raíz de tu servidor web."
 
-#: mod/settings.php:1302
-msgid "Default Private Post"
-msgstr "Publicación Privada por defecto"
+#: mod/install.php:607
+msgid "<h1>What next</h1>"
+msgstr "<h1>¿Ahora qué?</h1>"
 
-#: mod/settings.php:1303
-msgid "Default Public Post"
-msgstr "Publicación Pública por defecto"
+#: mod/install.php:608
+msgid ""
+"IMPORTANT: You will need to [manually] setup a scheduled task for the "
+"poller."
+msgstr "IMPORTANTE: Tendrás que configurar [manualmente] una tarea programada para el sondeo"
 
-#: mod/settings.php:1307
-msgid "Default Permissions for New Posts"
-msgstr "Permisos por defecto para nuevas publicaciones"
+#: mod/invite.php:28
+msgid "Total invitation limit exceeded."
+msgstr "Límite total de invitaciones excedido."
 
-#: mod/settings.php:1319
-msgid "Maximum private messages per day from unknown people:"
-msgstr "Número máximo de mensajes diarios para desconocidos:"
+#: mod/invite.php:51
+#, php-format
+msgid "%s : Not a valid email address."
+msgstr "%s : No es una dirección de correo válida."
 
-#: mod/settings.php:1322
-msgid "Notification Settings"
-msgstr "Configuración de notificaciones"
+#: mod/invite.php:76
+msgid "Please join us on Friendica"
+msgstr "Únete a nosotros en Friendica"
 
-#: mod/settings.php:1323
-msgid "By default post a status message when:"
-msgstr "Publicar en tu estado cuando:"
+#: mod/invite.php:87
+msgid "Invitation limit exceeded. Please contact your site administrator."
+msgstr "Límite de invitaciones sobrepasado. Contacta con el administrador del sitio."
 
-#: mod/settings.php:1324
-msgid "accepting a friend request"
-msgstr "aceptes una solicitud de amistad"
+#: mod/invite.php:91
+#, php-format
+msgid "%s : Message delivery failed."
+msgstr "%s : Ha fallado la entrega del mensaje."
 
-#: mod/settings.php:1325
-msgid "joining a forum/community"
-msgstr "te unas a un foro/comunidad"
+#: mod/invite.php:95
+#, php-format
+msgid "%d message sent."
+msgid_plural "%d messages sent."
+msgstr[0] "%d mensaje enviado."
+msgstr[1] "%d mensajes enviados."
 
-#: mod/settings.php:1326
-msgid "making an <em>interesting</em> profile change"
-msgstr "hagas un cambio <em>interesante</em> en tu perfil"
+#: mod/invite.php:114
+msgid "You have no more invitations available"
+msgstr "No tienes más invitaciones disponibles"
 
-#: mod/settings.php:1327
-msgid "Send a notification email when:"
-msgstr "Enviar notificación por correo cuando:"
+#: mod/invite.php:122
+#, php-format
+msgid ""
+"Visit %s for a list of public sites that you can join. Friendica members on "
+"other sites can all connect with each other, as well as with members of many"
+" other social networks."
+msgstr "Visita %s para ver una lista de servidores públicos donde puedes darte de alta. Los miembros de otros servidores de Friendica pueden conectarse entre ellos, así como con miembros de otras redes sociales diferentes."
 
-#: mod/settings.php:1328
-msgid "You receive an introduction"
-msgstr "Recibas una presentación"
+#: mod/invite.php:124
+#, php-format
+msgid ""
+"To accept this invitation, please visit and register at %s or any other "
+"public Friendica website."
+msgstr "Para aceptar la invitación visita y regístrate en %s o en cualquier otro servidor público de Friendica."
 
-#: mod/settings.php:1329
-msgid "Your introductions are confirmed"
-msgstr "Tu presentación sea confirmada"
+#: mod/invite.php:125
+#, php-format
+msgid ""
+"Friendica sites all inter-connect to create a huge privacy-enhanced social "
+"web that is owned and controlled by its members. They can also connect with "
+"many traditional social networks. See %s for a list of alternate Friendica "
+"sites you can join."
+msgstr "Los servidores de Friendica están interconectados para crear una enorme red social centrada en la privacidad y controlada por sus miembros. También se puede conectar con muchas redes sociales tradicionales. Mira en %s para poder ver un listado de servidores alternativos de Friendica donde puedes darte de alta."
 
-#: mod/settings.php:1330
-msgid "Someone writes on your profile wall"
-msgstr "Alguien escriba en el muro de mi perfil"
+#: mod/invite.php:128
+msgid ""
+"Our apologies. This system is not currently configured to connect with other"
+" public sites or invite members."
+msgstr "Discúlpanos. Este sistema no está configurado actualmente para conectar con otros servidores públicos o invitar nuevos miembros."
 
-#: mod/settings.php:1331
-msgid "Someone writes a followup comment"
-msgstr "Algien escriba en un comentario que sigo"
+#: mod/invite.php:134
+msgid "Send invitations"
+msgstr "Enviar invitaciones"
 
-#: mod/settings.php:1332
-msgid "You receive a private message"
-msgstr "Recibas un mensaje privado"
+#: mod/invite.php:135
+msgid "Enter email addresses, one per line:"
+msgstr "Introduce las direcciones de correo, una por línea:"
 
-#: mod/settings.php:1333
-msgid "You receive a friend suggestion"
-msgstr "Recibas una sugerencia de amistad"
+#: mod/invite.php:136 mod/message.php:332 mod/message.php:515
+#: mod/wallmessage.php:135
+msgid "Your message:"
+msgstr "Tu mensaje:"
 
-#: mod/settings.php:1334
-msgid "You are tagged in a post"
-msgstr "Seas etiquetado en una publicación"
+#: mod/invite.php:137
+msgid ""
+"You are cordially invited to join me and other close friends on Friendica - "
+"and help us to create a better social web."
+msgstr "Estás cordialmente invitado a unirte a mi y a otros amigos en Friendica, creemos juntos una red social mejor."
 
-#: mod/settings.php:1335
-msgid "You are poked/prodded/etc. in a post"
-msgstr "Te han tocado/empujado/etc. en una publicación"
+#: mod/invite.php:139
+msgid "You will need to supply this invitation code: $invite_code"
+msgstr "Tienes que proporcionar el siguiente código: $invite_code"
 
-#: mod/settings.php:1337
-msgid "Activate desktop notifications"
-msgstr "Activar notificaciones en pantalla."
+#: mod/invite.php:139
+msgid ""
+"Once you have registered, please connect with me via my profile page at:"
+msgstr "Una vez registrado, por favor contacta conmigo a través de mi página de perfil en:"
 
-#: mod/settings.php:1337
-msgid "Show desktop popup on new notifications"
-msgstr "Mostrar notificaciones emergentes en caso de nuevos eventos."
+#: mod/invite.php:141
+msgid ""
+"For more information about the Friendica project and why we feel it is "
+"important, please visit http://friendica.com"
+msgstr "Para más información sobre el Proyecto Friendica y sobre por qué pensamos que es algo importante, visita http://friendica.com"
 
-#: mod/settings.php:1339
-msgid "Text-only notification emails"
-msgstr "Notificaciones e-mail de solo texto"
+#: mod/item.php:118
+msgid "Unable to locate original post."
+msgstr "No se puede encontrar la publicación original."
 
-#: mod/settings.php:1341
-msgid "Send text only notification emails, without the html part"
-msgstr "Enviar las notificaciones por correo con formato de solo texto sin html."
+#: mod/item.php:336
+msgid "Empty post discarded."
+msgstr "Publicación vacía descartada."
 
-#: mod/settings.php:1343
-msgid "Advanced Account/Page Type Settings"
-msgstr "Configuración avanzada de tipo de Cuenta/Página"
+#: mod/item.php:889
+msgid "System error. Post not saved."
+msgstr "Error del sistema. Mensaje no guardado."
 
-#: mod/settings.php:1344
-msgid "Change the behaviour of this account for special situations"
-msgstr "Cambiar el comportamiento de esta cuenta para situaciones especiales"
+#: mod/item.php:979
+#, php-format
+msgid ""
+"This message was sent to you by %s, a member of the Friendica social "
+"network."
+msgstr "Este mensaje te lo ha enviado %s, miembro de la red social Friendica."
 
-#: mod/settings.php:1347
-msgid "Relocate"
-msgstr "Relocalizar"
+#: mod/item.php:981
+#, php-format
+msgid "You may visit them online at %s"
+msgstr "Los puedes visitar en línea en %s"
 
-#: mod/settings.php:1348
+#: mod/item.php:982
 msgid ""
-"If you have moved this profile from another server, and some of your "
-"contacts don't receive your updates, try pushing this button."
-msgstr "Si ha migrado este perfil desde otro servidor aquí y algunos contactos no reciben sus publicaciones intente  recomunicar su ubicación a traves este botón. (Como para decir el botón de los botones)"
+"Please contact the sender by replying to this post if you do not wish to "
+"receive these messages."
+msgstr "Por favor contacta con el remitente respondiendo a este mensaje si no deseas recibir estos mensajes."
 
-#: mod/settings.php:1349
-msgid "Resend relocate message to contacts"
-msgstr "Reenviar mensaje de relocalización a los contactos"
+#: mod/item.php:986
+#, php-format
+msgid "%s posted an update."
+msgstr "%s ha publicado una actualización."
 
-#: mod/videos.php:120
-msgid "Do you really want to delete this video?"
-msgstr "Realmente quieres eliminar este vídeo?"
+#: mod/localtime.php:24
+msgid "Time Conversion"
+msgstr "Conversión horária"
 
-#: mod/videos.php:125
-msgid "Delete Video"
-msgstr "Borrar vídeo"
+#: mod/localtime.php:26
+msgid ""
+"Friendica provides this service for sharing events with other networks and "
+"friends in unknown timezones."
+msgstr "Friendica ofrece este servicio para compartir eventos con otros servidores de la red friendica y amigos en zonas de horarios desconocidos."
 
-#: mod/videos.php:204
-msgid "No videos selected"
-msgstr "Ningún vídeo seleccionado"
+#: mod/localtime.php:30
+#, php-format
+msgid "UTC time: %s"
+msgstr "Tiempo UTC: %s"
 
-#: mod/videos.php:396
-msgid "Recent Videos"
-msgstr "Vídeos recientes"
+#: mod/localtime.php:33
+#, php-format
+msgid "Current timezone: %s"
+msgstr "Zona horaria actual: %s"
 
-#: mod/videos.php:398
-msgid "Upload New Videos"
-msgstr "Subir nuevos vídeos"
+#: mod/localtime.php:36
+#, php-format
+msgid "Converted localtime: %s"
+msgstr "Zona horaria local convertida: %s"
 
-#: mod/wall_attach.php:17 mod/wall_attach.php:25 mod/wall_attach.php:76
-#: mod/wall_upload.php:20 mod/wall_upload.php:33 mod/wall_upload.php:86
-#: mod/wall_upload.php:122 mod/wall_upload.php:125
-msgid "Invalid request."
-msgstr "Consulta invalida"
+#: mod/localtime.php:41
+msgid "Please select your timezone:"
+msgstr "Por favor, selecciona tu zona horaria:"
 
-#: mod/wall_attach.php:94
-msgid "Sorry, maybe your upload is bigger than the PHP configuration allows"
-msgstr "Disculpa, posiblemente el archivo subido es mas grande que la PHP configuración permite."
+#: mod/lockview.php:32 mod/lockview.php:40
+msgid "Remote privacy information not available."
+msgstr "Privacidad de la información remota no disponible."
 
-#: mod/wall_attach.php:94
-msgid "Or - did you try to upload an empty file?"
-msgstr "Si no - intento de subir un archivo vacío?"
+#: mod/lockview.php:49
+msgid "Visible to:"
+msgstr "Visible para:"
 
-#: mod/wall_attach.php:105
-#, php-format
-msgid "File exceeds size limit of %s"
-msgstr "El archivo excede el limite de tamaño de %s"
+#: mod/lostpass.php:19
+msgid "No valid account found."
+msgstr "No se ha encontrado ninguna cuenta válida"
 
-#: mod/wall_attach.php:156 mod/wall_attach.php:172
-msgid "File upload failed."
-msgstr "Ha fallado la subida del archivo."
+#: mod/lostpass.php:35
+msgid "Password reset request issued. Check your email."
+msgstr "Solicitud de restablecimiento de contraseña enviada. Revisa tu correo."
+
+#: mod/lostpass.php:41
+#, php-format
+msgid ""
+"\n"
+"\t\tDear %1$s,\n"
+"\t\t\tA request was recently received at \"%2$s\" to reset your account\n"
+"\t\tpassword. In order to confirm this request, please select the verification link\n"
+"\t\tbelow or paste it into your web browser address bar.\n"
+"\n"
+"\t\tIf you did NOT request this change, please DO NOT follow the link\n"
+"\t\tprovided and ignore and/or delete this email.\n"
+"\n"
+"\t\tYour password will not be changed unless we can verify that you\n"
+"\t\tissued this request."
+msgstr "\n\t\tEstimado %1$s,\n\t\t\tUna consulta llego recientemente a \"%2$s\" para renovar su\n\t\tcontraseña. Para confirmar esta solicitud por favor seleccione el enlace de verificación mas \n\t\tabajo o copie a pegue el mismo en la barra de dirección de su navegador.\n\n\t\tSi NO ha solicitado este cambio por favor NO SIGA este enlace\n\t\tproporcionado y ignore o borre este mail.\n\n\t\tSu contraseña no sera cambiada hasta que podamos verificar que usted haza\n\t\tsolicitado este cambio.."
 
-#: mod/admin.php:92
-msgid "Theme settings updated."
-msgstr "Configuración de la apariencia actualizada."
+#: mod/lostpass.php:52
+#, php-format
+msgid ""
+"\n"
+"\t\tFollow this link to verify your identity:\n"
+"\n"
+"\t\t%1$s\n"
+"\n"
+"\t\tYou will then receive a follow-up message containing the new password.\n"
+"\t\tYou may change that password from your account settings page after logging in.\n"
+"\n"
+"\t\tThe login details are as follows:\n"
+"\n"
+"\t\tSite Location:\t%2$s\n"
+"\t\tLogin Name:\t%3$s"
+msgstr "\n\t\tSiga este enlace para verificar su identidad:\n\n\t\t%1$s\n\n\t\tA continuación recibirá un mensaje consecutivo conteniendo la nueva contraseña.\n\t\tPodrá cambiar la contraseña después de haber accedido a la cuenta.\n\n\t\tLos detalles del acceso son las siguientes:\n\n\t\tDirección del sitio:\t%2$s\n\t\tNombre de la cuenta:\t%3$s"
 
-#: mod/admin.php:156 mod/admin.php:954
-msgid "Site"
-msgstr "Sitio"
+#: mod/lostpass.php:71
+#, php-format
+msgid "Password reset requested at %s"
+msgstr "Contraseña restablecida enviada a %s"
 
-#: mod/admin.php:157 mod/admin.php:898 mod/admin.php:1404 mod/admin.php:1420
-msgid "Users"
-msgstr "Usuarios"
+#: mod/lostpass.php:91
+msgid ""
+"Request could not be verified. (You may have previously submitted it.) "
+"Password reset failed."
+msgstr "La solicitud no puede ser verificada (deberías haberla proporcionado antes). Falló el restablecimiento de la contraseña."
 
-#: mod/admin.php:159 mod/admin.php:1780 mod/admin.php:1830
-msgid "Themes"
-msgstr "Temas"
+#: mod/lostpass.php:111
+msgid "Your password has been reset as requested."
+msgstr "Tu contraseña ha sido restablecida como solicitaste."
 
-#: mod/admin.php:161
-msgid "DB updates"
-msgstr "Actualizaciones de la Base de Datos"
+#: mod/lostpass.php:112
+msgid "Your new password is"
+msgstr "Tu nueva contraseña es"
 
-#: mod/admin.php:162 mod/admin.php:406
-msgid "Inspect Queue"
-msgstr "Inspeccionar cola"
+#: mod/lostpass.php:113
+msgid "Save or copy your new password - and then"
+msgstr "Guarda o copia tu nueva contraseña y luego"
 
-#: mod/admin.php:163 mod/admin.php:372
-msgid "Federation Statistics"
-msgstr "Estadísticas de federación"
+#: mod/lostpass.php:114
+msgid "click here to login"
+msgstr "pulsa aquí para acceder"
 
-#: mod/admin.php:177 mod/admin.php:188 mod/admin.php:1904
-msgid "Logs"
-msgstr "Registros"
+#: mod/lostpass.php:115
+msgid ""
+"Your password may be changed from the <em>Settings</em> page after "
+"successful login."
+msgstr "Puedes cambiar tu contraseña desde la página de <em>Configuración</em> después de acceder con éxito."
 
-#: mod/admin.php:178 mod/admin.php:1972
-msgid "View Logs"
-msgstr "Ver registro de depuración"
+#: mod/lostpass.php:125
+#, php-format
+msgid ""
+"\n"
+"\t\t\t\tDear %1$s,\n"
+"\t\t\t\t\tYour password has been changed as requested. Please retain this\n"
+"\t\t\t\tinformation for your records (or change your password immediately to\n"
+"\t\t\t\tsomething that you will remember).\n"
+"\t\t\t"
+msgstr "\n\t\t\t\tEstimado %1$s,\n\t\t\t\t\tSu contraseña ha cambiado como solicitado. Por favor guarde esta\n\t\t\t\tinformación para sus documentación (o cambie su contraseña inmediatamente a\n\t\t\t\talgo que pueda recordar).\n\t\t"
 
-#: mod/admin.php:179
-msgid "probe address"
-msgstr "probar direccion"
+#: mod/lostpass.php:131
+#, php-format
+msgid ""
+"\n"
+"\t\t\t\tYour login details are as follows:\n"
+"\n"
+"\t\t\t\tSite Location:\t%1$s\n"
+"\t\t\t\tLogin Name:\t%2$s\n"
+"\t\t\t\tPassword:\t%3$s\n"
+"\n"
+"\t\t\t\tYou may change that password from your account settings page after logging in.\n"
+"\t\t\t"
+msgstr "\n\t\t\t\tSus datos de acceso son las siguientes:\n\n\t\t\t\tDirección del sitio:\t%1$s\n\t\t\t\tNombre de cuenta:\t%2$s\n\t\t\t\tContraseña:\t%3$s\n\n\t\t\t\tPodrá cambiar esta contraseña después de ingresar al sitio en su pagina de configuración.\n\t\t\t"
 
-#: mod/admin.php:180
-msgid "check webfinger"
-msgstr "Verificar webfinger"
+#: mod/lostpass.php:147
+#, php-format
+msgid "Your password has been changed at %s"
+msgstr "Tu contraseña se ha cambiado por %s"
 
-#: mod/admin.php:187
-msgid "Plugin Features"
-msgstr "Características del módulo"
+#: mod/lostpass.php:159
+msgid "Forgot your Password?"
+msgstr "¿Olvidaste tu contraseña?"
 
-#: mod/admin.php:189
-msgid "diagnostics"
-msgstr "diagnosticos"
+#: mod/lostpass.php:160
+msgid ""
+"Enter your email address and submit to have your password reset. Then check "
+"your email for further instructions."
+msgstr "Introduce tu correo para restablecer tu contraseña. Luego comprueba tu correo para las instrucciones adicionales."
 
-#: mod/admin.php:190
-msgid "User registrations waiting for confirmation"
-msgstr "Registro de usuarios esperando la confirmación"
+#: mod/lostpass.php:162
+msgid "Reset"
+msgstr "Restablecer"
 
-#: mod/admin.php:306
-msgid "unknown"
-msgstr "desconocido"
+#: mod/maintenance.php:20
+msgid "System down for maintenance"
+msgstr "Servicio suspendido por mantenimiento"
 
-#: mod/admin.php:365
-msgid ""
-"This page offers you some numbers to the known part of the federated social "
-"network your Friendica node is part of. These numbers are not complete but "
-"only reflect the part of the network your node is aware of."
-msgstr "Esta pagina ofrece algunos datos sobre la red conocida a la que tu nodo friendica esta conectado. Estos nummeros no son completos respecto a las redes federadas, si no refleja los nodos esta instancia conoce. "
+#: mod/manage.php:141
+msgid "Manage Identities and/or Pages"
+msgstr "Administrar identidades y/o páginas"
 
-#: mod/admin.php:366
+#: mod/manage.php:142
 msgid ""
-"The <em>Auto Discovered Contact Directory</em> feature is not enabled, it "
-"will improve the data displayed here."
-msgstr "El modulo <em>directorio de contactos encontrados</em> no esta habilitado, habilitado aumentara la cantidad de datos detallados aquí."
+"Toggle between different identities or community/group pages which share "
+"your account details or which you have been granted \"manage\" permissions"
+msgstr "Cambia entre diferentes identidades o páginas de Comunidad/Grupos que comparten los detalles de tu cuenta o sobre los que tienes permisos para administrar"
 
-#: mod/admin.php:371 mod/admin.php:405 mod/admin.php:484 mod/admin.php:953
-#: mod/admin.php:1403 mod/admin.php:1521 mod/admin.php:1581 mod/admin.php:1779
-#: mod/admin.php:1829 mod/admin.php:1903 mod/admin.php:1971
-msgid "Administration"
-msgstr "Administración"
+#: mod/manage.php:143
+msgid "Select an identity to manage: "
+msgstr "Selecciona una identidad a gestionar:"
 
-#: mod/admin.php:378
-#, php-format
-msgid "Currently this node is aware of %d nodes from the following platforms:"
-msgstr "Actualmente este nodo reconoce %d nodos de las siguientes plataformas:"
+#: mod/match.php:35
+msgid "No keywords to match. Please add keywords to your default profile."
+msgstr "No hay palabras clave que coincidan. Por favor, agrega algunas palabras claves en tu perfil predeterminado."
 
-#: mod/admin.php:408
-msgid "ID"
-msgstr "ID"
+#: mod/match.php:88
+msgid "is interested in:"
+msgstr "estás interesado en:"
 
-#: mod/admin.php:409
-msgid "Recipient Name"
-msgstr "Nombre del recipiente"
+#: mod/match.php:102
+msgid "Profile Match"
+msgstr "Coincidencias de Perfil"
 
-#: mod/admin.php:410
-msgid "Recipient Profile"
-msgstr "Perfil del recipiente"
+#: mod/message.php:60 mod/wallmessage.php:50
+msgid "No recipient selected."
+msgstr "Ningún destinatario seleccionado"
 
-#: mod/admin.php:412
-msgid "Created"
-msgstr "Creado"
+#: mod/message.php:64
+msgid "Unable to locate contact information."
+msgstr "No se puede encontrar información del contacto."
 
-#: mod/admin.php:413
-msgid "Last Tried"
-msgstr "Ultimo intento"
+#: mod/message.php:67 mod/wallmessage.php:56
+msgid "Message could not be sent."
+msgstr "El mensaje no ha podido ser enviado."
 
-#: mod/admin.php:414
-msgid ""
-"This page lists the content of the queue for outgoing postings. These are "
-"postings the initial delivery failed for. They will be resend later and "
-"eventually deleted if the delivery fails permanently."
-msgstr "Esta pagina muestra la cola de mensajes salientes. Estos son publicaciones cuyo envío inicial fallo. Serán reenviados mas tarde y eventualmente eliminados si la entrega falla permanentemente. "
+#: mod/message.php:70 mod/wallmessage.php:59
+msgid "Message collection failure."
+msgstr "Fallo en la recolección de mensajes."
 
-#: mod/admin.php:439
-#, php-format
-msgid ""
-"Your DB still runs with MyISAM tables. You should change the engine type to "
-"InnoDB. As Friendica will use InnoDB only features in the future, you should"
-" change this! See <a href=\"%s\">here</a> for a guide that may be helpful "
-"converting the table engines. You may also use the "
-"<tt>convert_innodb.sql</tt> in the <tt>/util</tt> directory of your "
-"Friendica installation.<br />"
-msgstr "Su DB aún funciona con las tablas MyISAM. Debería cambiar el tipo de motror a InnoDB. ¡Como Friendica sólo usará las características de InnoDB en el futuro, debería cambiar esto! Vea <a href=\"%s\">aquí</a> para una guía que puede ayudar a convertir las tablas de motor. También puede usar <tt>convert_innodb.sql</tt> en el directorio <tt>/util</tt> de su instalación de Friendica.<br />"
+#: mod/message.php:73 mod/wallmessage.php:62
+msgid "Message sent."
+msgstr "Mensaje enviado."
 
-#: mod/admin.php:444
-msgid ""
-"You are using a MySQL version which does not support all features that "
-"Friendica uses. You should consider switching to MariaDB."
-msgstr "Está usando una versión de MySQL que no soporta todas las características de Friendica. Debería considerar cambiar a MariaDB."
+#: mod/message.php:204
+msgid "Do you really want to delete this message?"
+msgstr "¿Estás seguro de que quieres borrar este mensaje?"
 
-#: mod/admin.php:448 mod/admin.php:1352
-msgid "Normal Account"
-msgstr "Cuenta normal"
+#: mod/message.php:224
+msgid "Message deleted."
+msgstr "Mensaje eliminado."
 
-#: mod/admin.php:449 mod/admin.php:1353
-msgid "Soapbox Account"
-msgstr "Cuenta tribuna"
+#: mod/message.php:255
+msgid "Conversation removed."
+msgstr "Conversación eliminada."
 
-#: mod/admin.php:450 mod/admin.php:1354
-msgid "Community/Celebrity Account"
-msgstr "Cuenta de Comunidad/Celebridad"
+#: mod/message.php:322 mod/wallmessage.php:126
+msgid "Send Private Message"
+msgstr "Enviar mensaje privado"
 
-#: mod/admin.php:451 mod/admin.php:1355
-msgid "Automatic Friend Account"
-msgstr "Cuenta de amistad automática"
+#: mod/message.php:323 mod/message.php:510 mod/wallmessage.php:128
+msgid "To:"
+msgstr "Para:"
 
-#: mod/admin.php:452
-msgid "Blog Account"
-msgstr "Cuenta de blog"
+#: mod/message.php:328 mod/message.php:512 mod/wallmessage.php:129
+msgid "Subject:"
+msgstr "Asunto:"
 
-#: mod/admin.php:453
-msgid "Private Forum"
-msgstr "Foro privado"
+#: mod/message.php:364
+msgid "No messages."
+msgstr "No hay mensajes."
 
-#: mod/admin.php:479
-msgid "Message queues"
-msgstr "Cola de mensajes"
+#: mod/message.php:403
+msgid "Message not available."
+msgstr "Mensaje no disponibile."
 
-#: mod/admin.php:485
-msgid "Summary"
-msgstr "Resumen"
+#: mod/message.php:477
+msgid "Delete message"
+msgstr "Borrar mensaje"
 
-#: mod/admin.php:488
-msgid "Registered users"
-msgstr "Usuarios registrados"
+#: mod/message.php:503 mod/message.php:583
+msgid "Delete conversation"
+msgstr "Eliminar conversación"
 
-#: mod/admin.php:490
-msgid "Pending registrations"
-msgstr "Pendientes de registro"
+#: mod/message.php:505
+msgid ""
+"No secure communications available. You <strong>may</strong> be able to "
+"respond from the sender's profile page."
+msgstr "No hay comunicaciones seguras disponibles. <strong>Podrías</strong> responder desde la página de perfil del remitente. "
 
-#: mod/admin.php:491
-msgid "Version"
-msgstr "Versión"
+#: mod/message.php:509
+msgid "Send Reply"
+msgstr "Enviar respuesta"
 
-#: mod/admin.php:496
-msgid "Active plugins"
-msgstr "Módulos activos"
+#: mod/message.php:553
+#, php-format
+msgid "Unknown sender - %s"
+msgstr "Remitente desconocido - %s"
 
-#: mod/admin.php:521
-msgid "Can not parse base url. Must have at least <scheme>://<domain>"
-msgstr "No se puede resolver la direccion URL base.\nDeberá tener al menos <scheme>://<domain>"
+#: mod/message.php:555
+#, php-format
+msgid "You and %s"
+msgstr "Tú y %s"
 
-#: mod/admin.php:826
-msgid "RINO2 needs mcrypt php extension to work."
-msgstr "RINO2 precisa la extensión mcrypt para funcionar.  "
+#: mod/message.php:557
+#, php-format
+msgid "%s and You"
+msgstr "%s y Tú"
 
-#: mod/admin.php:834
-msgid "Site settings updated."
-msgstr "Configuración de actualización."
+#: mod/message.php:586
+msgid "D, d M Y - g:i A"
+msgstr "D, d M Y - g:i A"
 
-#: mod/admin.php:881
-msgid "No community page"
-msgstr "No hay pagina de comunidad"
+#: mod/message.php:589
+#, php-format
+msgid "%d message"
+msgid_plural "%d messages"
+msgstr[0] "%d mensaje"
+msgstr[1] "%d mensajes"
 
-#: mod/admin.php:882
-msgid "Public postings from users of this site"
-msgstr "Temas públicos de perfiles de este sitio."
+#: mod/mood.php:134
+msgid "Mood"
+msgstr "Ánimo"
 
-#: mod/admin.php:883
-msgid "Global community page"
-msgstr "Pagina global de comunidad"
+#: mod/mood.php:135
+msgid "Set your current mood and tell your friends"
+msgstr "Coloca tu ánimo actual y cuéntaselo a tus amigos"
 
-#: mod/admin.php:888 mod/contacts.php:530
-msgid "Never"
-msgstr "Nunca"
+#: mod/network.php:190 mod/search.php:25
+msgid "Remove term"
+msgstr "Eliminar término"
 
-#: mod/admin.php:889
-msgid "At post arrival"
-msgstr "A la llegada de una publicación"
+#: mod/network.php:397
+#, php-format
+msgid ""
+"Warning: This group contains %s member from a network that doesn't allow non"
+" public messages."
+msgid_plural ""
+"Warning: This group contains %s members from a network that doesn't allow "
+"non public messages."
+msgstr[0] "Aviso: Este grupo contiene %s miembro de una red que no permite mensajes públicos."
+msgstr[1] "Aviso: Este grupo contiene %s miembros de una red que no permite mensajes públicos."
 
-#: mod/admin.php:897 mod/contacts.php:557
-msgid "Disabled"
-msgstr "Deshabilitado"
+#: mod/network.php:400
+msgid "Messages in this group won't be send to these receivers."
+msgstr "Los mensajes de este grupo no se enviarán a estos receptores."
 
-#: mod/admin.php:899
-msgid "Users, Global Contacts"
-msgstr "Perfiles, contactos globales"
+#: mod/network.php:528
+msgid "Private messages to this person are at risk of public disclosure."
+msgstr "Los mensajes privados a esta persona corren el riesgo de ser mostrados públicamente."
 
-#: mod/admin.php:900
-msgid "Users, Global Contacts/fallback"
-msgstr "Perfiles, contactos globales/fallback"
+#: mod/network.php:533
+msgid "Invalid contact."
+msgstr "Contacto erróneo."
 
-#: mod/admin.php:904
-msgid "One month"
-msgstr "Un mes"
+#: mod/network.php:810
+msgid "Commented Order"
+msgstr "Orden de comentarios"
 
-#: mod/admin.php:905
-msgid "Three months"
-msgstr "Tres meses"
+#: mod/network.php:813
+msgid "Sort by Comment Date"
+msgstr "Ordenar por fecha de comentarios"
 
-#: mod/admin.php:906
-msgid "Half a year"
-msgstr "Medio año"
+#: mod/network.php:818
+msgid "Posted Order"
+msgstr "Orden de publicación"
 
-#: mod/admin.php:907
-msgid "One year"
-msgstr "Un año"
+#: mod/network.php:821
+msgid "Sort by Post Date"
+msgstr "Ordenar por fecha de publicación"
 
-#: mod/admin.php:912
-msgid "Multi user instance"
-msgstr "Sesión multi usuario"
+#: mod/network.php:832
+msgid "Posts that mention or involve you"
+msgstr "Publicaciones que te mencionan o involucran"
 
-#: mod/admin.php:935
-msgid "Closed"
-msgstr "Cerrado"
+#: mod/network.php:840
+msgid "New"
+msgstr "Nuevo"
 
-#: mod/admin.php:936
-msgid "Requires approval"
-msgstr "Requiere aprobación"
+#: mod/network.php:843
+msgid "Activity Stream - by date"
+msgstr "Corriente de actividad por fecha"
 
-#: mod/admin.php:937
-msgid "Open"
-msgstr "Abierto"
+#: mod/network.php:851
+msgid "Shared Links"
+msgstr "Enlaces compartidos"
 
-#: mod/admin.php:941
-msgid "No SSL policy, links will track page SSL state"
-msgstr "No existe una política de SSL, los vínculos harán un seguimiento del estado de SSL en la página"
+#: mod/network.php:854
+msgid "Interesting Links"
+msgstr "Enlaces interesantes"
 
-#: mod/admin.php:942
-msgid "Force all links to use SSL"
-msgstr "Forzar todos los enlaces a utilizar SSL"
+#: mod/network.php:862
+msgid "Starred"
+msgstr "Favoritos"
 
-#: mod/admin.php:943
-msgid "Self-signed certificate, use SSL for local links only (discouraged)"
-msgstr "Certificación personal, usa SSL solo para enlaces locales (no recomendado)"
+#: mod/network.php:865
+msgid "Favourite Posts"
+msgstr "Publicaciones favoritas"
 
-#: mod/admin.php:957
-msgid "File upload"
-msgstr "Subida de archivo"
+#: mod/newmember.php:6
+msgid "Welcome to Friendica"
+msgstr "Bienvenido a Friendica "
 
-#: mod/admin.php:958
-msgid "Policies"
-msgstr "Políticas"
+#: mod/newmember.php:8
+msgid "New Member Checklist"
+msgstr "Listado de nuevos miembros"
 
-#: mod/admin.php:960
-msgid "Auto Discovered Contact Directory"
-msgstr "Directorio de contactos descubierto automáticamente"
+#: mod/newmember.php:12
+msgid ""
+"We would like to offer some tips and links to help make your experience "
+"enjoyable. Click any item to visit the relevant page. A link to this page "
+"will be visible from your home page for two weeks after your initial "
+"registration and then will quietly disappear."
+msgstr "Nos gustaría ofrecerte algunos consejos y enlaces para ayudar a hacer tu experiencia más amena. Pulsa en cualquier elemento para visitar la página correspondiente. Un enlace a esta página será visible desde tu página de inicio durante las dos semanas siguientes a tu inscripción y luego desaparecerá."
 
-#: mod/admin.php:961
-msgid "Performance"
-msgstr "Rendimiento"
+#: mod/newmember.php:14
+msgid "Getting Started"
+msgstr "Empezando"
 
-#: mod/admin.php:962
-msgid "Worker"
-msgstr "Trabajador (??)"
+#: mod/newmember.php:18
+msgid "Friendica Walk-Through"
+msgstr "Visita guiada a Friendica"
 
-#: mod/admin.php:963
+#: mod/newmember.php:18
 msgid ""
-"Relocate - WARNING: advanced function. Could make this server unreachable."
-msgstr "Reubicación - ADVERTENCIA: función avanzada. Puede hacer a este servidor inaccesible. "
+"On your <em>Quick Start</em> page - find a brief introduction to your "
+"profile and network tabs, make some new connections, and find some groups to"
+" join."
+msgstr "En tu página de <em>Inicio Rápido</em> - busca una introducción breve para tus pestañas de perfil y red, haz algunas conexiones nuevas, y busca algunos grupos a los que unirte."
 
-#: mod/admin.php:966
-msgid "Site name"
-msgstr "Nombre del sitio"
+#: mod/newmember.php:26
+msgid "Go to Your Settings"
+msgstr "Ir a tus ajustes"
 
-#: mod/admin.php:967
-msgid "Host name"
-msgstr "Nombre de dominio"
+#: mod/newmember.php:26
+msgid ""
+"On your <em>Settings</em> page -  change your initial password. Also make a "
+"note of your Identity Address. This looks just like an email address - and "
+"will be useful in making friends on the free social web."
+msgstr "En la página de <em>Configuración</em> puedes cambiar tu contraseña inicial. También aparece tu ID (Identity Address). Es parecida a una dirección de correo y te servirá para conectar con gente de redes sociales libres."
 
-#: mod/admin.php:968
-msgid "Sender Email"
-msgstr "Dirección de origen de correo electrónico"
+#: mod/newmember.php:28
+msgid ""
+"Review the other settings, particularly the privacy settings. An unpublished"
+" directory listing is like having an unlisted phone number. In general, you "
+"should probably publish your listing - unless all of your friends and "
+"potential friends know exactly how to find you."
+msgstr "Revisa las otras configuraciones, especialmente la configuración de privacidad. Un listado de directorio sin publicar es como tener un número de teléfono sin publicar. Normalmente querrás publicar tu listado, a menos que tus amigos y amigos potenciales sepan cómo ponerse en contacto contigo."
+
+#: mod/newmember.php:36 mod/profile_photo.php:256 mod/profiles.php:699
+msgid "Upload Profile Photo"
+msgstr "Subir foto del Perfil"
 
-#: mod/admin.php:968
+#: mod/newmember.php:36
 msgid ""
-"The email address your server shall use to send notification emails from."
-msgstr "La dirección de correo electrónico que el servidor debería usar como dirección de envío."
+"Upload a profile photo if you have not done so already. Studies have shown "
+"that people with real photos of themselves are ten times more likely to make"
+" friends than people who do not."
+msgstr "Sube una foto para tu perfil si no lo has hecho aún. Los estudios han demostrado que la gente que usa fotos suyas reales tienen diez veces más éxito a la hora de entablar amistad que las que no."
 
-#: mod/admin.php:969
-msgid "Banner/Logo"
-msgstr "Imagen/Logotipo"
+#: mod/newmember.php:38
+msgid "Edit Your Profile"
+msgstr "Editar tu perfil"
 
-#: mod/admin.php:970
-msgid "Shortcut icon"
-msgstr "Icono de atajo"
+#: mod/newmember.php:38
+msgid ""
+"Edit your <strong>default</strong> profile to your liking. Review the "
+"settings for hiding your list of friends and hiding the profile from unknown"
+" visitors."
+msgstr "Edita tu perfil <strong>predeterminado</strong> como quieras. Revisa la configuración para ocultar tu lista de amigos o tu perfil a los visitantes desconocidos."
 
-#: mod/admin.php:970
-msgid "Link to an icon that will be used for browsers."
-msgstr "Enlace hacia un icono que sera usado para el navegador."
+#: mod/newmember.php:40
+msgid "Profile Keywords"
+msgstr "Palabras clave del perfil"
 
-#: mod/admin.php:971
-msgid "Touch icon"
-msgstr "Icono touch"
+#: mod/newmember.php:40
+msgid ""
+"Set some public keywords for your default profile which describe your "
+"interests. We may be able to find other people with similar interests and "
+"suggest friendships."
+msgstr "Define en tu perfil público algunas palabras que describan tus intereses. Así podremos buscar otras personas con los mismos gustos y sugerirte posibles amigos."
 
-#: mod/admin.php:971
-msgid "Link to an icon that will be used for tablets and mobiles."
-msgstr "Enlace para un icono que sera usado para tablets y moviles."
+#: mod/newmember.php:44
+msgid "Connecting"
+msgstr "Conectando"
 
-#: mod/admin.php:972
-msgid "Additional Info"
-msgstr "Información adicional"
+#: mod/newmember.php:51
+msgid "Importing Emails"
+msgstr "Importando correos electrónicos"
 
-#: mod/admin.php:972
-#, php-format
+#: mod/newmember.php:51
 msgid ""
-"For public servers: you can add additional information here that will be "
-"listed at %s/siteinfo."
-msgstr "Para servidores públicos: información adicional  que sera publicado en %s/siteinfo."
-
-#: mod/admin.php:973
-msgid "System language"
-msgstr "Idioma"
+"Enter your email access information on your Connector Settings page if you "
+"wish to import and interact with friends or mailing lists from your email "
+"INBOX"
+msgstr "Introduce la información para acceder a tu correo en la página de Configuración del conector si quieres importar e interactuar con amigos o listas de correos del buzón de entrada de tu correo electrónico."
 
-#: mod/admin.php:974
-msgid "System theme"
-msgstr "Tema"
+#: mod/newmember.php:53
+msgid "Go to Your Contacts Page"
+msgstr "Ir a tu página de contactos"
 
-#: mod/admin.php:974
+#: mod/newmember.php:53
 msgid ""
-"Default system theme - may be over-ridden by user profiles - <a href='#' "
-"id='cnftheme'>change theme settings</a>"
-msgstr "Tema por defecto del sistema, los usuarios podrán elegir el suyo propio en su configuración <a href='#' id='cnftheme'>cambiar configuración del tema</a>"
+"Your Contacts page is your gateway to managing friendships and connecting "
+"with friends on other networks. Typically you enter their address or site "
+"URL in the <em>Add New Contact</em> dialog."
+msgstr "Tu página de Contactos es el portal desde donde podrás manejar tus amistades y conectarte con amigos de otras redes. Normalmente introduces su dirección o la dirección de su sitio web en el recuadro \"Añadir contacto nuevo\"."
 
-#: mod/admin.php:975
-msgid "Mobile system theme"
-msgstr "Tema de sistema móvil"
+#: mod/newmember.php:55
+msgid "Go to Your Site's Directory"
+msgstr "Ir al directorio de tu sitio"
 
-#: mod/admin.php:975
-msgid "Theme for mobile devices"
-msgstr "Tema para dispositivos móviles"
+#: mod/newmember.php:55
+msgid ""
+"The Directory page lets you find other people in this network or other "
+"federated sites. Look for a <em>Connect</em> or <em>Follow</em> link on "
+"their profile page. Provide your own Identity Address if requested."
+msgstr "El Directorio te permite encontrar otras personas en esta red o en cualquier otro sitio federado. Busca algún enlace de <em>Conectar</em> o <em>Seguir</em> en su perfil. Proporciona tu direción personal si es necesario."
 
-#: mod/admin.php:976
-msgid "SSL link policy"
-msgstr "Política de enlaces SSL"
+#: mod/newmember.php:57
+msgid "Finding New People"
+msgstr "Encontrando nueva gente"
 
-#: mod/admin.php:976
-msgid "Determines whether generated links should be forced to use SSL"
-msgstr "Determina si los enlaces generados deben ser forzados a utilizar SSL"
+#: mod/newmember.php:57
+msgid ""
+"On the side panel of the Contacts page are several tools to find new "
+"friends. We can match people by interest, look up people by name or "
+"interest, and provide suggestions based on network relationships. On a brand"
+" new site, friend suggestions will usually begin to be populated within 24 "
+"hours."
+msgstr "En el panel lateral de la página de Contactos existen varias herramientas para encontrar nuevos amigos. Podemos filtrar personas por sus intereses, buscar personas por nombre o por sus intereses, y ofrecerte sugerencias basadas en sus relaciones de la red. En un sitio nuevo, las sugerencias de amigos por lo general comienzan pasadas las 24 horas."
 
-#: mod/admin.php:977
-msgid "Force SSL"
-msgstr "Forzar SSL"
+#: mod/newmember.php:65
+msgid "Group Your Contacts"
+msgstr "Agrupa tus contactos"
+
+#: mod/newmember.php:65
+msgid ""
+"Once you have made some friends, organize them into private conversation "
+"groups from the sidebar of your Contacts page and then you can interact with"
+" each group privately on your Network page."
+msgstr "Una vez que tengas algunos amigos, puedes organizarlos en grupos privados de conversación mediante el memnú en tu página de Contactos y luego puedes interactuar con cada grupo por separado desde tu página de Red."
 
-#: mod/admin.php:977
-msgid ""
-"Force all Non-SSL requests to SSL - Attention: on some systems it could lead"
-" to endless loops."
-msgstr "Forzar todos las consultas No-SSL a SSL. - ATENCIÓN: en algunos sistemas esto puede generar comportamiento recursivo interminable."
+#: mod/newmember.php:68
+msgid "Why Aren't My Posts Public?"
+msgstr "¿Por qué mis publicaciones no son públicas?"
 
-#: mod/admin.php:978
-msgid "Old style 'Share'"
-msgstr "Viejo estilo de 'reenviar'"
+#: mod/newmember.php:68
+msgid ""
+"Friendica respects your privacy. By default, your posts will only show up to"
+" people you've added as friends. For more information, see the help section "
+"from the link above."
+msgstr "Friendica respeta tu privacidad. Por defecto, tus publicaciones solo se mostrarán a personas que hayas añadido como amistades. Para más información, mira la sección de ayuda en el enlace de más arriba."
 
-#: mod/admin.php:978
-msgid "Deactivates the bbcode element 'share' for repeating items."
-msgstr "Desactiva el elemento bbcode 'reenviar' para objetos repetidos."
+#: mod/newmember.php:73
+msgid "Getting Help"
+msgstr "Consiguiendo ayuda"
 
-#: mod/admin.php:979
-msgid "Hide help entry from navigation menu"
-msgstr "Ocultar la ayuda en el menú de navegación"
+#: mod/newmember.php:77
+msgid "Go to the Help Section"
+msgstr "Ir a la sección de ayuda"
 
-#: mod/admin.php:979
+#: mod/newmember.php:77
 msgid ""
-"Hides the menu entry for the Help pages from the navigation menu. You can "
-"still access it calling /help directly."
-msgstr "Oculta la entrada de las páginas de Ayuda en el menú de navegación. Todavía se puede acceder escribiendo /ayuda directamente."
+"Our <strong>help</strong> pages may be consulted for detail on other program"
+" features and resources."
+msgstr "Puedes consultar nuestra página de <strong>Ayuda</strong> para más información y recursos de ayuda."
 
-#: mod/admin.php:980
-msgid "Single user instance"
-msgstr "Sesión de usuario único"
+#: mod/nogroup.php:65
+msgid "Contacts who are not members of a group"
+msgstr "Contactos sin grupo"
 
-#: mod/admin.php:980
-msgid "Make this instance multi-user or single-user for the named user"
-msgstr "Haz esta sesión multi-usuario o usuario único para el usuario"
+#: mod/notifications.php:35
+msgid "Invalid request identifier."
+msgstr "Solicitud de identificación no válida."
 
-#: mod/admin.php:981
-msgid "Maximum image size"
-msgstr "Tamaño máximo de la imagen"
+#: mod/notifications.php:44 mod/notifications.php:180
+#: mod/notifications.php:258
+msgid "Discard"
+msgstr "Descartar"
 
-#: mod/admin.php:981
-msgid ""
-"Maximum size in bytes of uploaded images. Default is 0, which means no "
-"limits."
-msgstr "Tamaño máximo en bytes de las imágenes a subir. Por defecto es 0, que quiere decir que no hay límite."
+#: mod/notifications.php:105
+msgid "Network Notifications"
+msgstr "Notificaciones de Red"
 
-#: mod/admin.php:982
-msgid "Maximum image length"
-msgstr "Largo máximo de imagen"
+#: mod/notifications.php:111 mod/notify.php:69
+msgid "System Notifications"
+msgstr "Notificaciones del sistema"
 
-#: mod/admin.php:982
-msgid ""
-"Maximum length in pixels of the longest side of uploaded images. Default is "
-"-1, which means no limits."
-msgstr "Longitud máxima en píxeles del lado más largo de las imágenes subidas. Por defecto es -1, que significa que no hay límites."
+#: mod/notifications.php:117
+msgid "Personal Notifications"
+msgstr "Notificaciones personales"
 
-#: mod/admin.php:983
-msgid "JPEG image quality"
-msgstr "Calidad de imagen JPEG"
+#: mod/notifications.php:123
+msgid "Home Notifications"
+msgstr "Notificaciones de Inicio"
 
-#: mod/admin.php:983
-msgid ""
-"Uploaded JPEGS will be saved at this quality setting [0-100]. Default is "
-"100, which is full quality."
-msgstr "Los archivos JPEG subidos se guardarán con este ajuste de calidad [0-100]. Por defecto es 100, que es calidad máxima."
+#: mod/notifications.php:152
+msgid "Show Ignored Requests"
+msgstr "Mostrar peticiones ignoradas"
 
-#: mod/admin.php:985
-msgid "Register policy"
-msgstr "Política de registros"
+#: mod/notifications.php:152
+msgid "Hide Ignored Requests"
+msgstr "Ocultar peticiones ignoradas"
 
-#: mod/admin.php:986
-msgid "Maximum Daily Registrations"
-msgstr "Registros Máximos Diarios"
+#: mod/notifications.php:164 mod/notifications.php:228
+msgid "Notification type: "
+msgstr "Tipo de notificación: "
 
-#: mod/admin.php:986
-msgid ""
-"If registration is permitted above, this sets the maximum number of new user"
-" registrations to accept per day.  If register is set to closed, this "
-"setting has no effect."
-msgstr "Si anteriormente se ha permitido el registro, esto establece el número máximo de registro de nuevos usuarios aceptados por día. Si el registro se establece como cerrado, esta opción no tiene efecto."
+#: mod/notifications.php:167
+#, php-format
+msgid "suggested by %s"
+msgstr "sugerido por %s"
 
-#: mod/admin.php:987
-msgid "Register text"
-msgstr "Términos"
+#: mod/notifications.php:173 mod/notifications.php:246
+msgid "Post a new friend activity"
+msgstr "Publica tu nueva amistad"
 
-#: mod/admin.php:987
-msgid "Will be displayed prominently on the registration page."
-msgstr "Se mostrará en un lugar destacado en la página de registro."
+#: mod/notifications.php:173 mod/notifications.php:246
+msgid "if applicable"
+msgstr "Si corresponde"
 
-#: mod/admin.php:988
-msgid "Accounts abandoned after x days"
-msgstr "Cuentas abandonadas después de x días"
+#: mod/notifications.php:195
+msgid "Claims to be known to you: "
+msgstr "Dice conocerte: "
 
-#: mod/admin.php:988
-msgid ""
-"Will not waste system resources polling external sites for abandonded "
-"accounts. Enter 0 for no time limit."
-msgstr "No gastará recursos del sistema creando sondeos a sitios externos para cuentas abandonadas. Introduce 0 para ningún límite temporal."
+#: mod/notifications.php:196
+msgid "yes"
+msgstr "sí"
 
-#: mod/admin.php:989
-msgid "Allowed friend domains"
-msgstr "Dominios amigos permitidos"
+#: mod/notifications.php:196
+msgid "no"
+msgstr "no"
 
-#: mod/admin.php:989
+#: mod/notifications.php:197 mod/notifications.php:202
+msgid "Shall your connection be bidirectional or not?"
+msgstr "¿Su conexión debe ser bidireccional o no?"
+
+#: mod/notifications.php:198 mod/notifications.php:203
+#, php-format
 msgid ""
-"Comma separated list of domains which are allowed to establish friendships "
-"with this site. Wildcards are accepted. Empty to allow any domains"
-msgstr "Lista separada por comas de los dominios que están autorizados para establecer conexiones con este sitio. Se aceptan comodines. Dejar en blanco para permitir cualquier dominio"
+"Accepting %s as a friend allows %s to subscribe to your posts, and you will "
+"also receive updates from them in your news feed."
+msgstr "Aceptar a %s como amigo le permite a %s suscribirse a sus publicaciones, y usted también recibirá actualizaciones de ellos en sus noticias."
 
-#: mod/admin.php:990
-msgid "Allowed email domains"
-msgstr "Dominios de correo permitidos"
+#: mod/notifications.php:199
+#, php-format
+msgid ""
+"Accepting %s as a subscriber allows them to subscribe to your posts, but you"
+" will not receive updates from them in your news feed."
+msgstr "Aceptar a %s como suscriptor les permite suscribirse a sus publicaciones, pero usted no recibirá actualizaciones de ellos en sus noticias."
 
-#: mod/admin.php:990
+#: mod/notifications.php:204
+#, php-format
 msgid ""
-"Comma separated list of domains which are allowed in email addresses for "
-"registrations to this site. Wildcards are accepted. Empty to allow any "
-"domains"
-msgstr "Lista separada por comas de los dominios que están autorizados en las direcciones de correo para registrarse en este sitio. Se aceptan comodines. Dejar en blanco para permitir cualquier dominio"
+"Accepting %s as a sharer allows them to subscribe to your posts, but you "
+"will not receive updates from them in your news feed."
+msgstr "Aceptar a %s como participante les permite suscribirse a sus publicaciones, pero usted no recibirá actualizaciones de ellos en sus noticias."
 
-#: mod/admin.php:991
-msgid "Block public"
-msgstr "Bloqueo público"
+#: mod/notifications.php:215
+msgid "Friend"
+msgstr "Amigo"
 
-#: mod/admin.php:991
-msgid ""
-"Check to block public access to all otherwise public personal pages on this "
-"site unless you are currently logged in."
-msgstr "Marca para bloquear el acceso público a todas las páginas personales, aún siendo públicas, hasta que no hayas iniciado tu sesión."
+#: mod/notifications.php:216
+msgid "Sharer"
+msgstr "Lector"
 
-#: mod/admin.php:992
-msgid "Force publish"
-msgstr "Forzar publicación"
+#: mod/notifications.php:216
+msgid "Subscriber"
+msgstr "Suscriptor"
 
-#: mod/admin.php:992
-msgid ""
-"Check to force all profiles on this site to be listed in the site directory."
-msgstr "Marca para forzar que todos los perfiles de este sitio sean listados en el directorio del sitio."
+#: mod/notifications.php:266
+msgid "No introductions."
+msgstr "Sin presentaciones."
 
-#: mod/admin.php:993
-msgid "Global directory URL"
-msgstr "URL del directorio global."
+#: mod/notifications.php:307
+msgid "Show unread"
+msgstr "Mostrar no leído"
 
-#: mod/admin.php:993
-msgid ""
-"URL to the global directory. If this is not set, the global directory is "
-"completely unavailable to the application."
-msgstr "URL del directorio global. Si se deja este campo vacío, el directorio global sera completamente inaccesible para la instancia."
+#: mod/notifications.php:307
+msgid "Show all"
+msgstr "Mostrar todo"
 
-#: mod/admin.php:994
-msgid "Allow threaded items"
-msgstr "Permitir elementos en hilo"
+#: mod/notifications.php:313
+#, php-format
+msgid "No more %s notifications."
+msgstr "No más notificaciones de %s."
 
-#: mod/admin.php:994
-msgid "Allow infinite level threading for items on this site."
-msgstr "Permitir infinitos niveles de hilo para los elementos de este sitio."
+#: mod/notify.php:65
+msgid "No more system notifications."
+msgstr "No hay más notificaciones del sistema."
 
-#: mod/admin.php:995
-msgid "Private posts by default for new users"
-msgstr "Publicaciones privadas por defecto para usuarios nuevos"
+#: mod/oexchange.php:21
+msgid "Post successful."
+msgstr "¡Publicado!"
 
-#: mod/admin.php:995
+#: mod/openid.php:24
+msgid "OpenID protocol error. No ID returned."
+msgstr "Error de protocolo OpenID. ID no devuelta."
+
+#: mod/openid.php:60
 msgid ""
-"Set default post permissions for all new members to the default privacy "
-"group rather than public."
-msgstr "Ajusta los permisos de publicación por defecto a los miembros nuevos al grupo privado por defecto en vez del público."
+"Account not found and OpenID registration is not permitted on this site."
+msgstr "Cuenta no encontrada y el registro OpenID no está permitido en ese sitio."
 
-#: mod/admin.php:996
-msgid "Don't include post content in email notifications"
-msgstr "No incluir el contenido del post en las notificaciones de correo electrónico"
+#: mod/ostatus_subscribe.php:14
+msgid "Subscribing to OStatus contacts"
+msgstr "Subscribir a los contactos de OStatus"
 
-#: mod/admin.php:996
-msgid ""
-"Don't include the content of a post/comment/private message/etc. in the "
-"email notifications that are sent out from this site, as a privacy measure."
-msgstr "No incluye el contenido de un mensaje/comentario/mensaje privado/etc. en las notificaciones de correo electrónico que se envían desde este sitio, como una medida de privacidad."
+#: mod/ostatus_subscribe.php:25
+msgid "No contact provided."
+msgstr "Sin suministro de datos de contacto."
 
-#: mod/admin.php:997
-msgid "Disallow public access to addons listed in the apps menu."
-msgstr "Deshabilitar acceso a addons listados en el menú de aplicaciones."
+#: mod/ostatus_subscribe.php:31
+msgid "Couldn't fetch information for contact."
+msgstr "No se ha podido conseguir la información del contacto."
 
-#: mod/admin.php:997
-msgid ""
-"Checking this box will restrict addons listed in the apps menu to members "
-"only."
-msgstr "Habilitando esta opción restringe el acceso a addons en el menú de aplicaciones a usuarios identificados."
+#: mod/ostatus_subscribe.php:40
+msgid "Couldn't fetch friends for contact."
+msgstr "No se ha podido conseguir datos de amigos para contactar."
 
-#: mod/admin.php:998
-msgid "Don't embed private images in posts"
-msgstr "No agregar imágenes privados en las publicaciones"
+#: mod/ostatus_subscribe.php:54 mod/repair_ostatus.php:44
+msgid "Done"
+msgstr "hecho!"
 
-#: mod/admin.php:998
-msgid ""
-"Don't replace locally-hosted private photos in posts with an embedded copy "
-"of the image. This means that contacts who receive posts containing private "
-"photos will have to authenticate and load each image, which may take a "
-"while."
-msgstr "No reemplazar imágenes privadas guardadas localmente en el servidor con imágenes integrados en los envíos. Esto significa que contactos que reciben publicaciones tendrán que autenticarse y cargar cada imagen, lo que puede demorar."
+#: mod/ostatus_subscribe.php:68
+msgid "success"
+msgstr "exito!"
+
+#: mod/ostatus_subscribe.php:70
+msgid "failed"
+msgstr "fallido!"
+
+#: mod/ostatus_subscribe.php:78 mod/repair_ostatus.php:50
+msgid "Keep this window open until done."
+msgstr "Mantén esta ventana abierta hasta que el proceso ha terminado."
+
+#: mod/p.php:9
+msgid "Not Extended"
+msgstr "No extendido"
 
-#: mod/admin.php:999
-msgid "Allow Users to set remote_self"
-msgstr "Permitir a los usuarios de definir perfiles_remotos"
+#: mod/photos.php:90 mod/photos.php:1876
+msgid "Recent Photos"
+msgstr "Fotos recientes"
 
-#: mod/admin.php:999
-msgid ""
-"With checking this, every user is allowed to mark every contact as a "
-"remote_self in the repair contact dialog. Setting this flag on a contact "
-"causes mirroring every posting of that contact in the users stream."
-msgstr "Al habilitar esta opción, cada perfil tiene el permiso de marcar cualquiera de sus contactos como un perfil_remoto. Habilitar la opción perfil_remoto para un contacto genera que todas las publicaciones  de este contacto seran re-publicado  en el muro del perfil."
+#: mod/photos.php:93 mod/photos.php:1303 mod/photos.php:1878
+msgid "Upload New Photos"
+msgstr "Subir nuevas fotos"
 
-#: mod/admin.php:1000
-msgid "Block multiple registrations"
-msgstr "Bloquear registros multiples"
+#: mod/photos.php:107 mod/settings.php:36
+msgid "everybody"
+msgstr "todos"
 
-#: mod/admin.php:1000
-msgid "Disallow users to register additional accounts for use as pages."
-msgstr "Impedir que los usuarios registren cuentas adicionales para su uso como páginas."
+#: mod/photos.php:171
+msgid "Contact information unavailable"
+msgstr "Información del contacto no disponible"
 
-#: mod/admin.php:1001
-msgid "OpenID support"
-msgstr "Soporte OpenID"
+#: mod/photos.php:192
+msgid "Album not found."
+msgstr "Álbum no encontrado."
 
-#: mod/admin.php:1001
-msgid "OpenID support for registration and logins."
-msgstr "Soporte OpenID para registros y accesos."
+#: mod/photos.php:225 mod/photos.php:237 mod/photos.php:1247
+msgid "Delete Album"
+msgstr "Eliminar álbum"
 
-#: mod/admin.php:1002
-msgid "Fullname check"
-msgstr "Comprobar Nombre completo"
+#: mod/photos.php:235
+msgid "Do you really want to delete this photo album and all its photos?"
+msgstr "¿Estás seguro de quieres borrar este álbum y todas sus fotos?"
 
-#: mod/admin.php:1002
-msgid ""
-"Force users to register with a space between firstname and lastname in Full "
-"name, as an antispam measure"
-msgstr "Fuerza a los usuarios a registrarse con un espacio entre su nombre y su apellido en el campo Nombre completo como medida anti-spam"
+#: mod/photos.php:317 mod/photos.php:328 mod/photos.php:1563
+msgid "Delete Photo"
+msgstr "Eliminar foto"
 
-#: mod/admin.php:1003
-msgid "UTF-8 Regular expressions"
-msgstr "Expresiones regulares UTF-8"
+#: mod/photos.php:326
+msgid "Do you really want to delete this photo?"
+msgstr "¿Estás seguro de que quieres borrar esta foto?"
 
-#: mod/admin.php:1003
-msgid "Use PHP UTF8 regular expressions"
-msgstr "Usar expresiones regulares de UTF8 en PHP"
+#: mod/photos.php:705
+#, php-format
+msgid "%1$s was tagged in %2$s by %3$s"
+msgstr "%1$s fue etiquetado en %2$s por %3$s"
 
-#: mod/admin.php:1004
-msgid "Community Page Style"
-msgstr "Estilo de pagina de comunidad"
+#: mod/photos.php:705
+msgid "a photo"
+msgstr "una foto"
 
-#: mod/admin.php:1004
-msgid ""
-"Type of community page to show. 'Global community' shows every public "
-"posting from an open distributed network that arrived on this server."
-msgstr "Tipo de pagina de comunidad a visualizar. 'Comunidad global' muestra todas las publicaciones publicas de la red abierta federada que llega a este servidor."
+#: mod/photos.php:803 mod/profile_photo.php:156 mod/wall_upload.php:151
+#, php-format
+msgid "Image exceeds size limit of %s"
+msgstr "La imagen excede el limite de %s"
 
-#: mod/admin.php:1005
-msgid "Posts per user on community page"
-msgstr "Publicaciones por usuario en la pagina de comunidad"
+#: mod/photos.php:811
+msgid "Image file is empty."
+msgstr "El archivo de imagen está vacío."
 
-#: mod/admin.php:1005
-msgid ""
-"The maximum number of posts per user on the community page. (Not valid for "
-"'Global Community')"
-msgstr "El numero máximo de publicaciones por usuario que aparecerán en la pagina de comunidad. (No valido para 'comunidad global')"
+#: mod/photos.php:844 mod/profile_photo.php:165 mod/wall_upload.php:186
+msgid "Unable to process image."
+msgstr "Imposible procesar la imagen."
 
-#: mod/admin.php:1006
-msgid "Enable OStatus support"
-msgstr "Permitir soporte OStatus"
+#: mod/photos.php:871 mod/profile_photo.php:315 mod/wall_upload.php:219
+msgid "Image upload failed."
+msgstr "Error al subir la imagen."
 
-#: mod/admin.php:1006
-msgid ""
-"Provide built-in OStatus (StatusNet, GNU Social etc.) compatibility. All "
-"communications in OStatus are public, so privacy warnings will be "
-"occasionally displayed."
-msgstr "Proporcionar OStatus compatibilidad integrada (StatusNet, GNU Social, Quitter etc.). Todas las comunicaciones en OStatus son publicas así que eventuales advertencias serán ocasionalmente desplegadas."
+#: mod/photos.php:974
+msgid "No photos selected"
+msgstr "Ninguna foto seleccionada"
 
-#: mod/admin.php:1007
-msgid "OStatus conversation completion interval"
-msgstr "Intervalo de actualización de conversaciones OStatus"
+#: mod/photos.php:1074 mod/videos.php:309
+msgid "Access to this item is restricted."
+msgstr "El acceso a este elemento está restringido."
 
-#: mod/admin.php:1007
-msgid ""
-"How often shall the poller check for new entries in OStatus conversations? "
-"This can be a very ressource task."
-msgstr "Cuan seguido el recolector deberá buscar nuevas entradas en OStatus? Esto puede ser un trabajo de mucha carga para los recursos del servidor."
+#: mod/photos.php:1134
+#, php-format
+msgid "You have used %1$.2f Mbytes of %2$.2f Mbytes photo storage."
+msgstr "Has usado %1$.2f MB de %2$.2f MB de tu álbum de fotos."
 
-#: mod/admin.php:1008
-msgid "Only import OStatus threads from our contacts"
-msgstr "Solo importar OStatus temas de nuestros (?) contactos."
+#: mod/photos.php:1168
+msgid "Upload Photos"
+msgstr "Subir fotos"
 
-#: mod/admin.php:1008
-msgid ""
-"Normally we import every content from our OStatus contacts. With this option"
-" we only store threads that are started by a contact that is known on our "
-"system."
-msgstr "Normalmente importamos todo el contenido de los contactos de OStatus. Con esta opción solamente se guardan temas que fueron iniciados por contactos que son conocidos de la instancia.\n(nota de traducción, no se entiende muy bien la función en base al texto original)"
+#: mod/photos.php:1172 mod/photos.php:1242
+msgid "New album name: "
+msgstr "Nombre del nuevo álbum: "
 
-#: mod/admin.php:1009
-msgid "OStatus support can only be enabled if threading is enabled."
-msgstr "Solo se puede habilitar el soporte OStatus  si threading (comentarios en fila) se encuentra habilitado."
+#: mod/photos.php:1173
+msgid "or existing album name: "
+msgstr "o nombre de un álbum existente: "
 
-#: mod/admin.php:1011
-msgid ""
-"Diaspora support can't be enabled because Friendica was installed into a sub"
-" directory."
-msgstr "El soporte para Diaspora* no se puede habilitar porque friendica se instalo en un directorio subalterno (sub directory)."
+#: mod/photos.php:1174
+msgid "Do not show a status post for this upload"
+msgstr "No actualizar tu estado con este envío"
 
-#: mod/admin.php:1012
-msgid "Enable Diaspora support"
-msgstr "Habilitar el soporte para Diaspora*"
+#: mod/photos.php:1185 mod/photos.php:1567 mod/settings.php:1307
+msgid "Show to Groups"
+msgstr "Mostrar a los Grupos"
 
-#: mod/admin.php:1012
-msgid "Provide built-in Diaspora network compatibility."
-msgstr "Provee una compatibilidad con la red de Diaspora."
+#: mod/photos.php:1186 mod/photos.php:1568 mod/settings.php:1308
+msgid "Show to Contacts"
+msgstr "Mostrar a los Contactos"
 
-#: mod/admin.php:1013
-msgid "Only allow Friendica contacts"
-msgstr "Permitir solo contactos de Friendica"
+#: mod/photos.php:1187
+msgid "Private Photo"
+msgstr "Foto Privada"
 
-#: mod/admin.php:1013
-msgid ""
-"All contacts must use Friendica protocols. All other built-in communication "
-"protocols disabled."
-msgstr "Todos los contactos deben usar protocolos de Friendica. El resto de protocolos serán desactivados."
+#: mod/photos.php:1188
+msgid "Public Photo"
+msgstr "Foto Pública"
 
-#: mod/admin.php:1014
-msgid "Verify SSL"
-msgstr "Verificar SSL"
+#: mod/photos.php:1254
+msgid "Edit Album"
+msgstr "Modificar álbum"
 
-#: mod/admin.php:1014
-msgid ""
-"If you wish, you can turn on strict certificate checking. This will mean you"
-" cannot connect (at all) to self-signed SSL sites."
-msgstr "Si quieres puedes activar la comprobación estricta de certificados. Esto significa que serás incapaz de conectar con ningún sitio que use certificados SSL autofirmados."
+#: mod/photos.php:1260
+msgid "Show Newest First"
+msgstr "Mostrar más nuevos primero"
 
-#: mod/admin.php:1015
-msgid "Proxy user"
-msgstr "Usuario proxy"
+#: mod/photos.php:1262
+msgid "Show Oldest First"
+msgstr "Mostrar más antiguos primero"
 
-#: mod/admin.php:1016
-msgid "Proxy URL"
-msgstr "Dirección proxy"
+#: mod/photos.php:1289 mod/photos.php:1861
+msgid "View Photo"
+msgstr "Ver foto"
 
-#: mod/admin.php:1017
-msgid "Network timeout"
-msgstr "Tiempo de espera de red"
+#: mod/photos.php:1335
+msgid "Permission denied. Access to this item may be restricted."
+msgstr "Permiso denegado. El acceso a este elemento puede estar restringido."
 
-#: mod/admin.php:1017
-msgid "Value is in seconds. Set to 0 for unlimited (not recommended)."
-msgstr "Valor en segundos. Usar 0 para dejarlo sin límites (no se recomienda)."
+#: mod/photos.php:1337
+msgid "Photo not available"
+msgstr "Foto no disponible"
 
-#: mod/admin.php:1018
-msgid "Delivery interval"
-msgstr "Intervalo de actualización"
+#: mod/photos.php:1395
+msgid "View photo"
+msgstr "Ver foto"
 
-#: mod/admin.php:1018
-msgid ""
-"Delay background delivery processes by this many seconds to reduce system "
-"load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 "
-"for large dedicated servers."
-msgstr "Retrasar la entrega de procesos en segundo plano por esta cantidad de segundos para reducir la carga del sistema. Recomendamos: 4-5 para los servidores compartidos, 2-3 para servidores privados virtuales, 0-1 para los grandes servidores dedicados."
+#: mod/photos.php:1395
+msgid "Edit photo"
+msgstr "Modificar foto"
 
-#: mod/admin.php:1019
-msgid "Poll interval"
-msgstr "Intervalo de sondeo"
+#: mod/photos.php:1396
+msgid "Use as profile photo"
+msgstr "Usar como foto del perfil"
 
-#: mod/admin.php:1019
-msgid ""
-"Delay background polling processes by this many seconds to reduce system "
-"load. If 0, use delivery interval."
-msgstr "Retrasar los procesos en segundo plano de sondeo en esta cantidad de segundos para reducir la carga del sistema. Si es 0, se usará el intervalo de entrega."
+#: mod/photos.php:1421
+msgid "View Full Size"
+msgstr "Ver a tamaño completo"
 
-#: mod/admin.php:1020
-msgid "Maximum Load Average"
-msgstr "Promedio de carga máxima"
+#: mod/photos.php:1507
+msgid "Tags: "
+msgstr "Etiquetas: "
 
-#: mod/admin.php:1020
-msgid ""
-"Maximum system load before delivery and poll processes are deferred - "
-"default 50."
-msgstr "Carga máxima del sistema antes de que la entrega y los procesos de sondeo sean retrasados - por defecto 50."
+#: mod/photos.php:1510
+msgid "[Remove any tag]"
+msgstr "[Borrar todas las etiquetas]"
 
-#: mod/admin.php:1021
-msgid "Maximum Load Average (Frontend)"
-msgstr "Carga máxima promedio (frontend)"
+#: mod/photos.php:1549
+msgid "New album name"
+msgstr "Nuevo nombre del álbum"
 
-#: mod/admin.php:1021
-msgid "Maximum system load before the frontend quits service - default 50."
-msgstr "Carga máxima del sistema antes de que el frontend cancele el servicio - por defecto 50."
+#: mod/photos.php:1550
+msgid "Caption"
+msgstr "Título"
 
-#: mod/admin.php:1022
-msgid "Maximum table size for optimization"
-msgstr "Tamaño máximo de las tablas para la optimización."
+#: mod/photos.php:1551
+msgid "Add a Tag"
+msgstr "Añadir una etiqueta"
 
-#: mod/admin.php:1022
+#: mod/photos.php:1551
 msgid ""
-"Maximum table size (in MB) for the automatic optimization - default 100 MB. "
-"Enter -1 to disable it."
-msgstr "Tamaño máximo de tablas (en MB) para la optimización automática - por defecto 100MB. Ingrese -1 para deshabilitar."
+"Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping"
+msgstr "Ejemplo: @juan, @Barbara_Ruiz, @julia@example.com, #California, #camping"
 
-#: mod/admin.php:1023
-msgid "Minimum level of fragmentation"
-msgstr "Nivel mínimo de fragmentación "
+#: mod/photos.php:1552
+msgid "Do not rotate"
+msgstr "No rotar"
 
-#: mod/admin.php:1023
-msgid ""
-"Minimum fragmenation level to start the automatic optimization - default "
-"value is 30%."
-msgstr "Nivel mínimo de fragmentación para para comenzar la optimización - valor por defecto es 30%. "
+#: mod/photos.php:1553
+msgid "Rotate CW (right)"
+msgstr "Girar a la derecha"
 
-#: mod/admin.php:1025
-msgid "Periodical check of global contacts"
-msgstr "Verificación periódica de los contactos globales."
+#: mod/photos.php:1554
+msgid "Rotate CCW (left)"
+msgstr "Girar a la izquierda"
+
+#: mod/photos.php:1569
+msgid "Private photo"
+msgstr "Foto privada"
+
+#: mod/photos.php:1570
+msgid "Public photo"
+msgstr "Foto pública"
 
-#: mod/admin.php:1025
-msgid ""
-"If enabled, the global contacts are checked periodically for missing or "
-"outdated data and the vitality of the contacts and servers."
-msgstr "Habilitado los contactos globales son verificado periódicamente  por datos faltantes o datos obsoletos como también por la vitalidad de los contactos y servidores."
+#: mod/photos.php:1792
+msgid "Map"
+msgstr "Mapa"
 
-#: mod/admin.php:1026
-msgid "Days between requery"
-msgstr "Días entre búsquedas"
+#: mod/photos.php:1867 mod/videos.php:391
+msgid "View Album"
+msgstr "Ver Álbum"
 
-#: mod/admin.php:1026
-msgid "Number of days after which a server is requeried for his contacts."
-msgstr "Cantidad de días hasta que un servidor es consultado por sus contactos."
+#: mod/ping.php:270
+msgid "{0} wants to be your friend"
+msgstr "{0} quiere ser tu amigo"
 
-#: mod/admin.php:1027
-msgid "Discover contacts from other servers"
-msgstr "Descubrir contactos de otros servidores"
+#: mod/ping.php:285
+msgid "{0} sent you a message"
+msgstr "{0} te ha enviado un mensaje"
 
-#: mod/admin.php:1027
-msgid ""
-"Periodically query other servers for contacts. You can choose between "
-"'users': the users on the remote system, 'Global Contacts': active contacts "
-"that are known on the system. The fallback is meant for Redmatrix servers "
-"and older friendica servers, where global contacts weren't available. The "
-"fallback increases the server load, so the recommened setting is 'Users, "
-"Global Contacts'."
-msgstr "Recoger periódicamente información sobre perfiles en otros servidores. Puede elegir entre 'usuarios': perfiles de un sistema remoto, 'contactos globales': contactos activos que son conocidos por el servidor. El fallback es para servidors redmatrix y instalaciones viejas de friendica en las que los contactos no estaban a disposición. El fallback aumenta la carga del servidor, asi que la configuración recomendada es 'usuarios, contactos globales'"
+#: mod/ping.php:300
+msgid "{0} requested registration"
+msgstr "{0} solicitudes de registro"
 
-#: mod/admin.php:1028
-msgid "Timeframe for fetching global contacts"
-msgstr "Intervalos de tiempo para revisar contactos globales."
+#: mod/poke.php:196
+msgid "Poke/Prod"
+msgstr "Toque/Empujón"
 
-#: mod/admin.php:1028
-msgid ""
-"When the discovery is activated, this value defines the timeframe for the "
-"activity of the global contacts that are fetched from other servers."
-msgstr "Cuando la revisacion es activada, este valor define el intervalo de tiempo de la actividad de los contactos globales que son recolectados de los servidores. (?)"
+#: mod/poke.php:197
+msgid "poke, prod or do other things to somebody"
+msgstr "da un toque, empujón o similar a alguien"
 
-#: mod/admin.php:1029
-msgid "Search the local directory"
-msgstr "Buscar el directorio local"
+#: mod/poke.php:198
+msgid "Recipient"
+msgstr "Receptor"
 
-#: mod/admin.php:1029
-msgid ""
-"Search the local directory instead of the global directory. When searching "
-"locally, every search will be executed on the global directory in the "
-"background. This improves the search results when the search is repeated."
-msgstr "Buscar en el directorio local en vez del directorio global. Cuando se busca localmente, cada busqueda sera efectuada en el directorio global en el background. Esto mejora los resultados de la busqueda cuando la misma es repetida."
+#: mod/poke.php:199
+msgid "Choose what you wish to do to recipient"
+msgstr "Elige qué desea hacer con el receptor"
 
-#: mod/admin.php:1031
-msgid "Publish server information"
-msgstr "Publicar información del servidor"
+#: mod/poke.php:202
+msgid "Make this post private"
+msgstr "Hacer esta publicación privada"
 
-#: mod/admin.php:1031
-msgid ""
-"If enabled, general server and usage data will be published. The data "
-"contains the name and version of the server, number of users with public "
-"profiles, number of posts and the activated protocols and connectors. See <a"
-" href='http://the-federation.info/'>the-federation.info</a> for details."
-msgstr "Si habilitado, datos generales del servidor y estadisticas de uso serán publicados. Los datos contienen el nombre y la versión del servidor, numero de usuarios con perfiles públicos, cantidad de temas publicados y los protocolos y conectores activados. Vea <a href='http://the-federation.info/'>the-federation.info</a> por detalles."
+#: mod/profile.php:174
+msgid "Tips for New Members"
+msgstr "Consejos para nuevos miembros"
 
-#: mod/admin.php:1033
-msgid "Use MySQL full text engine"
-msgstr "Usar motor MySQL de texto completo"
+#: mod/profile_photo.php:44
+msgid "Image uploaded but image cropping failed."
+msgstr "Imagen recibida, pero ha fallado al recortarla."
 
-#: mod/admin.php:1033
+#: mod/profile_photo.php:77 mod/profile_photo.php:85 mod/profile_photo.php:93
+#: mod/profile_photo.php:323
+#, php-format
+msgid "Image size reduction [%s] failed."
+msgstr "Ha fallado la reducción de las dimensiones de la imagen [%s]."
+
+#: mod/profile_photo.php:127
 msgid ""
-"Activates the full text engine. Speeds up search - but can only search for "
-"four and more characters."
-msgstr "Activa el motor de texto completo. Agiliza las búsquedas, pero solo busca cuatro o más caracteres."
+"Shift-reload the page or clear browser cache if the new photo does not "
+"display immediately."
+msgstr "Recarga la página o limpia la caché del navegador si la foto nueva no aparece inmediatamente."
 
-#: mod/admin.php:1034
-msgid "Suppress Language"
-msgstr "Suprimir idiomas"
+#: mod/profile_photo.php:137
+msgid "Unable to process image"
+msgstr "Imposible procesar la imagen"
 
-#: mod/admin.php:1034
-msgid "Suppress language information in meta information about a posting."
-msgstr "Suprimir la información de datos meta sobre informaciones de idiomas en las publicaciones."
+#: mod/profile_photo.php:254
+msgid "Upload File:"
+msgstr "Subir archivo:"
 
-#: mod/admin.php:1035
-msgid "Suppress Tags"
-msgstr "Suprimir tags"
+#: mod/profile_photo.php:255
+msgid "Select a profile:"
+msgstr "Elige un perfil:"
 
-#: mod/admin.php:1035
-msgid "Suppress showing a list of hashtags at the end of the posting."
-msgstr "Suprimir la lista de tags al final de una publicación."
+#: mod/profile_photo.php:257
+msgid "Upload"
+msgstr "Subir"
 
-#: mod/admin.php:1036
-msgid "Path to item cache"
-msgstr "Ruta a la caché del objeto"
+#: mod/profile_photo.php:260
+msgid "or"
+msgstr "o"
 
-#: mod/admin.php:1036
-msgid "The item caches buffers generated bbcode and external images."
-msgstr "El buffer de cache de items generado para bbcodes e imágenes externas. "
+#: mod/profile_photo.php:260
+msgid "skip this step"
+msgstr "saltar este paso"
 
-#: mod/admin.php:1037
-msgid "Cache duration in seconds"
-msgstr "Duración de la caché en segundos"
+#: mod/profile_photo.php:260
+msgid "select a photo from your photo albums"
+msgstr "elige una foto de tus álbumes"
 
-#: mod/admin.php:1037
-msgid ""
-"How long should the cache files be hold? Default value is 86400 seconds (One"
-" day). To disable the item cache, set the value to -1."
-msgstr "¿Por cuanto tiempo deberían los archives ser almacenados en el cache? Valor por defecto 86400 segundos (un día). Para deshabilita el item cache, ajuste el valor a -1."
+#: mod/profile_photo.php:274
+msgid "Crop Image"
+msgstr "Recortar imagen"
 
-#: mod/admin.php:1038
-msgid "Maximum numbers of comments per post"
-msgstr "Numero máximo de respuestas por tema"
+#: mod/profile_photo.php:275
+msgid "Please adjust the image cropping for optimum viewing."
+msgstr "Por favor, ajusta el recorte de la imagen para optimizarla."
 
-#: mod/admin.php:1038
-msgid "How much comments should be shown for each post? Default value is 100."
-msgstr "¿Cuantos comentarios deberían ser mostrados por tema? Valor por defecto es 100."
+#: mod/profile_photo.php:277
+msgid "Done Editing"
+msgstr "Editado"
 
-#: mod/admin.php:1039
-msgid "Path for lock file"
-msgstr "Ruta al archivo protegido"
+#: mod/profile_photo.php:313
+msgid "Image uploaded successfully."
+msgstr "Imagen subida con éxito."
 
-#: mod/admin.php:1039
-msgid ""
-"The lock file is used to avoid multiple pollers at one time. Only define a "
-"folder here."
-msgstr "El archivo lock es usado para evitar multiples pooler (recolectores de información) a la vez. Defina solo una carpeta aquí."
+#: mod/profiles.php:38
+msgid "Profile deleted."
+msgstr "Perfil eliminado."
 
-#: mod/admin.php:1040
-msgid "Temp path"
-msgstr "Ruta a los temporales"
+#: mod/profiles.php:56 mod/profiles.php:90
+msgid "Profile-"
+msgstr "Perfil-"
 
-#: mod/admin.php:1040
-msgid ""
-"If you have a restricted system where the webserver can't access the system "
-"temp path, enter another path here."
-msgstr "Si tiene un sistema restringido en donde el servidor web no puede acceder la dirección del sistema temp, ingrese una dirección alternativa aquí. "
+#: mod/profiles.php:75 mod/profiles.php:118
+msgid "New profile created."
+msgstr "Nuevo perfil creado."
 
-#: mod/admin.php:1041
-msgid "Base path to installation"
-msgstr "Ruta base para la instalación"
+#: mod/profiles.php:96
+msgid "Profile unavailable to clone."
+msgstr "Imposible duplicar el perfil."
 
-#: mod/admin.php:1041
-msgid ""
-"If the system cannot detect the correct path to your installation, enter the"
-" correct path here. This setting should only be set if you are using a "
-"restricted system and symbolic links to your webroot."
-msgstr "Si el sistema no puede detectar el acceso correcto a la instalación, ingrese la dirección correcta aquí. Esta configuración solo debería utilizarse si si usa un sistema restringido y enlaces simbolicos a su webroot."
+#: mod/profiles.php:190
+msgid "Profile Name is required."
+msgstr "Se necesita un nombre de perfil."
 
-#: mod/admin.php:1042
-msgid "Disable picture proxy"
-msgstr "Deshabilitar proxy de imagen"
+#: mod/profiles.php:338
+msgid "Marital Status"
+msgstr "Estado civil"
 
-#: mod/admin.php:1042
-msgid ""
-"The picture proxy increases performance and privacy. It shouldn't be used on"
-" systems with very low bandwith."
-msgstr "El proxy de imagen mejora el performance y privacidad. No debería ser usado en sistemas con poco ancho de banda."
+#: mod/profiles.php:342
+msgid "Romantic Partner"
+msgstr "Pareja sentimental"
 
-#: mod/admin.php:1043
-msgid "Enable old style pager"
-msgstr "Habilitar paginación estilo viejo"
+#: mod/profiles.php:354
+msgid "Work/Employment"
+msgstr "Trabajo/estudios"
 
-#: mod/admin.php:1043
-msgid ""
-"The old style pager has page numbers but slows down massively the page "
-"speed."
-msgstr "La paginación al estilo viejo tiene números de paginas pero enlentece masivamente la velocidad de la pagina."
+#: mod/profiles.php:357
+msgid "Religion"
+msgstr "Religión"
 
-#: mod/admin.php:1044
-msgid "Only search in tags"
-msgstr "Solo buscar en tags"
+#: mod/profiles.php:361
+msgid "Political Views"
+msgstr "Preferencias políticas"
 
-#: mod/admin.php:1044
-msgid "On large systems the text search can slow down the system extremely."
-msgstr "En sistemas grandes, la búsqueda de texto puede enlentecer el sistema gravemente."
+#: mod/profiles.php:365
+msgid "Gender"
+msgstr "Género"
 
-#: mod/admin.php:1046
-msgid "New base url"
-msgstr "Nueva URLbase"
+#: mod/profiles.php:369
+msgid "Sexual Preference"
+msgstr "Orientación sexual"
 
-#: mod/admin.php:1046
-msgid ""
-"Change base url for this server. Sends relocate message to all DFRN contacts"
-" of all users."
-msgstr "Cambiar base URL para este servidor. Envía mensajes de relocalisación a todos los contactos DFRN."
+#: mod/profiles.php:373
+msgid "XMPP"
+msgstr "XMPP"
 
-#: mod/admin.php:1048
-msgid "RINO Encryption"
-msgstr "Encryptado RINO"
+#: mod/profiles.php:377
+msgid "Homepage"
+msgstr "Página de inicio"
 
-#: mod/admin.php:1048
-msgid "Encryption layer between nodes."
-msgstr "Capa de encryptación entre nodos."
+#: mod/profiles.php:381 mod/profiles.php:694
+msgid "Interests"
+msgstr "Intereses"
 
-#: mod/admin.php:1049
-msgid "Embedly API key"
-msgstr "Embedly llave de API (API key) "
+#: mod/profiles.php:385
+msgid "Address"
+msgstr "Dirección"
 
-#: mod/admin.php:1049
-msgid ""
-"<a href='http://embed.ly'>Embedly</a> is used to fetch additional data for "
-"web pages. This is an optional parameter."
-msgstr "<a href='http://embed.ly'>Embedly</a> es usado para recolectar datos adicionales para paginas web. Esto es un parámetro opcional."
+#: mod/profiles.php:392 mod/profiles.php:690
+msgid "Location"
+msgstr "Ubicación"
 
-#: mod/admin.php:1051
-msgid "Enable 'worker' background processing"
-msgstr "Habilitar procesos de fondo del \"trabajador\""
+#: mod/profiles.php:477
+msgid "Profile updated."
+msgstr "Perfil actualizado."
 
-#: mod/admin.php:1051
-msgid ""
-"The worker background processing limits the number of parallel background "
-"jobs to a maximum number and respects the system load."
-msgstr "Limita los procesos del trabajo de fondo del numero paralelo de trabajos a un numero máximo que respeta la carga del sistema."
+#: mod/profiles.php:565
+msgid " and "
+msgstr " y "
 
-#: mod/admin.php:1052
-msgid "Maximum number of parallel workers"
-msgstr "Numero máximo de trabajos paralelos de fondo."
+#: mod/profiles.php:573
+msgid "public profile"
+msgstr "perfil público"
 
-#: mod/admin.php:1052
-msgid ""
-"On shared hosters set this to 2. On larger systems, values of 10 are great. "
-"Default value is 4."
-msgstr "Ajustar a 2 en un servidor compartido (shared hosting).\nEn sistemas grandes valores como 10 son excelentes.\nValor por defecto es 4."
+#: mod/profiles.php:576
+#, php-format
+msgid "%1$s changed %2$s to &ldquo;%3$s&rdquo;"
+msgstr "%1$s cambió su %2$s a &ldquo;%3$s&rdquo;"
 
-#: mod/admin.php:1053
-msgid "Don't use 'proc_open' with the worker"
-msgstr "No use 'proc_open' junto al \"trabajador\"!"
+#: mod/profiles.php:577
+#, php-format
+msgid " - Visit %1$s's %2$s"
+msgstr " - Visita %1$s's %2$s"
 
-#: mod/admin.php:1053
-msgid ""
-"Enable this if your system doesn't allow the use of 'proc_open'. This can "
-"happen on shared hosters. If this is enabled you should increase the "
-"frequency of poller calls in your crontab."
-msgstr "Habilite esta función si el sistema no permite el uso de 'proc_open'. Esto suelo suceder en servidores compartidos (shared hosting). Si esta función se habilita se debería incrementar la frecuencia de llamadas del poller (poller calls) en la pestaña de trabajos cron. (¡en el hosting?)"
+#: mod/profiles.php:580
+#, php-format
+msgid "%1$s has an updated %2$s, changing %3$s."
+msgstr "%1$s tiene una actualización %2$s, cambiando %3$s."
 
-#: mod/admin.php:1054
-msgid "Enable fastlane"
-msgstr "Habilitar ascenso rápido"
+#: mod/profiles.php:637
+msgid "Hide contacts and friends:"
+msgstr "Ocultar contactos y amigos"
 
-#: mod/admin.php:1054
-msgid ""
-"When enabed, the fastlane mechanism starts an additional worker if processes"
-" with higher priority are blocked by processes of lower priority."
-msgstr "Cuando está habilitado, el mecanismo ascenso rápido inicia un trabajador adicional si los procesos de mayor prioridad son bloqueados por prcesos de menor prioridad."
+#: mod/profiles.php:642
+msgid "Hide your contact/friend list from viewers of this profile?"
+msgstr "¿Ocultar tu lista de contactos/amigos en este perfil?"
 
-#: mod/admin.php:1055
-msgid "Enable frontend worker"
-msgstr "Habilitar trabajador de interfaz"
+#: mod/profiles.php:666
+msgid "Show more profile fields:"
+msgstr "Mostrar mas campos del perfil:"
 
-#: mod/admin.php:1055
-msgid ""
-"When enabled the Worker process is triggered when backend access is "
-"performed (e.g. messages being delivered). On smaller sites you might want "
-"to call yourdomain.tld/worker on a regular basis via an external cron job. "
-"You should only enable this option if you cannot utilize cron/scheduled jobs"
-" on your server. The worker background process needs to be activated for "
-"this."
-msgstr "Cuando está habilitado, el proceso de Trabajador se activa cuando se ejecuta el acceso de respaldo (ej. mensajes siendo entregados). En páginas más pequeñas usted puede querer llamar a yourdomain.tld/worker en una base regular mediante un trabajo cron externo. Sólo debería habilitar esta opción si no puede utilizar trabajos cron/scheduled en su servidor. El proceso de trabajador en segundo plano necesita ser activado para eso."
+#: mod/profiles.php:678
+msgid "Profile Actions"
+msgstr "Acciones de perfil"
 
-#: mod/admin.php:1084
-msgid "Update has been marked successful"
-msgstr "La actualización se ha completado con éxito"
+#: mod/profiles.php:679
+msgid "Edit Profile Details"
+msgstr "Editar detalles de tu perfil"
 
-#: mod/admin.php:1092
-#, php-format
-msgid "Database structure update %s was successfully applied."
-msgstr "Actualización de base de datos %s fue aplicada con éxito."
+#: mod/profiles.php:681
+msgid "Change Profile Photo"
+msgstr "Cambiar imagen del Perfil"
 
-#: mod/admin.php:1095
-#, php-format
-msgid "Executing of database structure update %s failed with error: %s"
-msgstr "El paso de actualización de la estructura de la base de datos %s fallo con el mensaje de error: %s"
+#: mod/profiles.php:682
+msgid "View this profile"
+msgstr "Ver este perfil"
 
-#: mod/admin.php:1107
-#, php-format
-msgid "Executing %s failed with error: %s"
-msgstr "Paso %s fallo con el error: %s"
+#: mod/profiles.php:684
+msgid "Create a new profile using these settings"
+msgstr "¿Crear un nuevo perfil con esta configuración?"
 
-#: mod/admin.php:1110
-#, php-format
-msgid "Update %s was successfully applied."
-msgstr "Actualización %s aplicada con éxito."
+#: mod/profiles.php:685
+msgid "Clone this profile"
+msgstr "Clonar este perfil"
 
-#: mod/admin.php:1114
-#, php-format
-msgid "Update %s did not return a status. Unknown if it succeeded."
-msgstr "La actualización %s no ha informado, se desconoce el estado."
+#: mod/profiles.php:686
+msgid "Delete this profile"
+msgstr "Eliminar este perfil"
 
-#: mod/admin.php:1116
-#, php-format
-msgid "There was no additional update function %s that needed to be called."
-msgstr "No había función adicional de actualización %s que necesitaba ser requerida."
+#: mod/profiles.php:688
+msgid "Basic information"
+msgstr "Información básica"
 
-#: mod/admin.php:1135
-msgid "No failed updates."
-msgstr "Actualizaciones sin fallos."
+#: mod/profiles.php:689
+msgid "Profile picture"
+msgstr "Imagen del perfil"
 
-#: mod/admin.php:1136
-msgid "Check database structure"
-msgstr "Revisar estructura de la base de datos"
+#: mod/profiles.php:691
+msgid "Preferences"
+msgstr "Preferencias"
 
-#: mod/admin.php:1141
-msgid "Failed Updates"
-msgstr "Actualizaciones fallidas"
+#: mod/profiles.php:692
+msgid "Status information"
+msgstr "Información del estatus"
 
-#: mod/admin.php:1142
-msgid ""
-"This does not include updates prior to 1139, which did not return a status."
-msgstr "No se incluyen las anteriores a la 1139, que no indicaban su estado."
+#: mod/profiles.php:693
+msgid "Additional information"
+msgstr "Información addicional"
 
-#: mod/admin.php:1143
-msgid "Mark success (if update was manually applied)"
-msgstr "Marcar como correcta (si actualizaste manualmente)"
+#: mod/profiles.php:696
+msgid "Relation"
+msgstr "Relación"
 
-#: mod/admin.php:1144
-msgid "Attempt to execute this update step automatically"
-msgstr "Intentando ejecutar este paso automáticamente"
+#: mod/profiles.php:700
+msgid "Your Gender:"
+msgstr "Género:"
 
-#: mod/admin.php:1178
-#, php-format
-msgid ""
-"\n"
-"\t\t\tDear %1$s,\n"
-"\t\t\t\tthe administrator of %2$s has set up an account for you."
-msgstr "\n\t\t\tEstimado %1$s,\n\t\t\t\tel administrador de %2$s ha creado una cuenta para usted."
+#: mod/profiles.php:701
+msgid "<span class=\"heart\">&hearts;</span> Marital Status:"
+msgstr "<span class=\"heart\"&hearts;</span> Estado civil:"
 
-#: mod/admin.php:1181
-#, php-format
-msgid ""
-"\n"
-"\t\t\tThe login details are as follows:\n"
-"\n"
-"\t\t\tSite Location:\t%1$s\n"
-"\t\t\tLogin Name:\t\t%2$s\n"
-"\t\t\tPassword:\t\t%3$s\n"
-"\n"
-"\t\t\tYou may change your password from your account \"Settings\" page after logging\n"
-"\t\t\tin.\n"
-"\n"
-"\t\t\tPlease take a few moments to review the other account settings on that page.\n"
-"\n"
-"\t\t\tYou may also wish to add some basic information to your default profile\n"
-"\t\t\t(on the \"Profiles\" page) so that other people can easily find you.\n"
-"\n"
-"\t\t\tWe recommend setting your full name, adding a profile photo,\n"
-"\t\t\tadding some profile \"keywords\" (very useful in making new friends) - and\n"
-"\t\t\tperhaps what country you live in; if you do not wish to be more specific\n"
-"\t\t\tthan that.\n"
-"\n"
-"\t\t\tWe fully respect your right to privacy, and none of these items are necessary.\n"
-"\t\t\tIf you are new and do not know anybody here, they may help\n"
-"\t\t\tyou to make some new and interesting friends.\n"
-"\n"
-"\t\t\tThank you and welcome to %4$s."
-msgstr "\n\t\t\tLos detalles de acceso son las siguientes:\n\n\t\t\tDirección del sitio:\t%1$s\n\t\t\tNombre de la cuenta:\t\t%2$s\n\t\t\tContraseña:\t\t%3$s\n\n\t\t\tPodrá cambiar la contraseña desde la pagina de configuración de su cuenta después de acceder a la misma\n\t\t\ten.\n\n\t\t\tPor favor tome unos minutos para revisar las opciones demás de la cuenta en dicha pagina de configuración.\n\n\t\t\tTambién podrá agregar informaciones adicionales a su pagina de perfil predeterminado. \n\t\t\t(en la pagina \"Perfiles\") para que otras personas pueden encontrarlo fácilmente.\n\n\t\t\tRecomendamos que elija un nombre apropiado, agregando una imagen de perfil,\n\t\t\tagregando algunas palabras claves de la cuenta (muy útil para hacer nuevos amigos) - y \n\t\t\tquizás el país en donde vive; si no quiere ser mas especifico\n\t\t\tque eso.\n\n\t\t\tRespetamos absolutamente su derecho a la privacidad y ninguno de estos detalles es necesario.\n\t\t\tSi eres nuevo aquí y no conoces a nadie, estos detalles pueden ayudarte\n\t\t\tpara hacer nuevas e interesantes amistades.\n\n\t\t\tGracias y bienvenido a  %4$s."
+#: mod/profiles.php:703
+msgid "Example: fishing photography software"
+msgstr "Ejemplo: pesca fotografía software"
 
-#: mod/admin.php:1225
-#, php-format
-msgid "%s user blocked/unblocked"
-msgid_plural "%s users blocked/unblocked"
-msgstr[0] "%s usuario bloqueado/desbloqueado"
-msgstr[1] "%s usuarios bloqueados/desbloqueados"
+#: mod/profiles.php:708
+msgid "Profile Name:"
+msgstr "Nombres del perfil:"
 
-#: mod/admin.php:1232
-#, php-format
-msgid "%s user deleted"
-msgid_plural "%s users deleted"
-msgstr[0] "%s usuario eliminado"
-msgstr[1] "%s usuarios eliminados"
+#: mod/profiles.php:710
+msgid ""
+"This is your <strong>public</strong> profile.<br />It <strong>may</strong> "
+"be visible to anybody using the internet."
+msgstr "Éste es tu perfil <strong>público</strong>.<br /><strong>Puede</strong> ser visto por cualquier usuario de internet."
 
-#: mod/admin.php:1279
-#, php-format
-msgid "User '%s' deleted"
-msgstr "Usuario '%s' eliminado"
+#: mod/profiles.php:711
+msgid "Your Full Name:"
+msgstr "Tu nombre completo:"
 
-#: mod/admin.php:1287
-#, php-format
-msgid "User '%s' unblocked"
-msgstr "Usuario '%s' desbloqueado"
+#: mod/profiles.php:712
+msgid "Title/Description:"
+msgstr "Título/Descrición:"
 
-#: mod/admin.php:1287
-#, php-format
-msgid "User '%s' blocked"
-msgstr "Usuario '%s' bloqueado'"
+#: mod/profiles.php:715
+msgid "Street Address:"
+msgstr "Dirección"
 
-#: mod/admin.php:1396 mod/admin.php:1422
-msgid "Register date"
-msgstr "Fecha de registro"
+#: mod/profiles.php:716
+msgid "Locality/City:"
+msgstr "Localidad/Ciudad:"
 
-#: mod/admin.php:1396 mod/admin.php:1422
-msgid "Last login"
-msgstr "Último acceso"
+#: mod/profiles.php:717
+msgid "Region/State:"
+msgstr "Región/Estado:"
 
-#: mod/admin.php:1396 mod/admin.php:1422
-msgid "Last item"
-msgstr "Último elemento"
+#: mod/profiles.php:718
+msgid "Postal/Zip Code:"
+msgstr "Código postal:"
 
-#: mod/admin.php:1405
-msgid "Add User"
-msgstr "Agregar usuario"
+#: mod/profiles.php:719
+msgid "Country:"
+msgstr "País"
 
-#: mod/admin.php:1406
-msgid "select all"
-msgstr "seleccionar todo"
+#: mod/profiles.php:723
+msgid "Who: (if applicable)"
+msgstr "¿Quién? (si es aplicable)"
 
-#: mod/admin.php:1407
-msgid "User registrations waiting for confirm"
-msgstr "Registro de usuarios esperando confirmación"
+#: mod/profiles.php:723
+msgid "Examples: cathy123, Cathy Williams, cathy@example.com"
+msgstr "Ejemplos: cathy123, Cathy Williams, cathy@example.com"
 
-#: mod/admin.php:1408
-msgid "User waiting for permanent deletion"
-msgstr "Usuario esperando anulación permanente."
+#: mod/profiles.php:724
+msgid "Since [date]:"
+msgstr "Desde [fecha]:"
 
-#: mod/admin.php:1409
-msgid "Request date"
-msgstr "Solicitud de fecha"
+#: mod/profiles.php:726
+msgid "Tell us about yourself..."
+msgstr "Háblanos sobre ti..."
 
-#: mod/admin.php:1410
-msgid "No registrations."
-msgstr "Sin registros."
+#: mod/profiles.php:727
+msgid "XMPP (Jabber) address:"
+msgstr "Dirección XMPP (Jabber):"
 
-#: mod/admin.php:1411
-msgid "Note from the user"
-msgstr "Nota para el usuario"
+#: mod/profiles.php:727
+msgid ""
+"The XMPP address will be propagated to your contacts so that they can follow"
+" you."
+msgstr "La dirección XMPP será propagada entre sus contactos para que puedan seguirle."
 
-#: mod/admin.php:1413
-msgid "Deny"
-msgstr "Denegado"
+#: mod/profiles.php:728
+msgid "Homepage URL:"
+msgstr "Dirección de tu página:"
 
-#: mod/admin.php:1415 mod/contacts.php:605 mod/contacts.php:805
-#: mod/contacts.php:983
-msgid "Block"
-msgstr "Bloquear"
+#: mod/profiles.php:731
+msgid "Religious Views:"
+msgstr "Creencias religiosas:"
 
-#: mod/admin.php:1416 mod/contacts.php:605 mod/contacts.php:805
-#: mod/contacts.php:983
-msgid "Unblock"
-msgstr "Desbloquear"
+#: mod/profiles.php:732
+msgid "Public Keywords:"
+msgstr "Palabras clave públicas:"
 
-#: mod/admin.php:1417
-msgid "Site admin"
-msgstr "Administrador de la web"
+#: mod/profiles.php:732
+msgid "(Used for suggesting potential friends, can be seen by others)"
+msgstr "(Utilizadas para sugerir amigos potenciales, otros pueden verlo)"
 
-#: mod/admin.php:1418
-msgid "Account expired"
-msgstr "Cuenta caducada"
+#: mod/profiles.php:733
+msgid "Private Keywords:"
+msgstr "Palabras clave privadas:"
 
-#: mod/admin.php:1421
-msgid "New User"
-msgstr "Nuevo usuario"
+#: mod/profiles.php:733
+msgid "(Used for searching profiles, never shown to others)"
+msgstr "(Utilizadas para buscar perfiles, nunca se muestra a otros)"
 
-#: mod/admin.php:1422
-msgid "Deleted since"
-msgstr "Borrado desde"
+#: mod/profiles.php:736
+msgid "Musical interests"
+msgstr "Gustos musicales"
 
-#: mod/admin.php:1427
-msgid ""
-"Selected users will be deleted!\\n\\nEverything these users had posted on "
-"this site will be permanently deleted!\\n\\nAre you sure?"
-msgstr "¡Los usuarios seleccionados serán eliminados!\\n\\n¡Todo lo que hayan publicado en este sitio se borrará para siempre!\\n\\n¿Estás seguro?"
+#: mod/profiles.php:737
+msgid "Books, literature"
+msgstr "Libros, literatura"
 
-#: mod/admin.php:1428
-msgid ""
-"The user {0} will be deleted!\\n\\nEverything this user has posted on this "
-"site will be permanently deleted!\\n\\nAre you sure?"
-msgstr "¡El usuario {0} será eliminado!\\n\\n¡Todo lo que haya publicado en este sitio se borrará para siempre!\\n\\n¿Estás seguro?"
+#: mod/profiles.php:738
+msgid "Television"
+msgstr "Televisión"
 
-#: mod/admin.php:1438
-msgid "Name of the new user."
-msgstr "Nombre del nuevo usuario"
+#: mod/profiles.php:739
+msgid "Film/dance/culture/entertainment"
+msgstr "Películas/baile/cultura/entretenimiento"
 
-#: mod/admin.php:1439
-msgid "Nickname"
-msgstr "Apodo"
+#: mod/profiles.php:740
+msgid "Hobbies/Interests"
+msgstr "Aficiones/Intereses"
 
-#: mod/admin.php:1439
-msgid "Nickname of the new user."
-msgstr "Apodo del nuevo perfil."
+#: mod/profiles.php:741
+msgid "Love/romance"
+msgstr "Amor/Romance"
 
-#: mod/admin.php:1440
-msgid "Email address of the new user."
-msgstr "Dirección de correo del nuevo perfil."
+#: mod/profiles.php:742
+msgid "Work/employment"
+msgstr "Trabajo/ocupación"
 
-#: mod/admin.php:1483
-#, php-format
-msgid "Plugin %s disabled."
-msgstr "Módulo %s deshabilitado."
+#: mod/profiles.php:743
+msgid "School/education"
+msgstr "Escuela/estudios"
 
-#: mod/admin.php:1487
-#, php-format
-msgid "Plugin %s enabled."
-msgstr "Módulo %s habilitado."
+#: mod/profiles.php:744
+msgid "Contact information and Social Networks"
+msgstr "Informacioń de contacto y Redes sociales"
 
-#: mod/admin.php:1498 mod/admin.php:1734
-msgid "Disable"
-msgstr "Desactivado"
+#: mod/profiles.php:788
+msgid "Edit/Manage Profiles"
+msgstr "Editar/Administrar perfiles"
 
-#: mod/admin.php:1500 mod/admin.php:1736
-msgid "Enable"
-msgstr "Activado"
+#: mod/profperm.php:26 mod/profperm.php:57
+msgid "Invalid profile identifier."
+msgstr "Identificador de perfil no válido."
 
-#: mod/admin.php:1523 mod/admin.php:1781
-msgid "Toggle"
-msgstr "Activar"
+#: mod/profperm.php:103
+msgid "Profile Visibility Editor"
+msgstr "Editor de visibilidad del perfil"
 
-#: mod/admin.php:1531 mod/admin.php:1790
-msgid "Author: "
-msgstr "Autor:"
+#: mod/profperm.php:116
+msgid "Visible To"
+msgstr "Visible para"
 
-#: mod/admin.php:1532 mod/admin.php:1791
-msgid "Maintainer: "
-msgstr "Mantenedor: "
+#: mod/profperm.php:132
+msgid "All Contacts (with secure profile access)"
+msgstr "Todos los contactos (con perfil de acceso seguro)"
 
-#: mod/admin.php:1584
-msgid "Reload active plugins"
-msgstr "Recargar plugins activos"
+#: mod/register.php:93
+msgid ""
+"Registration successful. Please check your email for further instructions."
+msgstr "Te has registrado con éxito. Por favor, consulta tu correo para más información."
 
-#: mod/admin.php:1589
+#: mod/register.php:98
 #, php-format
 msgid ""
-"There are currently no plugins available on your node. You can find the "
-"official plugin repository at %1$s and might find other interesting plugins "
-"in the open plugin registry at %2$s"
-msgstr "No ay plugins habilitados en este nodo. Encontrara los repositorios oficiales de plugins en %1$s y posiblemente encontrara mas plugins interesantes en el registro abierto de plugins aquí %2$s ."
-
-#: mod/admin.php:1694
-msgid "No themes found."
-msgstr "No se encontraron temas."
+"Failed to send email message. Here your accout details:<br> login: %s<br> "
+"password: %s<br><br>You can change your password after login."
+msgstr "Error al intentar de enviar mensaje de correo. Aquí los detalles de su cuenta: <br> login: %s<br> contraseña: %s<br><br>Puede cambiar su contraseña después de ingresar al sitio."
 
-#: mod/admin.php:1772
-msgid "Screenshot"
-msgstr "Captura de pantalla"
+#: mod/register.php:105
+msgid "Registration successful."
+msgstr "Registro exitoso."
 
-#: mod/admin.php:1832
-msgid "Reload active themes"
-msgstr "Recargar interfaces de usuario activos"
+#: mod/register.php:111
+msgid "Your registration can not be processed."
+msgstr "Tu registro no se puede procesar."
 
-#: mod/admin.php:1837
-#, php-format
-msgid "No themes found on the system. They should be paced in %1$s"
-msgstr "No se encuentran interfaces en el sistema. Deberían estar localizados (paced) en  %1$s"
+#: mod/register.php:160
+msgid "Your registration is pending approval by the site owner."
+msgstr "Tu registro está pendiente de aprobación por el propietario del sitio."
 
-#: mod/admin.php:1838
-msgid "[Experimental]"
-msgstr "[Experimental]"
+#: mod/register.php:198 mod/uimport.php:51
+msgid ""
+"This site has exceeded the number of allowed daily account registrations. "
+"Please try again tomorrow."
+msgstr "Este sitio ha excedido el número de registros diarios permitidos. Inténtalo de nuevo mañana por favor."
 
-#: mod/admin.php:1839
-msgid "[Unsupported]"
-msgstr "[Sin soporte]"
+#: mod/register.php:226
+msgid ""
+"You may (optionally) fill in this form via OpenID by supplying your OpenID "
+"and clicking 'Register'."
+msgstr "Puedes (opcionalmente) rellenar este formulario a través de OpenID escribiendo tu OpenID y pulsando en \"Registrar\"."
 
-#: mod/admin.php:1863
-msgid "Log settings updated."
-msgstr "Configuración de registro actualizada."
+#: mod/register.php:227
+msgid ""
+"If you are not familiar with OpenID, please leave that field blank and fill "
+"in the rest of the items."
+msgstr "Si no estás familiarizado con OpenID, por favor deja ese campo en blanco y rellena el resto de los elementos."
 
-#: mod/admin.php:1895
-msgid "PHP log currently enabled."
-msgstr "Registro PHP actualmente disponible."
+#: mod/register.php:228
+msgid "Your OpenID (optional): "
+msgstr "Tu OpenID (opcional):"
 
-#: mod/admin.php:1897
-msgid "PHP log currently disabled."
-msgstr "Registro PHP actualmente deshabilitado."
+#: mod/register.php:242
+msgid "Include your profile in member directory?"
+msgstr "¿Incluir tu perfil en el directorio de miembros?"
 
-#: mod/admin.php:1906
-msgid "Clear"
-msgstr "Limpiar"
+#: mod/register.php:267
+msgid "Note for the admin"
+msgstr "Nota para el administrador"
 
-#: mod/admin.php:1911
-msgid "Enable Debugging"
-msgstr "Habilitar debugging"
+#: mod/register.php:267
+msgid "Leave a message for the admin, why you want to join this node"
+msgstr "Deje un mensaje para el administrador sobre por qué quiere unirse a este nodo"
 
-#: mod/admin.php:1912
-msgid "Log file"
-msgstr "Archivo de registro"
+#: mod/register.php:268
+msgid "Membership on this site is by invitation only."
+msgstr "Sitio solo accesible mediante invitación."
 
-#: mod/admin.php:1912
-msgid ""
-"Must be writable by web server. Relative to your Friendica top-level "
-"directory."
-msgstr "Debes tener permiso de escritura en el servidor. Relacionado con tu directorio de inicio de Friendica."
+#: mod/register.php:269
+msgid "Your invitation ID: "
+msgstr "ID de tu invitación: "
 
-#: mod/admin.php:1913
-msgid "Log level"
-msgstr "Nivel de registro"
+#: mod/register.php:280
+msgid "Your Full Name (e.g. Joe Smith, real or real-looking): "
+msgstr "Nombre completo (ej. Joe Smith, real o real aparente):"
 
-#: mod/admin.php:1916
-msgid "PHP logging"
-msgstr "PHP logging"
+#: mod/register.php:281
+msgid "Your Email Address: "
+msgstr "Tu dirección de correo: "
 
-#: mod/admin.php:1917
-msgid ""
-"To enable logging of PHP errors and warnings you can add the following to "
-"the .htconfig.php file of your installation. The filename set in the "
-"'error_log' line is relative to the friendica top-level directory and must "
-"be writeable by the web server. The option '1' for 'log_errors' and "
-"'display_errors' is to enable these options, set to '0' to disable them."
-msgstr "Para habilitar la documentación de los errores PHP y las advertencias se puede agregar lo siguiente al archivo .htconfig.php de la instalación (ftp). La dirección definido en el 'error_log' es relativo al directorio friendica principal (top-level directory) y debe de ser habilitado para la escritura por el servidor web. La opción '1' para 'log_errors' y 'display_errors' es para habilitar estas opciones, '0' para deshabilitarlo."
+#: mod/register.php:283 mod/settings.php:1278
+msgid "New Password:"
+msgstr "Contraseña nueva:"
 
-#: mod/admin.php:2045
-#, php-format
-msgid "Lock feature %s"
-msgstr "Trancar opción %s "
+#: mod/register.php:283
+msgid "Leave empty for an auto generated password."
+msgstr "Dejar vacío para autogenerar una contraseña"
 
-#: mod/admin.php:2053
-msgid "Manage Additional Features"
-msgstr "Administrar opciones adicionales"
+#: mod/register.php:284 mod/settings.php:1279
+msgid "Confirm:"
+msgstr "Confirmar:"
 
-#: mod/contacts.php:128
-#, php-format
-msgid "%d contact edited."
-msgid_plural "%d contacts edited."
-msgstr[0] "%d contacto editado."
-msgstr[1] "%d contacts edited."
+#: mod/register.php:285
+msgid ""
+"Choose a profile nickname. This must begin with a text character. Your "
+"profile address on this site will then be "
+"'<strong>nickname@$sitename</strong>'."
+msgstr "Elije un apodo. Debe comenzar con una letra. Tu dirección de perfil en este sitio va a ser \"<strong>apodo@$nombredelsitio</strong>\"."
 
-#: mod/contacts.php:159 mod/contacts.php:368
-msgid "Could not access contact record."
-msgstr "No se pudo acceder a los datos del contacto."
+#: mod/register.php:286
+msgid "Choose a nickname: "
+msgstr "Escoge un apodo: "
 
-#: mod/contacts.php:173
-msgid "Could not locate selected profile."
-msgstr "No se pudo encontrar el perfil seleccionado."
+#: mod/register.php:295 mod/uimport.php:66
+msgid "Import"
+msgstr "Importar"
 
-#: mod/contacts.php:206
-msgid "Contact updated."
-msgstr "Contacto actualizado."
+#: mod/register.php:296
+msgid "Import your profile to this friendica instance"
+msgstr "Importar tu perfil a esta instancia de friendica"
 
-#: mod/contacts.php:208 mod/dfrn_request.php:583
-msgid "Failed to update contact record."
-msgstr "Error al actualizar el contacto."
+#: mod/regmod.php:58
+msgid "Account approved."
+msgstr "Cuenta aprobada."
 
-#: mod/contacts.php:389
-msgid "Contact has been blocked"
-msgstr "El contacto ha sido bloqueado"
+#: mod/regmod.php:95
+#, php-format
+msgid "Registration revoked for %s"
+msgstr "Registro anulado para %s"
 
-#: mod/contacts.php:389
-msgid "Contact has been unblocked"
-msgstr "El contacto ha sido desbloqueado"
+#: mod/regmod.php:107
+msgid "Please login."
+msgstr "Por favor accede."
 
-#: mod/contacts.php:400
-msgid "Contact has been ignored"
-msgstr "El contacto ha sido ignorado"
+#: mod/removeme.php:52 mod/removeme.php:55
+msgid "Remove My Account"
+msgstr "Eliminar mi cuenta"
 
-#: mod/contacts.php:400
-msgid "Contact has been unignored"
-msgstr "El contacto ya no está ignorado"
+#: mod/removeme.php:53
+msgid ""
+"This will completely remove your account. Once this has been done it is not "
+"recoverable."
+msgstr "Esto eliminará por completo tu cuenta. Una vez hecho no se puede deshacer."
 
-#: mod/contacts.php:412
-msgid "Contact has been archived"
-msgstr "El contacto ha sido archivado"
+#: mod/removeme.php:54
+msgid "Please enter your password for verification:"
+msgstr "Por favor, introduce tu contraseña para la verificación:"
 
-#: mod/contacts.php:412
-msgid "Contact has been unarchived"
-msgstr "El contacto ya no está archivado"
+#: mod/repair_ostatus.php:14
+msgid "Resubscribing to OStatus contacts"
+msgstr "Resubscribir a contactos de OStatus"
 
-#: mod/contacts.php:437
-msgid "Drop contact"
-msgstr "Eliminar contacto"
+#: mod/repair_ostatus.php:30
+msgid "Error"
+msgstr "error"
 
-#: mod/contacts.php:440 mod/contacts.php:801
-msgid "Do you really want to delete this contact?"
-msgstr "¿Estás seguro de que quieres eliminar este contacto?"
+#: mod/search.php:100
+msgid "Only logged in users are permitted to perform a search."
+msgstr "Solo usuarios activos tienen permiso para ejecutar búsquedas."
 
-#: mod/contacts.php:457
-msgid "Contact has been removed."
-msgstr "El contacto ha sido eliminado"
+#: mod/search.php:124
+msgid "Too Many Requests"
+msgstr "Demasiadas consultas"
 
-#: mod/contacts.php:498
-#, php-format
-msgid "You are mutual friends with %s"
-msgstr "Ahora tienes una amistad mutua con %s"
+#: mod/search.php:125
+msgid "Only one search per minute is permitted for not logged in users."
+msgstr "Se permite solo una búsqueda por minuto para usuarios no identificados."
 
-#: mod/contacts.php:502
+#: mod/search.php:230
 #, php-format
-msgid "You are sharing with %s"
-msgstr "Estás compartiendo con %s"
+msgid "Items tagged with: %s"
+msgstr "Objetos taggeado con: %s"
 
-#: mod/contacts.php:507
-#, php-format
-msgid "%s is sharing with you"
-msgstr "%s está compartiendo contigo"
+#: mod/settings.php:60
+msgid "Display"
+msgstr "Interfaz del usuario"
 
-#: mod/contacts.php:527
-msgid "Private communications are not available for this contact."
-msgstr "Las comunicaciones privadas no está disponibles para este contacto."
+#: mod/settings.php:67 mod/settings.php:890
+msgid "Social Networks"
+msgstr "Redes sociales"
 
-#: mod/contacts.php:534
-msgid "(Update was successful)"
-msgstr "(La actualización se ha completado)"
+#: mod/settings.php:88
+msgid "Connected apps"
+msgstr "Aplicaciones conectadas"
 
-#: mod/contacts.php:534
-msgid "(Update was not successful)"
-msgstr "(La actualización no se ha completado)"
+#: mod/settings.php:95 mod/uexport.php:45
+msgid "Export personal data"
+msgstr "Exportación de datos personales"
 
-#: mod/contacts.php:536 mod/contacts.php:964
-msgid "Suggest friends"
-msgstr "Sugerir amigos"
+#: mod/settings.php:102
+msgid "Remove account"
+msgstr "Eliminar cuenta"
 
-#: mod/contacts.php:540
-#, php-format
-msgid "Network type: %s"
-msgstr "Tipo de red: %s"
+#: mod/settings.php:157
+msgid "Missing some important data!"
+msgstr "¡Faltan algunos datos importantes!"
 
-#: mod/contacts.php:553
-msgid "Communications lost with this contact!"
-msgstr "¡Se ha perdido la comunicación con este contacto!"
+#: mod/settings.php:271
+msgid "Failed to connect with email account using the settings provided."
+msgstr "Error al conectar con la cuenta de correo mediante la configuración suministrada."
 
-#: mod/contacts.php:556
-msgid "Fetch further information for feeds"
-msgstr "Recaudar informacion complementaria de los feeds"
+#: mod/settings.php:276
+msgid "Email settings updated."
+msgstr "Configuración de correo actualizada."
 
-#: mod/contacts.php:557
-msgid "Fetch information"
-msgstr "Recaudar informacion"
+#: mod/settings.php:291
+msgid "Features updated"
+msgstr "Actualizaciones"
 
-#: mod/contacts.php:557
-msgid "Fetch information and keywords"
-msgstr "Recaudar informacion y palabras claves"
+#: mod/settings.php:361
+msgid "Relocate message has been send to your contacts"
+msgstr "Mensaje de reubicación ha sido enviado a sus contactos."
 
-#: mod/contacts.php:575
-msgid "Contact"
-msgstr "Contacto"
+#: mod/settings.php:380
+msgid "Empty passwords are not allowed. Password unchanged."
+msgstr "No se permiten contraseñas vacías. La contraseña no ha sido modificada."
 
-#: mod/contacts.php:578
-msgid "Profile Visibility"
-msgstr "Visibilidad del Perfil"
+#: mod/settings.php:388
+msgid "Wrong password."
+msgstr "Contraseña incorrecta"
 
-#: mod/contacts.php:579
-#, php-format
-msgid ""
-"Please choose the profile you would like to display to %s when viewing your "
-"profile securely."
-msgstr "Por favor, selecciona el perfil que quieras mostrar a %s cuando esté viendo tu perfil de forma segura."
+#: mod/settings.php:399
+msgid "Password changed."
+msgstr "Contraseña modificada."
 
-#: mod/contacts.php:580
-msgid "Contact Information / Notes"
-msgstr "Información del Contacto / Notas"
+#: mod/settings.php:401
+msgid "Password update failed. Please try again."
+msgstr "La actualización de la contraseña ha fallado. Por favor, prueba otra vez."
 
-#: mod/contacts.php:581
-msgid "Edit contact notes"
-msgstr "Editar notas del contacto"
+#: mod/settings.php:481
+msgid " Please use a shorter name."
+msgstr " Usa un nombre más corto."
 
-#: mod/contacts.php:587
-msgid "Block/Unblock contact"
-msgstr "Boquear/Desbloquear contacto"
+#: mod/settings.php:483
+msgid " Name too short."
+msgstr " Nombre demasiado corto."
 
-#: mod/contacts.php:588
-msgid "Ignore contact"
-msgstr "Ignorar contacto"
+#: mod/settings.php:492
+msgid "Wrong Password"
+msgstr "Contraseña incorrecta"
 
-#: mod/contacts.php:589
-msgid "Repair URL settings"
-msgstr "Configuración de reparación de la dirección"
+#: mod/settings.php:497
+msgid " Not valid email."
+msgstr " Correo no válido."
 
-#: mod/contacts.php:590
-msgid "View conversations"
-msgstr "Ver conversaciones"
+#: mod/settings.php:503
+msgid " Cannot change to that email."
+msgstr " No se puede usar ese correo."
 
-#: mod/contacts.php:596
-msgid "Last update:"
-msgstr "Última actualización:"
+#: mod/settings.php:559
+msgid "Private forum has no privacy permissions. Using default privacy group."
+msgstr "El foro privado no tiene permisos de privacidad. Usando el grupo de privacidad por defecto."
 
-#: mod/contacts.php:598
-msgid "Update public posts"
-msgstr "Actualizar publicaciones públicas"
+#: mod/settings.php:563
+msgid "Private forum has no privacy permissions and no default privacy group."
+msgstr "El foro privado no tiene permisos de privacidad ni grupo por defecto de privacidad."
 
-#: mod/contacts.php:600 mod/contacts.php:974
-msgid "Update now"
-msgstr "Actualizar ahora"
+#: mod/settings.php:603
+msgid "Settings updated."
+msgstr "Configuración actualizada."
 
-#: mod/contacts.php:606 mod/contacts.php:806 mod/contacts.php:991
-msgid "Unignore"
-msgstr "Quitar de Ignorados"
+#: mod/settings.php:680 mod/settings.php:706 mod/settings.php:742
+msgid "Add application"
+msgstr "Agregar aplicación"
 
-#: mod/contacts.php:610
-msgid "Currently blocked"
-msgstr "Bloqueados"
+#: mod/settings.php:684 mod/settings.php:710
+msgid "Consumer Key"
+msgstr "Clave del consumidor"
 
-#: mod/contacts.php:611
-msgid "Currently ignored"
-msgstr "Ignorados"
+#: mod/settings.php:685 mod/settings.php:711
+msgid "Consumer Secret"
+msgstr "Secreto del consumidor"
 
-#: mod/contacts.php:612
-msgid "Currently archived"
-msgstr "Archivados"
+#: mod/settings.php:686 mod/settings.php:712
+msgid "Redirect"
+msgstr "Redirigir"
 
-#: mod/contacts.php:613
-msgid ""
-"Replies/likes to your public posts <strong>may</strong> still be visible"
-msgstr "Los comentarios o \"me gusta\" en tus publicaciones públicas todavía <strong>pueden</strong> ser visibles."
+#: mod/settings.php:687 mod/settings.php:713
+msgid "Icon url"
+msgstr "Dirección del ícono"
 
-#: mod/contacts.php:614
-msgid "Notification for new posts"
-msgstr "Notificacion de nuevos temas."
+#: mod/settings.php:698
+msgid "You can't edit this application."
+msgstr "No puedes editar esta aplicación."
 
-#: mod/contacts.php:614
-msgid "Send a notification of every new post of this contact"
-msgstr "Enviar una notificacion por nuevos temas de este contacto."
+#: mod/settings.php:741
+msgid "Connected Apps"
+msgstr "Aplicaciones conectadas"
 
-#: mod/contacts.php:617
-msgid "Blacklisted keywords"
-msgstr "Lista negra de palabras"
+#: mod/settings.php:745
+msgid "Client key starts with"
+msgstr "Clave de cliente comienza por"
 
-#: mod/contacts.php:617
-msgid ""
-"Comma separated list of keywords that should not be converted to hashtags, "
-"when \"Fetch information and keywords\" is selected"
-msgstr "Lista separada por comas de palabras claves que no deberian ser convertido en #hashtags cuando \"Recaudar informacion y palabras claves\" es seleccionado"
+#: mod/settings.php:746
+msgid "No name"
+msgstr "Sin nombre"
 
-#: mod/contacts.php:635
-msgid "Actions"
-msgstr "Acciones"
+#: mod/settings.php:747
+msgid "Remove authorization"
+msgstr "Suprimir la autorización"
 
-#: mod/contacts.php:638
-msgid "Contact Settings"
-msgstr "Ajustes del contacto"
+#: mod/settings.php:759
+msgid "No Plugin settings configured"
+msgstr "No se ha configurado ningún módulo"
 
-#: mod/contacts.php:684
-msgid "Suggestions"
-msgstr "Sugerencias"
+#: mod/settings.php:768
+msgid "Plugin Settings"
+msgstr "Configuración de los módulos"
 
-#: mod/contacts.php:687
-msgid "Suggest potential friends"
-msgstr "Amistades potenciales sugeridas"
+#: mod/settings.php:790
+msgid "Additional Features"
+msgstr "Características adicionales"
 
-#: mod/contacts.php:695
-msgid "Show all contacts"
-msgstr "Mostrar todos los contactos"
+#: mod/settings.php:800 mod/settings.php:804
+msgid "General Social Media Settings"
+msgstr "Configuración general de social media "
 
-#: mod/contacts.php:700
-msgid "Unblocked"
-msgstr "Desbloqueados"
+#: mod/settings.php:810
+msgid "Disable intelligent shortening"
+msgstr "Deshabilitar recorte inteligente de URL"
 
-#: mod/contacts.php:703
-msgid "Only show unblocked contacts"
-msgstr "Mostrar solo contactos sin bloquear"
+#: mod/settings.php:812
+msgid ""
+"Normally the system tries to find the best link to add to shortened posts. "
+"If this option is enabled then every shortened post will always point to the"
+" original friendica post."
+msgstr "Normalemente el sistema intenta de encontrara el mejor enlace para agregar a envíos recortados (twitter, OStatus). Si esta opción se encuentra habilitado, todo envío recortado apuntara siempre al tema original en friendica."
 
-#: mod/contacts.php:709
-msgid "Blocked"
-msgstr "Bloqueados"
+#: mod/settings.php:818
+msgid "Automatically follow any GNU Social (OStatus) followers/mentioners"
+msgstr "Automáticamente seguir cualquier GNUsocial (OStatus) seguidores o menciones "
 
-#: mod/contacts.php:712
-msgid "Only show blocked contacts"
-msgstr "Mostrar solo contactos bloqueados"
+#: mod/settings.php:820
+msgid ""
+"If you receive a message from an unknown OStatus user, this option decides "
+"what to do. If it is checked, a new contact will be created for every "
+"unknown user."
+msgstr "Cuando se recibe un mensaje de un perfil desconocido de OStatus, esta opción define que hacer.\nSi es habilitado, un nuevo contacto sera creado para cada usuario."
 
-#: mod/contacts.php:718
-msgid "Ignored"
-msgstr "Ignorados"
+#: mod/settings.php:826
+msgid "Default group for OStatus contacts"
+msgstr "Grupo por defecto para contactos OStatus"
 
-#: mod/contacts.php:721
-msgid "Only show ignored contacts"
-msgstr "Mostrar solo contactos ignorados"
+#: mod/settings.php:834
+msgid "Your legacy GNU Social account"
+msgstr "Tu cuenta GNU social conectada"
 
-#: mod/contacts.php:727
-msgid "Archived"
-msgstr "Archivados"
+#: mod/settings.php:836
+msgid ""
+"If you enter your old GNU Social/Statusnet account name here (in the format "
+"user@domain.tld), your contacts will be added automatically. The field will "
+"be emptied when done."
+msgstr "Si agrega su viejo nombre de perfil  GNUsocial/Statusnet aqui (en el formato de usuario@dominio.tld), sus contactos serán añadidos automáticamente.\nEl campo sera vaciado cuando termine el proceso. "
 
-#: mod/contacts.php:730
-msgid "Only show archived contacts"
-msgstr "Mostrar solo contactos archivados"
+#: mod/settings.php:839
+msgid "Repair OStatus subscriptions"
+msgstr "Reparar subscripciones de OStatus"
 
-#: mod/contacts.php:736
-msgid "Hidden"
-msgstr "Ocultos"
+#: mod/settings.php:848 mod/settings.php:849
+#, php-format
+msgid "Built-in support for %s connectivity is %s"
+msgstr "El soporte integrado de conexión con %s está %s"
 
-#: mod/contacts.php:739
-msgid "Only show hidden contacts"
-msgstr "Mostrar solo contactos ocultos"
+#: mod/settings.php:848 mod/settings.php:849
+msgid "enabled"
+msgstr "habilitado"
 
-#: mod/contacts.php:796
-msgid "Search your contacts"
-msgstr "Buscar en tus contactos"
+#: mod/settings.php:848 mod/settings.php:849
+msgid "disabled"
+msgstr "deshabilitado"
 
-#: mod/contacts.php:807 mod/contacts.php:999
-msgid "Archive"
-msgstr "Archivo"
+#: mod/settings.php:849
+msgid "GNU Social (OStatus)"
+msgstr "GNUsocial (OStatus)"
 
-#: mod/contacts.php:807 mod/contacts.php:999
-msgid "Unarchive"
-msgstr "Sin archivar"
+#: mod/settings.php:883
+msgid "Email access is disabled on this site."
+msgstr "El acceso por correo está deshabilitado en esta web."
 
-#: mod/contacts.php:810
-msgid "Batch Actions"
-msgstr "Accones en lote"
+#: mod/settings.php:895
+msgid "Email/Mailbox Setup"
+msgstr "Configuración del correo/buzón"
 
-#: mod/contacts.php:856
-msgid "View all contacts"
-msgstr "Ver todos los contactos"
+#: mod/settings.php:896
+msgid ""
+"If you wish to communicate with email contacts using this service "
+"(optional), please specify how to connect to your mailbox."
+msgstr "Si quieres comunicarte con tus contactos de correo usando este servicio (opcional), por favor, especifica cómo conectar con tu buzón."
 
-#: mod/contacts.php:866
-msgid "View all common friends"
-msgstr "Ver todos los conocidos en común "
+#: mod/settings.php:897
+msgid "Last successful email check:"
+msgstr "Última comprobación del correo con éxito:"
 
-#: mod/contacts.php:873
-msgid "Advanced Contact Settings"
-msgstr "Configuración avanzada"
+#: mod/settings.php:899
+msgid "IMAP server name:"
+msgstr "Nombre del servidor IMAP:"
 
-#: mod/contacts.php:907
-msgid "Mutual Friendship"
-msgstr "Amistad recíproca"
+#: mod/settings.php:900
+msgid "IMAP port:"
+msgstr "Puerto IMAP:"
 
-#: mod/contacts.php:911
-msgid "is a fan of yours"
-msgstr "es tu fan"
+#: mod/settings.php:901
+msgid "Security:"
+msgstr "Seguridad:"
 
-#: mod/contacts.php:915
-msgid "you are a fan of"
-msgstr "eres fan de"
+#: mod/settings.php:901 mod/settings.php:906
+msgid "None"
+msgstr "Ninguna"
 
-#: mod/contacts.php:985
-msgid "Toggle Blocked status"
-msgstr "Cambiar bloqueados"
+#: mod/settings.php:902
+msgid "Email login name:"
+msgstr "Nombre de usuario:"
 
-#: mod/contacts.php:993
-msgid "Toggle Ignored status"
-msgstr "Cambiar ignorados"
+#: mod/settings.php:903
+msgid "Email password:"
+msgstr "Contraseña:"
 
-#: mod/contacts.php:1001
-msgid "Toggle Archive status"
-msgstr "Cambiar archivados"
+#: mod/settings.php:904
+msgid "Reply-to address:"
+msgstr "Dirección de respuesta:"
 
-#: mod/contacts.php:1009
-msgid "Delete contact"
-msgstr "Eliminar contacto"
+#: mod/settings.php:905
+msgid "Send public posts to all email contacts:"
+msgstr "Enviar publicaciones públicas a todos los contactos de correo:"
 
-#: mod/dfrn_confirm.php:127
-msgid ""
-"This may occasionally happen if contact was requested by both persons and it"
-" has already been approved."
-msgstr "Esto puede ocurrir a veces si la conexión fue solicitada por ambas personas y ya hubiera sido aprobada."
+#: mod/settings.php:906
+msgid "Action after import:"
+msgstr "Acción después de importar:"
 
-#: mod/dfrn_confirm.php:246
-msgid "Response from remote site was not understood."
-msgstr "La respuesta desde el sitio remoto no ha sido entendida."
+#: mod/settings.php:906
+msgid "Move to folder"
+msgstr "Mover a un directorio"
 
-#: mod/dfrn_confirm.php:255 mod/dfrn_confirm.php:260
-msgid "Unexpected response from remote site: "
-msgstr "Respuesta inesperada desde el sitio remoto: "
+#: mod/settings.php:907
+msgid "Move to folder:"
+msgstr "Mover al directorio:"
 
-#: mod/dfrn_confirm.php:269
-msgid "Confirmation completed successfully."
-msgstr "Confirmación completada con éxito."
+#: mod/settings.php:1003
+msgid "Display Settings"
+msgstr "Configuración Tema/Visualización"
 
-#: mod/dfrn_confirm.php:271 mod/dfrn_confirm.php:285 mod/dfrn_confirm.php:292
-msgid "Remote site reported: "
-msgstr "El sito remoto informó: "
+#: mod/settings.php:1009 mod/settings.php:1032
+msgid "Display Theme:"
+msgstr "Utilizar tema:"
 
-#: mod/dfrn_confirm.php:283
-msgid "Temporary failure. Please wait and try again."
-msgstr "Error temporal. Por favor, espere y vuelva a intentarlo."
+#: mod/settings.php:1010
+msgid "Mobile Theme:"
+msgstr "Tema móvil:"
 
-#: mod/dfrn_confirm.php:290
-msgid "Introduction failed or was revoked."
-msgstr "La presentación ha fallado o ha sido anulada."
+#: mod/settings.php:1011
+msgid "Suppress warning of insecure networks"
+msgstr "Suprimir el aviso de redes inseguras"
 
-#: mod/dfrn_confirm.php:419
-msgid "Unable to set contact photo."
-msgstr "Imposible establecer la foto del contacto."
+#: mod/settings.php:1011
+msgid ""
+"Should the system suppress the warning that the current group contains "
+"members of networks that can't receive non public postings."
+msgstr "Debería el sistema suprimir el aviso de que el grupo actual contiene miembros de redes que no pueden recibir publicaciones públicas."
 
-#: mod/dfrn_confirm.php:557
-#, php-format
-msgid "No user record found for '%s' "
-msgstr "No se ha encontrado a ningún '%s' "
+#: mod/settings.php:1012
+msgid "Update browser every xx seconds"
+msgstr "Actualizar navegador cada xx segundos"
 
-#: mod/dfrn_confirm.php:567
-msgid "Our site encryption key is apparently messed up."
-msgstr "Nuestra clave de cifrado del sitio es aparentemente un lío."
+#: mod/settings.php:1012
+msgid "Minimum of 10 seconds. Enter -1 to disable it."
+msgstr "Minimo 10 segundos. Ingrese -1 para deshabilitar."
 
-#: mod/dfrn_confirm.php:578
-msgid "Empty site URL was provided or URL could not be decrypted by us."
-msgstr "Se ha proporcionado una dirección vacía o no hemos podido descifrarla."
+#: mod/settings.php:1013
+msgid "Number of items to display per page:"
+msgstr "Número de elementos a mostrar por página:"
 
-#: mod/dfrn_confirm.php:599
-msgid "Contact record was not found for you on our site."
-msgstr "El contacto no se ha encontrado en nuestra base de datos."
+#: mod/settings.php:1013 mod/settings.php:1014
+msgid "Maximum of 100 items"
+msgstr "Máximo 100 elementos"
 
-#: mod/dfrn_confirm.php:613
-#, php-format
-msgid "Site public key not available in contact record for URL %s."
-msgstr "La clave pública del sitio no está disponible en los datos del contacto para %s."
+#: mod/settings.php:1014
+msgid "Number of items to display per page when viewed from mobile device:"
+msgstr "Cantidad de objetos a visualizar cuando se usa un movil"
 
-#: mod/dfrn_confirm.php:633
-msgid ""
-"The ID provided by your system is a duplicate on our system. It should work "
-"if you try again."
-msgstr "La identificación proporcionada por el sistema es un duplicado de nuestro sistema. Debería funcionar si lo intentas de nuevo."
+#: mod/settings.php:1015
+msgid "Don't show emoticons"
+msgstr "No mostrar emoticones"
 
-#: mod/dfrn_confirm.php:644
-msgid "Unable to set your contact credentials on our system."
-msgstr "No se puede establecer las credenciales de tu contacto en nuestro sistema."
+#: mod/settings.php:1016
+msgid "Calendar"
+msgstr "Calendario"
 
-#: mod/dfrn_confirm.php:703
-msgid "Unable to update your contact profile details on our system"
-msgstr "No se puede actualizar los datos de tu perfil de contacto en nuestro sistema"
+#: mod/settings.php:1017
+msgid "Beginning of week:"
+msgstr "Principio de la semana:"
 
-#: mod/dfrn_confirm.php:775
-#, php-format
-msgid "%1$s has joined %2$s"
-msgstr "%1$s se ha unido a %2$s"
+#: mod/settings.php:1018
+msgid "Don't show notices"
+msgstr "No mostrara avisos"
 
-#: mod/dfrn_request.php:101
-msgid "This introduction has already been accepted."
-msgstr "Esta presentación ya ha sido aceptada."
+#: mod/settings.php:1019
+msgid "Infinite scroll"
+msgstr "pagina infinita (sroll)"
 
-#: mod/dfrn_request.php:124 mod/dfrn_request.php:520
-msgid "Profile location is not valid or does not contain profile information."
-msgstr "La dirección del perfil no es válida o no contiene información del perfil."
+#: mod/settings.php:1020
+msgid "Automatic updates only at the top of the network page"
+msgstr "Actualizaciones automaticas solo estando al principio de la pagina"
 
-#: mod/dfrn_request.php:129 mod/dfrn_request.php:525
-msgid "Warning: profile location has no identifiable owner name."
-msgstr "Aviso: La dirección del perfil no tiene un nombre de propietario identificable."
+#: mod/settings.php:1021
+msgid "Bandwith Saver Mode"
+msgstr "Modo de guardado de ancho de banda"
 
-#: mod/dfrn_request.php:131 mod/dfrn_request.php:527
-msgid "Warning: profile location has no profile photo."
-msgstr "Aviso: la dirección del perfil no tiene foto de perfil."
+#: mod/settings.php:1021
+msgid ""
+"When enabled, embedded content is not displayed on automatic updates, they "
+"only show on page reload."
+msgstr "Cuando está habilitado, el contenido incrustado no se muestra en las actualizaciones automáticas, sólo en las páginas recargadas."
 
-#: mod/dfrn_request.php:134 mod/dfrn_request.php:530
-#, php-format
-msgid "%d required parameter was not found at the given location"
-msgid_plural "%d required parameters were not found at the given location"
-msgstr[0] "no se encontró %d parámetro requerido en el lugar determinado"
-msgstr[1] "no se encontraron %d parámetros requeridos en el lugar determinado"
+#: mod/settings.php:1023
+msgid "General Theme Settings"
+msgstr "Ajustes generales de tema"
 
-#: mod/dfrn_request.php:180
-msgid "Introduction complete."
-msgstr "Presentación completa."
+#: mod/settings.php:1024
+msgid "Custom Theme Settings"
+msgstr "Ajustes personalizados de tema"
 
-#: mod/dfrn_request.php:222
-msgid "Unrecoverable protocol error."
-msgstr "Error de protocolo irrecuperable."
+#: mod/settings.php:1025
+msgid "Content Settings"
+msgstr "Ajustes de contenido"
 
-#: mod/dfrn_request.php:250
-msgid "Profile unavailable."
-msgstr "Perfil no disponible."
+#: mod/settings.php:1026 view/theme/duepuntozero/config.php:63
+#: view/theme/frio/config.php:66 view/theme/quattro/config.php:69
+#: view/theme/vier/config.php:114
+msgid "Theme settings"
+msgstr "Configuración del Tema"
 
-#: mod/dfrn_request.php:277
-#, php-format
-msgid "%s has received too many connection requests today."
-msgstr "%s ha recibido demasiadas solicitudes de conexión hoy."
+#: mod/settings.php:1110
+msgid "Account Types"
+msgstr "Tipos de cuenta"
 
-#: mod/dfrn_request.php:278
-msgid "Spam protection measures have been invoked."
-msgstr "Han sido activadas las medidas de protección contra spam."
+#: mod/settings.php:1111
+msgid "Personal Page Subtypes"
+msgstr "Subtipos de página personal"
 
-#: mod/dfrn_request.php:279
-msgid "Friends are advised to please try again in 24 hours."
-msgstr "Tus amigos serán avisados para que lo intenten de nuevo pasadas 24 horas."
+#: mod/settings.php:1112
+msgid "Community Forum Subtypes"
+msgstr "Subtipos de foro de comunidad"
 
-#: mod/dfrn_request.php:341
-msgid "Invalid locator"
-msgstr "Localizador no válido"
+#: mod/settings.php:1119
+msgid "Personal Page"
+msgstr "Página personal"
 
-#: mod/dfrn_request.php:350
-msgid "Invalid email address."
-msgstr "Dirección de correo incorrecta"
+#: mod/settings.php:1120
+msgid "This account is a regular personal profile"
+msgstr "Esta cuenta es un perfil personal corriente"
 
-#: mod/dfrn_request.php:375
-msgid "This account has not been configured for email. Request failed."
-msgstr "Esta cuenta no ha sido configurada para el correo. Fallo de solicitud."
+#: mod/settings.php:1123
+msgid "Organisation Page"
+msgstr "Página de organización"
 
-#: mod/dfrn_request.php:478
-msgid "You have already introduced yourself here."
-msgstr "Ya te has presentado aquí."
+#: mod/settings.php:1124
+msgid "This account is a profile for an organisation"
+msgstr "Esta cuenta es un perfil de una organización"
 
-#: mod/dfrn_request.php:482
-#, php-format
-msgid "Apparently you are already friends with %s."
-msgstr "Al parecer, ya eres amigo de %s."
+#: mod/settings.php:1127
+msgid "News Page"
+msgstr "Página de noticias"
 
-#: mod/dfrn_request.php:503
-msgid "Invalid profile URL."
-msgstr "Dirección de perfil no válida."
+#: mod/settings.php:1128
+msgid "This account is a news account/reflector"
+msgstr "Esta cuenta es una cuenta de noticias/reflectora"
 
-#: mod/dfrn_request.php:604
-msgid "Your introduction has been sent."
-msgstr "Tu presentación ha sido enviada."
+#: mod/settings.php:1131
+msgid "Community Forum"
+msgstr "Foro de la comunidad"
 
-#: mod/dfrn_request.php:644
+#: mod/settings.php:1132
 msgid ""
-"Remote subscription can't be done for your network. Please subscribe "
-"directly on your system."
-msgstr "La subscripción remota no se podrá hacer para tu red. Por favor contacta directamente desde tu sistema."
+"This account is a community forum where people can discuss with each other"
+msgstr "Esta cuenta es un foro de comunidad donde la gente puede debatir con otros"
 
-#: mod/dfrn_request.php:664
-msgid "Please login to confirm introduction."
-msgstr "Inicia sesión para confirmar la presentación."
+#: mod/settings.php:1135
+msgid "Normal Account Page"
+msgstr "Página de cuenta normal"
 
-#: mod/dfrn_request.php:674
-msgid ""
-"Incorrect identity currently logged in. Please login to "
-"<strong>this</strong> profile."
-msgstr "Sesión iniciada con la identificación incorrecta. Entra en <strong>este</strong> perfil."
+#: mod/settings.php:1136
+msgid "This account is a normal personal profile"
+msgstr "Esta cuenta es el perfil personal normal"
 
-#: mod/dfrn_request.php:688 mod/dfrn_request.php:705
-msgid "Confirm"
-msgstr "Confirmar"
+#: mod/settings.php:1139
+msgid "Soapbox Page"
+msgstr "Página de tribuna"
 
-#: mod/dfrn_request.php:700
-msgid "Hide this contact"
-msgstr "Ocultar este contacto"
+#: mod/settings.php:1140
+msgid "Automatically approve all connection/friend requests as read-only fans"
+msgstr "Acepta automáticamente todas las peticiones de conexión/amistad como seguidores de solo-lectura"
 
-#: mod/dfrn_request.php:703
-#, php-format
-msgid "Welcome home %s."
-msgstr "Bienvenido a casa %s"
+#: mod/settings.php:1143
+msgid "Public Forum"
+msgstr "Foro público"
+
+#: mod/settings.php:1144
+msgid "Automatically approve all contact requests"
+msgstr "Aprovar autimáticamente todas las solicitudes de contacto"
 
-#: mod/dfrn_request.php:704
-#, php-format
-msgid "Please confirm your introduction/connection request to %s."
-msgstr "Por favor, confirma tu solicitud de presentación/conexión con %s."
+#: mod/settings.php:1147
+msgid "Automatic Friend Page"
+msgstr "Página de Amistad autómatica"
 
-#: mod/dfrn_request.php:833
-msgid ""
-"Please enter your 'Identity Address' from one of the following supported "
-"communications networks:"
-msgstr "Por favor introduce tu dirección ID de una de las siguientes redes sociales soportadas:"
+#: mod/settings.php:1148
+msgid "Automatically approve all connection/friend requests as friends"
+msgstr "Aceptar automáticamente todas las solicitudes de conexión/amistad como amigos"
 
-#: mod/dfrn_request.php:854
-#, php-format
-msgid ""
-"If you are not yet a member of the free social web, <a "
-"href=\"%s/siteinfo\">follow this link to find a public Friendica site and "
-"join us today</a>."
-msgstr "Si aun no eres miembro de la red social libre  <a href=\"%s/siteinfo\">seguí este enlace para encontrara un sitio disponible de friendica y acompañanos hoy mismo</a>"
+#: mod/settings.php:1151
+msgid "Private Forum [Experimental]"
+msgstr "Foro privado [Experimental]"
 
-#: mod/dfrn_request.php:859
-msgid "Friend/Connection Request"
-msgstr "Solicitud de Amistad/Conexión"
+#: mod/settings.php:1152
+msgid "Private forum - approved members only"
+msgstr "Foro privado - solo miembros"
 
-#: mod/dfrn_request.php:860
-msgid ""
-"Examples: jojo@demo.friendica.com, http://demo.friendica.com/profile/jojo, "
-"testuser@identi.ca"
-msgstr "Ejemplos: jojo@demo.friendica.com, http://demo.friendica.com/profile/jojo, testuser@identi.ca"
+#: mod/settings.php:1163
+msgid "OpenID:"
+msgstr "OpenID:"
 
-#: mod/dfrn_request.php:861 mod/follow.php:109
-msgid "Please answer the following:"
-msgstr "Por favor responde lo siguiente:"
+#: mod/settings.php:1163
+msgid "(Optional) Allow this OpenID to login to this account."
+msgstr "(Opcional) Permitir a este OpenID acceder a esta cuenta."
 
-#: mod/dfrn_request.php:862 mod/follow.php:110
-#, php-format
-msgid "Does %s know you?"
-msgstr "¿%s te conoce?"
+#: mod/settings.php:1171
+msgid "Publish your default profile in your local site directory?"
+msgstr "¿Quieres publicar tu perfil predeterminado en el directorio local del sitio?"
 
-#: mod/dfrn_request.php:866 mod/follow.php:111
-msgid "Add a personal note:"
-msgstr "Añade una nota personal:"
+#: mod/settings.php:1177
+msgid "Publish your default profile in the global social directory?"
+msgstr "¿Quieres publicar tu perfil predeterminado en el directorio social de forma global?"
 
-#: mod/dfrn_request.php:869
-msgid "StatusNet/Federated Social Web"
-msgstr "StatusNet/Web Social Federada"
+#: mod/settings.php:1184
+msgid "Hide your contact/friend list from viewers of your default profile?"
+msgstr "¿Quieres ocultar tu lista de contactos/amigos en la vista de tu perfil predeterminado?"
 
-#: mod/dfrn_request.php:871
-#, php-format
+#: mod/settings.php:1188
 msgid ""
-" - please do not use this form.  Instead, enter %s into your Diaspora search"
-" bar."
-msgstr "(En vez de usar este formulario, introduce %s en la barra de búsqueda de Diaspora."
+"If enabled, posting public messages to Diaspora and other networks isn't "
+"possible."
+msgstr "Si habilitado, enviar temas públicos a  a Diaspora* y otras redes no es posible. "
 
-#: mod/dfrn_request.php:872 mod/follow.php:117
-msgid "Your Identity Address:"
-msgstr "Dirección de tu perfil:"
+#: mod/settings.php:1193
+msgid "Allow friends to post to your profile page?"
+msgstr "¿Permites que tus amigos publiquen en tu página de perfil?"
 
-#: mod/dfrn_request.php:875 mod/follow.php:19
-msgid "Submit Request"
-msgstr "Enviar solicitud"
+#: mod/settings.php:1198
+msgid "Allow friends to tag your posts?"
+msgstr "¿Permites a los amigos etiquetar tus publicaciones?"
 
-#: mod/follow.php:30
-msgid "You already added this contact."
-msgstr "Ya has añadido este contacto."
+#: mod/settings.php:1203
+msgid "Allow us to suggest you as a potential friend to new members?"
+msgstr "¿Nos permite recomendarte como amigo potencial a los nuevos miembros?"
 
-#: mod/follow.php:39
-msgid "Diaspora support isn't enabled. Contact can't be added."
-msgstr "El soporte de Diaspora* no esta habilitado, el contacto no puede ser agregado."
+#: mod/settings.php:1208
+msgid "Permit unknown people to send you private mail?"
+msgstr "¿Permites que desconocidos te manden correos privados?"
 
-#: mod/follow.php:46
-msgid "OStatus support is disabled. Contact can't be added."
-msgstr "El soporte de OStatus no esta habilitado, el contacto no puede ser agregado."
+#: mod/settings.php:1216
+msgid "Profile is <strong>not published</strong>."
+msgstr "El perfil <strong>no está publicado</strong>."
 
-#: mod/follow.php:53
-msgid "The network type couldn't be detected. Contact can't be added."
-msgstr "No se pudo detectar el tipo de red. Contacto no puede ser agregado."
+#: mod/settings.php:1224
+#, php-format
+msgid "Your Identity Address is <strong>'%s'</strong> or '%s'."
+msgstr "Su dirección de identidad es <strong>'%s'</strong> o '%s'."
 
-#: mod/follow.php:180
-msgid "Contact added"
-msgstr "Contacto añadido"
+#: mod/settings.php:1231
+msgid "Automatically expire posts after this many days:"
+msgstr "Las publicaciones expirarán automáticamente después de estos días:"
 
-#: mod/install.php:139
-msgid "Friendica Communications Server - Setup"
-msgstr "Servidor de comunicación Friendica - Configuración"
+#: mod/settings.php:1231
+msgid "If empty, posts will not expire. Expired posts will be deleted"
+msgstr "Si lo dejas vacío no expirarán nunca. Las publicaciones que hayan expirado se borrarán"
 
-#: mod/install.php:145
-msgid "Could not connect to database."
-msgstr "No es posible la conexión con la base de datos."
+#: mod/settings.php:1232
+msgid "Advanced expiration settings"
+msgstr "Configuración avanzada de expiración"
 
-#: mod/install.php:149
-msgid "Could not create table."
-msgstr "No se puede crear la tabla."
+#: mod/settings.php:1233
+msgid "Advanced Expiration"
+msgstr "Expiración avanzada"
 
-#: mod/install.php:155
-msgid "Your Friendica site database has been installed."
-msgstr "La base de datos de su sitio web de Friendica ha sido instalada."
+#: mod/settings.php:1234
+msgid "Expire posts:"
+msgstr "¿Expiran las publicaciones?"
 
-#: mod/install.php:160
-msgid ""
-"You may need to import the file \"database.sql\" manually using phpmyadmin "
-"or mysql."
-msgstr "Puede que tengas que importar el archivo \"Database.sql\" manualmente usando phpmyadmin o mysql."
+#: mod/settings.php:1235
+msgid "Expire personal notes:"
+msgstr "¿Expiran las notas personales?"
 
-#: mod/install.php:161 mod/install.php:230 mod/install.php:607
-msgid "Please see the file \"INSTALL.txt\"."
-msgstr "Por favor, consulta el archivo \"INSTALL.txt\"."
+#: mod/settings.php:1236
+msgid "Expire starred posts:"
+msgstr "¿Expiran los favoritos?"
 
-#: mod/install.php:173
-msgid "Database already in use."
-msgstr "Base de datos ya se encuentra en uso"
+#: mod/settings.php:1237
+msgid "Expire photos:"
+msgstr "¿Expiran las fotografías?"
 
-#: mod/install.php:227
-msgid "System check"
-msgstr "Verificación del sistema"
+#: mod/settings.php:1238
+msgid "Only expire posts by others:"
+msgstr "Solo expiran los mensajes de los demás:"
 
-#: mod/install.php:232
-msgid "Check again"
-msgstr "Compruebalo de nuevo"
+#: mod/settings.php:1269
+msgid "Account Settings"
+msgstr "Configuración de la cuenta"
 
-#: mod/install.php:251
-msgid "Database connection"
-msgstr "Conexión con la base de datos"
+#: mod/settings.php:1277
+msgid "Password Settings"
+msgstr "Configuración de la contraseña"
 
-#: mod/install.php:252
-msgid ""
-"In order to install Friendica we need to know how to connect to your "
-"database."
-msgstr "Con el fin de poder instalar Friendica, necesitamos saber cómo conectar con tu base de datos."
+#: mod/settings.php:1279
+msgid "Leave password fields blank unless changing"
+msgstr "Deja la contraseña en blanco si no quieres cambiarla"
 
-#: mod/install.php:253
-msgid ""
-"Please contact your hosting provider or site administrator if you have "
-"questions about these settings."
-msgstr "Por favor, contacta con tu proveedor de servicios o con el administrador de la página si tienes alguna pregunta sobre estas configuraciones."
+#: mod/settings.php:1280
+msgid "Current Password:"
+msgstr "Contraseña actual:"
 
-#: mod/install.php:254
-msgid ""
-"The database you specify below should already exist. If it does not, please "
-"create it before continuing."
-msgstr "La base de datos que especifiques a continuación debería existir ya. Si no es el caso, debes crearla antes de continuar."
+#: mod/settings.php:1280 mod/settings.php:1281
+msgid "Your current password to confirm the changes"
+msgstr "Su contraseña actual para confirmar los cambios."
 
-#: mod/install.php:258
-msgid "Database Server Name"
-msgstr "Nombre del servidor de la base de datos"
+#: mod/settings.php:1281
+msgid "Password:"
+msgstr "Contraseña:"
 
-#: mod/install.php:259
-msgid "Database Login Name"
-msgstr "Usuario de la base de datos"
+#: mod/settings.php:1285
+msgid "Basic Settings"
+msgstr "Configuración básica"
 
-#: mod/install.php:260
-msgid "Database Login Password"
-msgstr "Contraseña de la base de datos"
+#: mod/settings.php:1287
+msgid "Email Address:"
+msgstr "Dirección de correo:"
 
-#: mod/install.php:261
-msgid "Database Name"
-msgstr "Nombre de la base de datos"
+#: mod/settings.php:1288
+msgid "Your Timezone:"
+msgstr "Zona horaria:"
 
-#: mod/install.php:262 mod/install.php:303
-msgid "Site administrator email address"
-msgstr "Dirección de correo del administrador de la web"
+#: mod/settings.php:1289
+msgid "Your Language:"
+msgstr "Tu idioma:"
 
-#: mod/install.php:262 mod/install.php:303
+#: mod/settings.php:1289
 msgid ""
-"Your account email address must match this in order to use the web admin "
-"panel."
-msgstr "La dirección de correo de tu cuenta debe coincidir con esta para poder usar el panel de administración de la web."
+"Set the language we use to show you friendica interface and to send you "
+"emails"
+msgstr "Selecciona el idioma que se usara para la interfaz del usuario y para el envío de correo."
 
-#: mod/install.php:266 mod/install.php:306
-msgid "Please select a default timezone for your website"
-msgstr "Por favor, selecciona la zona horaria predeterminada para tu web"
+#: mod/settings.php:1290
+msgid "Default Post Location:"
+msgstr "Localización predeterminada:"
 
-#: mod/install.php:293
-msgid "Site settings"
-msgstr "Configuración de la página web"
+#: mod/settings.php:1291
+msgid "Use Browser Location:"
+msgstr "Usar localización del navegador:"
 
-#: mod/install.php:307
-msgid "System Language:"
-msgstr "Sistema de idioma:"
+#: mod/settings.php:1294
+msgid "Security and Privacy Settings"
+msgstr "Configuración de seguridad y privacidad"
 
-#: mod/install.php:307
-msgid ""
-"Set the default language for your Friendica installation interface and to "
-"send emails."
-msgstr "Seleccione el idioma por defecto para su interfaz de instalación de Friendica y para enviar emails."
+#: mod/settings.php:1296
+msgid "Maximum Friend Requests/Day:"
+msgstr "Máximo número de peticiones de amistad por día:"
 
-#: mod/install.php:347
-msgid "Could not find a command line version of PHP in the web server PATH."
-msgstr "No se pudo encontrar una versión de la línea de comandos de PHP en la ruta del servidor web."
+#: mod/settings.php:1296 mod/settings.php:1326
+msgid "(to prevent spam abuse)"
+msgstr "(para prevenir el abuso de spam)"
 
-#: mod/install.php:348
-msgid ""
-"If you don't have a command line version of PHP installed on server, you "
-"will not be able to run background polling via cron. See <a "
-"href='https://github.com/friendica/friendica/blob/master/doc/Install.md#set-"
-"up-the-poller'>'Setup the poller'</a>"
-msgstr "Si no tienes una versión de command line de php installado en el servidor, no sera posible de efectuar polling como trabajo de fondo a traves de cron. Vea <a href='https://github.com/friendica/friendica/blob/master/doc/Install.md#set-up-the-poller'>'Setup the poller'</a>"
+#: mod/settings.php:1297
+msgid "Default Post Permissions"
+msgstr "Permisos por defecto para las publicaciones"
 
-#: mod/install.php:352
-msgid "PHP executable path"
-msgstr "Dirección al ejecutable PHP"
+#: mod/settings.php:1298
+msgid "(click to open/close)"
+msgstr "(pulsa para abrir/cerrar)"
 
-#: mod/install.php:352
-msgid ""
-"Enter full path to php executable. You can leave this blank to continue the "
-"installation."
-msgstr "Introduce la ruta completa al ejecutable php. Puedes dejarlo en blanco y seguir con la instalación."
+#: mod/settings.php:1309
+msgid "Default Private Post"
+msgstr "Publicación Privada por defecto"
 
-#: mod/install.php:357
-msgid "Command line PHP"
-msgstr "Línea de comandos PHP"
+#: mod/settings.php:1310
+msgid "Default Public Post"
+msgstr "Publicación Pública por defecto"
 
-#: mod/install.php:366
-msgid "PHP executable is not the php cli binary (could be cgi-fgci version)"
-msgstr "El ejecutable PHP no es e lphp cli binary (podria ser versión cgi-fgci)"
+#: mod/settings.php:1314
+msgid "Default Permissions for New Posts"
+msgstr "Permisos por defecto para nuevas publicaciones"
 
-#: mod/install.php:367
-msgid "Found PHP version: "
-msgstr "Versión PHP encontrada:"
+#: mod/settings.php:1326
+msgid "Maximum private messages per day from unknown people:"
+msgstr "Número máximo de mensajes diarios para desconocidos:"
+
+#: mod/settings.php:1329
+msgid "Notification Settings"
+msgstr "Configuración de notificaciones"
+
+#: mod/settings.php:1330
+msgid "By default post a status message when:"
+msgstr "Publicar en tu estado cuando:"
+
+#: mod/settings.php:1331
+msgid "accepting a friend request"
+msgstr "aceptes una solicitud de amistad"
 
-#: mod/install.php:369
-msgid "PHP cli binary"
-msgstr "PHP cli binario"
+#: mod/settings.php:1332
+msgid "joining a forum/community"
+msgstr "te unas a un foro/comunidad"
 
-#: mod/install.php:380
-msgid ""
-"The command line version of PHP on your system does not have "
-"\"register_argc_argv\" enabled."
-msgstr "La versión en línea de comandos de PHP en tu sistema no tiene \"register_argc_argv\" habilitado."
+#: mod/settings.php:1333
+msgid "making an <em>interesting</em> profile change"
+msgstr "hagas un cambio <em>interesante</em> en tu perfil"
 
-#: mod/install.php:381
-msgid "This is required for message delivery to work."
-msgstr "Esto es necesario para que funcione la entrega de mensajes."
+#: mod/settings.php:1334
+msgid "Send a notification email when:"
+msgstr "Enviar notificación por correo cuando:"
 
-#: mod/install.php:383
-msgid "PHP register_argc_argv"
-msgstr "PHP register_argc_argv"
+#: mod/settings.php:1335
+msgid "You receive an introduction"
+msgstr "Recibas una presentación"
 
-#: mod/install.php:404
-msgid ""
-"Error: the \"openssl_pkey_new\" function on this system is not able to "
-"generate encryption keys"
-msgstr "Error:  La función \"openssl_pkey_new\" en este sistema no es capaz de generar claves de cifrado"
+#: mod/settings.php:1336
+msgid "Your introductions are confirmed"
+msgstr "Tu presentación sea confirmada"
 
-#: mod/install.php:405
-msgid ""
-"If running under Windows, please see "
-"\"http://www.php.net/manual/en/openssl.installation.php\"."
-msgstr "Si se ejecuta en Windows, por favor consulta la sección \"http://www.php.net/manual/en/openssl.installation.php\"."
+#: mod/settings.php:1337
+msgid "Someone writes on your profile wall"
+msgstr "Alguien escriba en el muro de mi perfil"
 
-#: mod/install.php:407
-msgid "Generate encryption keys"
-msgstr "Generar claves de encriptación"
+#: mod/settings.php:1338
+msgid "Someone writes a followup comment"
+msgstr "Algien escriba en un comentario que sigo"
 
-#: mod/install.php:414
-msgid "libCurl PHP module"
-msgstr "Módulo PHP libCurl"
+#: mod/settings.php:1339
+msgid "You receive a private message"
+msgstr "Recibas un mensaje privado"
 
-#: mod/install.php:415
-msgid "GD graphics PHP module"
-msgstr "Módulo PHP gráficos GD"
+#: mod/settings.php:1340
+msgid "You receive a friend suggestion"
+msgstr "Recibas una sugerencia de amistad"
 
-#: mod/install.php:416
-msgid "OpenSSL PHP module"
-msgstr "Módulo PHP OpenSSL"
+#: mod/settings.php:1341
+msgid "You are tagged in a post"
+msgstr "Seas etiquetado en una publicación"
 
-#: mod/install.php:417
-msgid "mysqli PHP module"
-msgstr "Módulo PHP mysqli"
+#: mod/settings.php:1342
+msgid "You are poked/prodded/etc. in a post"
+msgstr "Te han tocado/empujado/etc. en una publicación"
 
-#: mod/install.php:418
-msgid "mb_string PHP module"
-msgstr "Módulo PHP mb_string"
+#: mod/settings.php:1344
+msgid "Activate desktop notifications"
+msgstr "Activar notificaciones en pantalla."
 
-#: mod/install.php:419
-msgid "mcrypt PHP module"
-msgstr "modulo mycrypt PHP"
+#: mod/settings.php:1344
+msgid "Show desktop popup on new notifications"
+msgstr "Mostrar notificaciones emergentes en caso de nuevos eventos."
 
-#: mod/install.php:420
-msgid "XML PHP module"
-msgstr "Módulo XML PHP"
+#: mod/settings.php:1346
+msgid "Text-only notification emails"
+msgstr "Notificaciones e-mail de solo texto"
 
-#: mod/install.php:421
-msgid "iconv module"
-msgstr "Módulo iconv"
+#: mod/settings.php:1348
+msgid "Send text only notification emails, without the html part"
+msgstr "Enviar las notificaciones por correo con formato de solo texto sin html."
 
-#: mod/install.php:425 mod/install.php:427
-msgid "Apache mod_rewrite module"
-msgstr "Módulo mod_rewrite de Apache"
+#: mod/settings.php:1350
+msgid "Advanced Account/Page Type Settings"
+msgstr "Configuración avanzada de tipo de Cuenta/Página"
 
-#: mod/install.php:425
-msgid ""
-"Error: Apache webserver mod-rewrite module is required but not installed."
-msgstr "Error: El módulo de Apache mod-rewrite es necesario pero no está instalado."
+#: mod/settings.php:1351
+msgid "Change the behaviour of this account for special situations"
+msgstr "Cambiar el comportamiento de esta cuenta para situaciones especiales"
 
-#: mod/install.php:433
-msgid "Error: libCURL PHP module required but not installed."
-msgstr "Error: El módulo de PHP libcurl es necesario, pero no está instalado."
+#: mod/settings.php:1354
+msgid "Relocate"
+msgstr "Relocalizar"
 
-#: mod/install.php:437
+#: mod/settings.php:1355
 msgid ""
-"Error: GD graphics PHP module with JPEG support required but not installed."
-msgstr "Error: El módulo de de PHP gráficos GD con soporte JPEG es necesario, pero no está instalado."
+"If you have moved this profile from another server, and some of your "
+"contacts don't receive your updates, try pushing this button."
+msgstr "Si ha migrado este perfil desde otro servidor aquí y algunos contactos no reciben sus publicaciones intente  recomunicar su ubicación a traves este botón. (Como para decir el botón de los botones)"
 
-#: mod/install.php:441
-msgid "Error: openssl PHP module required but not installed."
-msgstr "Error: El módulo de PHP openssl es necesario, pero  no está instalado."
+#: mod/settings.php:1356
+msgid "Resend relocate message to contacts"
+msgstr "Reenviar mensaje de relocalización a los contactos"
 
-#: mod/install.php:445
-msgid "Error: mysqli PHP module required but not installed."
-msgstr "Error: El módulo de PHP mysqli es necesario, pero no está instalado."
+#: mod/subthread.php:104
+#, php-format
+msgid "%1$s is following %2$s's %3$s"
+msgstr "%1$s está siguiendo las %3$s de %2$s"
 
-#: mod/install.php:449
-msgid "Error: mb_string PHP module required but not installed."
-msgstr "Error: El módulo de PHP mb_string es necesario, pero no está instalado."
+#: mod/suggest.php:27
+msgid "Do you really want to delete this suggestion?"
+msgstr "¿Estás seguro de que quieres borrar esta sugerencia?"
 
-#: mod/install.php:453
-msgid "Error: mcrypt PHP module required but not installed."
-msgstr "Error: modulo mycrypt PHP requerido pero no instalado."
+#: mod/suggest.php:71
+msgid ""
+"No suggestions available. If this is a new site, please try again in 24 "
+"hours."
+msgstr "No hay sugerencias disponibles. Si el sitio web es nuevo inténtalo de nuevo dentro de 24 horas."
 
-#: mod/install.php:457
-msgid "Error: iconv PHP module required but not installed."
-msgstr "Error: módulo iconv PHP requerido pero no instalado."
+#: mod/suggest.php:84 mod/suggest.php:104
+msgid "Ignore/Hide"
+msgstr "Ignorar/Ocultar"
 
-#: mod/install.php:466
-msgid ""
-"If you are using php_cli, please make sure that mcrypt module is enabled in "
-"its config file"
-msgstr "Si está utilizando php_cli, por favor asegúrese de que el módulo mcrypt está habilitado en este archivo de configuración"
+#: mod/tagrm.php:43
+msgid "Tag removed"
+msgstr "Etiqueta eliminada"
 
-#: mod/install.php:469
-msgid ""
-"Function mcrypt_create_iv() is not defined. This is needed to enable RINO2 "
-"encryption layer."
-msgstr "Función mycrypt_create_iv() no esta definido. Esto es preciso para habilitar RINO2 encryption layer."
+#: mod/tagrm.php:82
+msgid "Remove Item Tag"
+msgstr "Eliminar etiqueta"
 
-#: mod/install.php:471
-msgid "mcrypt_create_iv() function"
-msgstr "mcrypt_create_iv() función"
+#: mod/tagrm.php:84
+msgid "Select a tag to remove: "
+msgstr "Selecciona una etiqueta para eliminar: "
 
-#: mod/install.php:479
-msgid "Error, XML PHP module required but not installed."
-msgstr "Error, módulo XML PHP requerido pero no instalado."
+#: mod/uexport.php:37
+msgid "Export account"
+msgstr "Exportar cuenta"
 
-#: mod/install.php:494
+#: mod/uexport.php:37
 msgid ""
-"The web installer needs to be able to create a file called \".htconfig.php\""
-" in the top folder of your web server and it is unable to do so."
-msgstr "El programa de instalación web necesita ser capaz de crear un archivo llamado \".htconfig.php\" en la carpeta principal de tu servidor web y es incapaz de hacerlo."
+"Export your account info and contacts. Use this to make a backup of your "
+"account and/or to move it to another server."
+msgstr "Exporta la información de tu cuenta y tus contactos. Úsalo para guardar una copia de seguridad de tu cuenta y/o moverla a otro servidor."
 
-#: mod/install.php:495
-msgid ""
-"This is most often a permission setting, as the web server may not be able "
-"to write files in your folder - even if you can."
-msgstr "Se trata a menudo de una configuración de permisos, pues el servidor web puede que no sea capaz de escribir archivos en la carpeta, aunque tú sí puedas."
+#: mod/uexport.php:38
+msgid "Export all"
+msgstr "Exportar todo"
 
-#: mod/install.php:496
+#: mod/uexport.php:38
 msgid ""
-"At the end of this procedure, we will give you a text to save in a file "
-"named .htconfig.php in your Friendica top folder."
-msgstr "Al final obtendremos un texto que debes guardar en un archivo llamado .htconfig.php en la carpeta de Friendica."
+"Export your accout info, contacts and all your items as json. Could be a "
+"very big file, and could take a lot of time. Use this to make a full backup "
+"of your account (photos are not exported)"
+msgstr "Exporta la información de tu cuenta, contactos y lo demás en JSON. Puede ser un archivo bastante grande, por lo que llevará tiempo. Úsalo para hacer una copia de seguridad completa de tu cuenta (las fotos no se exportarán)"
 
-#: mod/install.php:497
-msgid ""
-"You can alternatively skip this procedure and perform a manual installation."
-" Please see the file \"INSTALL.txt\" for instructions."
-msgstr "Como alternativa, puedes saltarte estos pasos y realizar una instalación manual. Por favor, consulta el archivo \"INSTALL.txt\" para las instrucciones."
+#: mod/uimport.php:68
+msgid "Move account"
+msgstr "Mover cuenta"
 
-#: mod/install.php:500
-msgid ".htconfig.php is writable"
-msgstr ".htconfig.php tiene permiso de escritura"
+#: mod/uimport.php:69
+msgid "You can import an account from another Friendica server."
+msgstr "Puedes importar una cuenta desde otro servidor de Friendica."
 
-#: mod/install.php:510
+#: mod/uimport.php:70
 msgid ""
-"Friendica uses the Smarty3 template engine to render its web views. Smarty3 "
-"compiles templates to PHP to speed up rendering."
-msgstr "Friendica usa el motor de templates Smarty3 para renderizar su visualisacion web. Smarty3 compila templates hacia PHP para acelerar la velocidad del renderizar."
+"You need to export your account from the old server and upload it here. We "
+"will recreate your old account here with all your contacts. We will try also"
+" to inform your friends that you moved here."
+msgstr "Necesitas exportar tu cuenta del antiguo servidor y subirla aquí. Volveremos a crear tu antigua cuenta con todos tus contactos aquí. También intentaremos de informar a tus amigos de que te has mudado."
 
-#: mod/install.php:511
+#: mod/uimport.php:71
 msgid ""
-"In order to store these compiled templates, the web server needs to have "
-"write access to the directory view/smarty3/ under the Friendica top level "
-"folder."
-msgstr "Para poder guardar estos templates compilados, el servidor web necesita acceso de escritura en el directorio /view/smarty3/ en el árbol de raíz de la instalación friendica."
+"This feature is experimental. We can't import contacts from the OStatus "
+"network (GNU Social/Statusnet) or from Diaspora"
+msgstr "Esta característica es experimental. No podemos importar contactos desde la red OStatus (statusnet/identi.ca) o desde Diaspora*"
 
-#: mod/install.php:512
-msgid ""
-"Please ensure that the user that your web server runs as (e.g. www-data) has"
-" write access to this folder."
-msgstr "Por favor asegure que el usuario que utiliza el servidor web (ejemplo: www-data) tiene permisos de escritura en esta carpeta."
+#: mod/uimport.php:72
+msgid "Account file"
+msgstr "Archivo de la cuenta"
 
-#: mod/install.php:513
+#: mod/uimport.php:72
 msgid ""
-"Note: as a security measure, you should give the web server write access to "
-"view/smarty3/ only--not the template files (.tpl) that it contains."
-msgstr "Nota: como medida de seguridad deberia dar acceso de escritura solo a /view/smarty3 / → no al los archivos template (.tpl) que contiene."
-
-#: mod/install.php:516
-msgid "view/smarty3 is writable"
-msgstr "Se puede escribir en /view/smarty3"
+"To export your account, go to \"Settings->Export your personal data\" and "
+"select \"Export account\""
+msgstr "Para exportar el perfil vaya a \"Configuracion -> Exportar sus datos personales\" y seleccione \"Exportar cuenta\""
 
-#: mod/install.php:532
-msgid ""
-"Url rewrite in .htaccess is not working. Check your server configuration."
-msgstr "La reescritura de la dirección en .htaccess no funcionó. Revisa la configuración."
+#: mod/update_community.php:19 mod/update_display.php:23
+#: mod/update_network.php:27 mod/update_notes.php:36 mod/update_profile.php:35
+msgid "[Embedded content - reload page to view]"
+msgstr "[Contenido incrustado - recarga la página para verlo]"
 
-#: mod/install.php:534
-msgid "Url rewrite is working"
-msgstr "Reescribiendo la dirección..."
+#: mod/videos.php:124
+msgid "Do you really want to delete this video?"
+msgstr "Realmente quieres eliminar este vídeo?"
 
-#: mod/install.php:552
-msgid "ImageMagick PHP extension is not installed"
-msgstr "No está instalada la extensión ImageMagick PHP"
+#: mod/videos.php:129
+msgid "Delete Video"
+msgstr "Borrar vídeo"
 
-#: mod/install.php:555
-msgid "ImageMagick PHP extension is installed"
-msgstr "ImageMagick PHP extension is installed"
+#: mod/videos.php:208
+msgid "No videos selected"
+msgstr "Ningún vídeo seleccionado"
 
-#: mod/install.php:557
-msgid "ImageMagick supports GIF"
-msgstr "ImageMagick supporta GIF"
+#: mod/videos.php:400
+msgid "Recent Videos"
+msgstr "Vídeos recientes"
 
-#: mod/install.php:566
-msgid ""
-"The database configuration file \".htconfig.php\" could not be written. "
-"Please use the enclosed text to create a configuration file in your web "
-"server root."
-msgstr "El archivo de configuración de base de datos \".htconfig.php\" no se pudo escribir. Por favor, utiliza el texto adjunto para crear un archivo de configuración en la raíz de tu servidor web."
+#: mod/videos.php:402
+msgid "Upload New Videos"
+msgstr "Subir nuevos vídeos"
 
-#: mod/install.php:605
-msgid "<h1>What next</h1>"
-msgstr "<h1>¿Ahora qué?</h1>"
+#: mod/viewcontacts.php:75
+msgid "No contacts."
+msgstr "Ningún contacto."
 
-#: mod/install.php:606
-msgid ""
-"IMPORTANT: You will need to [manually] setup a scheduled task for the "
-"poller."
-msgstr "IMPORTANTE: Tendrás que configurar [manualmente] una tarea programada para el sondeo"
+#: mod/viewsrc.php:7
+msgid "Access denied."
+msgstr "Acceso denegado."
 
-#: mod/item.php:116
-msgid "Unable to locate original post."
-msgstr "No se puede encontrar la publicación original."
+#: mod/wall_attach.php:17 mod/wall_attach.php:25 mod/wall_attach.php:76
+#: mod/wall_upload.php:20 mod/wall_upload.php:33 mod/wall_upload.php:86
+#: mod/wall_upload.php:122 mod/wall_upload.php:125
+msgid "Invalid request."
+msgstr "Consulta invalida"
 
-#: mod/item.php:341
-msgid "Empty post discarded."
-msgstr "Publicación vacía descartada."
+#: mod/wall_attach.php:94
+msgid "Sorry, maybe your upload is bigger than the PHP configuration allows"
+msgstr "Disculpa, posiblemente el archivo subido es mas grande que la PHP configuración permite."
 
-#: mod/item.php:902
-msgid "System error. Post not saved."
-msgstr "Error del sistema. Mensaje no guardado."
+#: mod/wall_attach.php:94
+msgid "Or - did you try to upload an empty file?"
+msgstr "Si no - intento de subir un archivo vacío?"
 
-#: mod/item.php:992
+#: mod/wall_attach.php:105
 #, php-format
-msgid ""
-"This message was sent to you by %s, a member of the Friendica social "
-"network."
-msgstr "Este mensaje te lo ha enviado %s, miembro de la red social Friendica."
+msgid "File exceeds size limit of %s"
+msgstr "El archivo excede el limite de tamaño de %s"
+
+#: mod/wall_attach.php:158 mod/wall_attach.php:174
+msgid "File upload failed."
+msgstr "Ha fallado la subida del archivo."
 
-#: mod/item.php:994
+#: mod/wallmessage.php:42 mod/wallmessage.php:106
 #, php-format
-msgid "You may visit them online at %s"
-msgstr "Los puedes visitar en línea en %s"
+msgid "Number of daily wall messages for %s exceeded. Message failed."
+msgstr "Excedido el número máximo de mensajes para %s. El mensaje no se ha enviado."
 
-#: mod/item.php:995
-msgid ""
-"Please contact the sender by replying to this post if you do not wish to "
-"receive these messages."
-msgstr "Por favor contacta con el remitente respondiendo a este mensaje si no deseas recibir estos mensajes."
+#: mod/wallmessage.php:53
+msgid "Unable to check your home location."
+msgstr "Imposible comprobar tu servidor de inicio."
 
-#: mod/item.php:999
-#, php-format
-msgid "%s posted an update."
-msgstr "%s ha publicado una actualización."
+#: mod/wallmessage.php:80 mod/wallmessage.php:89
+msgid "No recipient."
+msgstr "Sin receptor."
 
-#: mod/network.php:398
+#: mod/wallmessage.php:127
 #, php-format
 msgid ""
-"Warning: This group contains %s member from a network that doesn't allow non"
-" public messages."
-msgid_plural ""
-"Warning: This group contains %s members from a network that doesn't allow "
-"non public messages."
-msgstr[0] "Aviso: Este grupo contiene %s miembro de una red que no permite mensajes públicos."
-msgstr[1] "Aviso: Este grupo contiene %s miembros de una red que no permite mensajes públicos."
-
-#: mod/network.php:401
-msgid "Messages in this group won't be send to these receivers."
-msgstr "Los mensajes de este grupo no se enviarán a estos receptores."
+"If you wish for %s to respond, please check that the privacy settings on "
+"your site allow private mail from unknown senders."
+msgstr "Si quieres que %s te responda, asegúrate de que la configuración de privacidad permite enviar correo privado a desconocidos."
 
-#: mod/network.php:529
-msgid "Private messages to this person are at risk of public disclosure."
-msgstr "Los mensajes privados a esta persona corren el riesgo de ser mostrados públicamente."
+#: object/Item.php:359
+msgid "via"
+msgstr "vía"
 
-#: mod/network.php:534
-msgid "Invalid contact."
-msgstr "Contacto erróneo."
+#: view/theme/duepuntozero/config.php:44
+msgid "greenzero"
+msgstr "greenzero"
 
-#: mod/network.php:826
-msgid "Commented Order"
-msgstr "Orden de comentarios"
+#: view/theme/duepuntozero/config.php:45
+msgid "purplezero"
+msgstr "purplezero"
 
-#: mod/network.php:829
-msgid "Sort by Comment Date"
-msgstr "Ordenar por fecha de comentarios"
+#: view/theme/duepuntozero/config.php:46
+msgid "easterbunny"
+msgstr "easterbunny"
 
-#: mod/network.php:834
-msgid "Posted Order"
-msgstr "Orden de publicación"
+#: view/theme/duepuntozero/config.php:47
+msgid "darkzero"
+msgstr "darkzero"
 
-#: mod/network.php:837
-msgid "Sort by Post Date"
-msgstr "Ordenar por fecha de publicación"
+#: view/theme/duepuntozero/config.php:48
+msgid "comix"
+msgstr "comix"
 
-#: mod/network.php:848
-msgid "Posts that mention or involve you"
-msgstr "Publicaciones que te mencionan o involucran"
+#: view/theme/duepuntozero/config.php:49
+msgid "slackr"
+msgstr "slackr"
 
-#: mod/network.php:856
-msgid "New"
-msgstr "Nuevo"
+#: view/theme/duepuntozero/config.php:64
+msgid "Variations"
+msgstr "Variaciones"
 
-#: mod/network.php:859
-msgid "Activity Stream - by date"
-msgstr "Corriente de actividad por fecha"
+#: view/theme/frio/config.php:47
+msgid "Default"
+msgstr "Por defecto"
 
-#: mod/network.php:867
-msgid "Shared Links"
-msgstr "Enlaces compartidos"
+#: view/theme/frio/config.php:59
+msgid "Note: "
+msgstr "Nota:"
 
-#: mod/network.php:870
-msgid "Interesting Links"
-msgstr "Enlaces interesantes"
+#: view/theme/frio/config.php:59
+msgid "Check image permissions if all users are allowed to visit the image"
+msgstr "Compruebe los permisos de imagen si se les permite a todos los usuarios visitar la imagen"
 
-#: mod/network.php:878
-msgid "Starred"
-msgstr "Favoritos"
+#: view/theme/frio/config.php:67
+msgid "Select scheme"
+msgstr "Seleccionar plan"
 
-#: mod/network.php:881
-msgid "Favourite Posts"
-msgstr "Publicaciones favoritas"
+#: view/theme/frio/config.php:68
+msgid "Navigation bar background color"
+msgstr "Color de fondo de la barra de navegación"
 
-#: mod/ping.php:261
-msgid "{0} wants to be your friend"
-msgstr "{0} quiere ser tu amigo"
+#: view/theme/frio/config.php:69
+msgid "Navigation bar icon color "
+msgstr "Color de icono de la barra de navegación"
 
-#: mod/ping.php:276
-msgid "{0} sent you a message"
-msgstr "{0} te ha enviado un mensaje"
+#: view/theme/frio/config.php:70
+msgid "Link color"
+msgstr "Color de enlace"
 
-#: mod/ping.php:291
-msgid "{0} requested registration"
-msgstr "{0} solicitudes de registro"
+#: view/theme/frio/config.php:71
+msgid "Set the background color"
+msgstr "Seleccionar el color de fondo"
 
-#: mod/viewcontacts.php:72
-msgid "No contacts."
-msgstr "Ningún contacto."
+#: view/theme/frio/config.php:72
+msgid "Content background transparency"
+msgstr "Transparencia de contenido de fondo"
 
-#: object/Item.php:370
-msgid "via"
-msgstr "vía"
+#: view/theme/frio/config.php:73
+msgid "Set the background image"
+msgstr "Seleccionar la imagen de fondo"
 
 #: view/theme/frio/php/Image.php:23
 msgid "Repeat the image"
@@ -8733,195 +8794,74 @@ msgstr "Reajustar al mejor tamaño"
 msgid "Resize to best fit and retain aspect ratio."
 msgstr "Reajustar al mejor tamaño y conservar proporción"
 
-#: view/theme/frio/config.php:42
-msgid "Default"
-msgstr "Por defecto"
-
-#: view/theme/frio/config.php:54
-msgid "Note: "
-msgstr "Nota:"
-
-#: view/theme/frio/config.php:54
-msgid "Check image permissions if all users are allowed to visit the image"
-msgstr "Compruebe los permisos de imagen si se les permite a todos los usuarios visitar la imagen"
-
-#: view/theme/frio/config.php:62
-msgid "Select scheme"
-msgstr "Seleccionar plan"
-
-#: view/theme/frio/config.php:63
-msgid "Navigation bar background color"
-msgstr "Color de fondo de la barra de navegación"
-
-#: view/theme/frio/config.php:64
-msgid "Navigation bar icon color "
-msgstr "Color de icono de la barra de navegación"
-
-#: view/theme/frio/config.php:65
-msgid "Link color"
-msgstr "Color de enlace"
-
-#: view/theme/frio/config.php:66
-msgid "Set the background color"
-msgstr "Seleccionar el color de fondo"
-
-#: view/theme/frio/config.php:67
-msgid "Content background transparency"
-msgstr "Transparencia de contenido de fondo"
-
-#: view/theme/frio/config.php:68
-msgid "Set the background image"
-msgstr "Seleccionar la imagen de fondo"
-
-#: view/theme/frio/theme.php:229
+#: view/theme/frio/theme.php:226
 msgid "Guest"
 msgstr "Invitado"
 
-#: view/theme/frio/theme.php:235
+#: view/theme/frio/theme.php:232
 msgid "Visitor"
 msgstr "Visitante"
 
-#: view/theme/quattro/config.php:67
+#: view/theme/quattro/config.php:70
 msgid "Alignment"
 msgstr "Alineación"
 
-#: view/theme/quattro/config.php:67
+#: view/theme/quattro/config.php:70
 msgid "Left"
 msgstr "Izquierda"
 
-#: view/theme/quattro/config.php:67
+#: view/theme/quattro/config.php:70
 msgid "Center"
 msgstr "Centrado"
 
-#: view/theme/quattro/config.php:68
+#: view/theme/quattro/config.php:71
 msgid "Color scheme"
 msgstr "Esquema de color"
 
-#: view/theme/quattro/config.php:69
+#: view/theme/quattro/config.php:72
 msgid "Posts font size"
 msgstr "Tamaño de letra del titulo de las publicaciones"
 
-#: view/theme/quattro/config.php:70
+#: view/theme/quattro/config.php:73
 msgid "Textareas font size"
 msgstr "Tamaño de letra del área de texto"
 
-#: view/theme/vier/theme.php:152 view/theme/vier/config.php:112
-msgid "Community Profiles"
-msgstr "Perfiles de la Comunidad"
-
-#: view/theme/vier/theme.php:181 view/theme/vier/config.php:116
-msgid "Last users"
-msgstr "Últimos usuarios"
-
-#: view/theme/vier/theme.php:199 view/theme/vier/config.php:115
-msgid "Find Friends"
-msgstr "Buscar amigos"
-
-#: view/theme/vier/theme.php:200
-msgid "Local Directory"
-msgstr "Directorio local"
-
-#: view/theme/vier/theme.php:291
-msgid "Quick Start"
-msgstr "Inicio rápido"
-
-#: view/theme/vier/theme.php:373 view/theme/vier/config.php:114
-msgid "Connect Services"
-msgstr "Servicios conectados"
-
-#: view/theme/vier/config.php:64
+#: view/theme/vier/config.php:69
 msgid "Comma separated list of helper forums"
 msgstr "Lista separada por comas de foros de ayuda."
 
-#: view/theme/vier/config.php:110
+#: view/theme/vier/config.php:115
 msgid "Set style"
 msgstr "Definir estilo"
 
-#: view/theme/vier/config.php:111
+#: view/theme/vier/config.php:116
 msgid "Community Pages"
 msgstr "Páginas de Comunidad"
 
-#: view/theme/vier/config.php:113
+#: view/theme/vier/config.php:117 view/theme/vier/theme.php:146
+msgid "Community Profiles"
+msgstr "Perfiles de la Comunidad"
+
+#: view/theme/vier/config.php:118
 msgid "Help or @NewHere ?"
 msgstr "¿Ayuda o @NuevoAquí?"
 
-#: view/theme/duepuntozero/config.php:45
-msgid "greenzero"
-msgstr "greenzero"
-
-#: view/theme/duepuntozero/config.php:46
-msgid "purplezero"
-msgstr "purplezero"
-
-#: view/theme/duepuntozero/config.php:47
-msgid "easterbunny"
-msgstr "easterbunny"
-
-#: view/theme/duepuntozero/config.php:48
-msgid "darkzero"
-msgstr "darkzero"
-
-#: view/theme/duepuntozero/config.php:49
-msgid "comix"
-msgstr "comix"
-
-#: view/theme/duepuntozero/config.php:50
-msgid "slackr"
-msgstr "slackr"
-
-#: view/theme/duepuntozero/config.php:62
-msgid "Variations"
-msgstr "Variaciones"
-
-#: boot.php:970
-msgid "Delete this item?"
-msgstr "¿Eliminar este elemento?"
-
-#: boot.php:973
-msgid "show fewer"
-msgstr "ver menos"
-
-#: boot.php:1655
-#, php-format
-msgid "Update %s failed. See error logs."
-msgstr "Falló la actualización de %s. Mira los registros de errores."
-
-#: boot.php:1767
-msgid "Create a New Account"
-msgstr "Crear una nueva cuenta"
-
-#: boot.php:1796
-msgid "Password: "
-msgstr "Contraseña: "
-
-#: boot.php:1797
-msgid "Remember me"
-msgstr "Recordarme"
-
-#: boot.php:1800
-msgid "Or login using OpenID: "
-msgstr "O inicia sesión usando OpenID: "
-
-#: boot.php:1806
-msgid "Forgot your password?"
-msgstr "¿Olvidaste la contraseña?"
-
-#: boot.php:1809
-msgid "Website Terms of Service"
-msgstr "Términos de uso del sitio"
+#: view/theme/vier/config.php:119 view/theme/vier/theme.php:385
+msgid "Connect Services"
+msgstr "Servicios conectados"
 
-#: boot.php:1810
-msgid "terms of service"
-msgstr "Términos de uso"
+#: view/theme/vier/config.php:120 view/theme/vier/theme.php:194
+msgid "Find Friends"
+msgstr "Buscar amigos"
 
-#: boot.php:1812
-msgid "Website Privacy Policy"
-msgstr "Política de privacidad del sitio"
+#: view/theme/vier/config.php:121 view/theme/vier/theme.php:176
+msgid "Last users"
+msgstr "Últimos usuarios"
 
-#: boot.php:1813
-msgid "privacy policy"
-msgstr "Política de privacidad"
+#: view/theme/vier/theme.php:195
+msgid "Local Directory"
+msgstr "Directorio local"
 
-#: index.php:451
-msgid "toggle mobile"
-msgstr "Cambiar a versión móvil"
+#: view/theme/vier/theme.php:286
+msgid "Quick Start"
+msgstr "Inicio rápido"
index d8c0e84fde561721409e6f891a29da19bfd79f1f..a7365bb19006e3c3a448be6d6bb409565e4d9ba2 100644 (file)
@@ -5,112 +5,82 @@ function string_plural_select_es($n){
        return ($n != 1);;
 }}
 ;
-$a->strings["Add New Contact"] = "Añadir nuevo contacto";
-$a->strings["Enter address or web location"] = "Escribe la dirección o página web";
-$a->strings["Example: bob@example.com, http://example.com/barbara"] = "Ejemplo: miguel@ejemplo.com, http://ejemplo.com/miguel";
-$a->strings["Connect"] = "Conectar";
-$a->strings["%d invitation available"] = array(
-       0 => "%d invitación disponible",
-       1 => "%d invitaviones disponibles",
-);
-$a->strings["Find People"] = "Buscar personas";
-$a->strings["Enter name or interest"] = "Introduzce nombre o intereses";
-$a->strings["Connect/Follow"] = "Conectar/Seguir";
-$a->strings["Examples: Robert Morgenstein, Fishing"] = "Ejemplos: Robert Morgenstein, Pesca";
-$a->strings["Find"] = "Buscar";
-$a->strings["Friend Suggestions"] = "Sugerencias de amigos";
-$a->strings["Similar Interests"] = "Intereses similares";
-$a->strings["Random Profile"] = "Perfil aleatorio";
-$a->strings["Invite Friends"] = "Invitar amigos";
-$a->strings["Networks"] = "Redes";
-$a->strings["All Networks"] = "Todas las redes";
-$a->strings["Saved Folders"] = "Directorios guardados";
-$a->strings["Everything"] = "Todo";
-$a->strings["Categories"] = "Categorías";
-$a->strings["%d contact in common"] = array(
-       0 => "%d contacto en común",
-       1 => "%d contactos en común",
-);
+$a->strings["Delete this item?"] = "¿Eliminar este elemento?";
 $a->strings["show more"] = "ver más";
+$a->strings["show fewer"] = "ver menos";
+$a->strings["Update %s failed. See error logs."] = "Falló la actualización de %s. Mira los registros de errores.";
+$a->strings["Create a New Account"] = "Crear una nueva cuenta";
+$a->strings["Register"] = "Registrarse";
+$a->strings["Logout"] = "Salir";
+$a->strings["Login"] = "Acceder";
+$a->strings["Nickname or Email: "] = "Apodo o Correo electrónico: ";
+$a->strings["Password: "] = "Contraseña: ";
+$a->strings["Remember me"] = "Recordarme";
+$a->strings["Or login using OpenID: "] = "O inicia sesión usando OpenID: ";
+$a->strings["Forgot your password?"] = "¿Olvidaste la contraseña?";
+$a->strings["Password Reset"] = "Restablecer la contraseña";
+$a->strings["Website Terms of Service"] = "Términos de uso del sitio";
+$a->strings["terms of service"] = "Términos de uso";
+$a->strings["Website Privacy Policy"] = "Política de privacidad del sitio";
+$a->strings["privacy policy"] = "Política de privacidad";
+$a->strings["View Profile"] = "Ver perfil";
+$a->strings["Connect/Follow"] = "Conectar/Seguir";
+$a->strings["View Status"] = "Ver estado";
+$a->strings["View Photos"] = "Ver fotos";
+$a->strings["Network Posts"] = "Publicaciones en la red";
+$a->strings["View Contact"] = "Ver contacto";
+$a->strings["Drop Contact"] = "Eliminar contacto";
+$a->strings["Send PM"] = "Enviar mensaje privado";
+$a->strings["Poke"] = "Toque";
+$a->strings["Organisation"] = "Organización";
+$a->strings["News"] = "Noticias";
+$a->strings["Forum"] = "Foro";
 $a->strings["Forums"] = "Foros";
 $a->strings["External link to forum"] = "Enlace externo al foro";
-$a->strings["Male"] = "Hombre";
-$a->strings["Female"] = "Mujer";
-$a->strings["Currently Male"] = "Actualmente Hombre";
-$a->strings["Currently Female"] = "Actualmente Mujer";
-$a->strings["Mostly Male"] = "Mayormente Hombre";
-$a->strings["Mostly Female"] = "Mayormente Mujer";
-$a->strings["Transgender"] = "Transgenérico";
-$a->strings["Intersex"] = "Bisexual";
-$a->strings["Transsexual"] = "Transexual";
-$a->strings["Hermaphrodite"] = "Hermafrodita";
-$a->strings["Neuter"] = "Neutro";
-$a->strings["Non-specific"] = "Sin especificar";
-$a->strings["Other"] = "Otro";
-$a->strings["Undecided"] = array(
-       0 => "Indeciso",
-       1 => "Indeciso",
-);
-$a->strings["Males"] = "Hombres";
-$a->strings["Females"] = "Mujeres";
-$a->strings["Gay"] = "Gay";
-$a->strings["Lesbian"] = "Lesbiana";
-$a->strings["No Preference"] = "Sin preferencias";
-$a->strings["Bisexual"] = "Bisexual";
-$a->strings["Autosexual"] = "Autosexual";
-$a->strings["Abstinent"] = "Célibe";
-$a->strings["Virgin"] = "Virgen";
-$a->strings["Deviant"] = "Desviado";
-$a->strings["Fetish"] = "Fetichista";
-$a->strings["Oodles"] = "Orgiástico";
-$a->strings["Nonsexual"] = "Asexual";
-$a->strings["Single"] = "Soltero";
-$a->strings["Lonely"] = "Solitario";
-$a->strings["Available"] = "Disponible";
-$a->strings["Unavailable"] = "No disponible";
-$a->strings["Has crush"] = "Enamorado";
-$a->strings["Infatuated"] = "Loco/a por alguien";
-$a->strings["Dating"] = "De citas";
-$a->strings["Unfaithful"] = "Infiel";
-$a->strings["Sex Addict"] = "Adicto al sexo";
-$a->strings["Friends"] = "Amigos";
-$a->strings["Friends/Benefits"] = "Amigos con beneficios";
-$a->strings["Casual"] = "Casual";
-$a->strings["Engaged"] = "Comprometido/a";
-$a->strings["Married"] = "Casado/a";
-$a->strings["Imaginarily married"] = "Casado imaginario";
-$a->strings["Partners"] = "Socios";
-$a->strings["Cohabiting"] = "Cohabitando";
-$a->strings["Common law"] = "Pareja de hecho";
-$a->strings["Happy"] = "Feliz";
-$a->strings["Not looking"] = "No busca relación";
-$a->strings["Swinger"] = "Swinger";
-$a->strings["Betrayed"] = "Traicionado/a";
-$a->strings["Separated"] = "Separado/a";
-$a->strings["Unstable"] = "Inestable";
-$a->strings["Divorced"] = "Divorciado/a";
-$a->strings["Imaginarily divorced"] = "Divorciado imaginario";
-$a->strings["Widowed"] = "Viudo/a";
-$a->strings["Uncertain"] = "Incierto";
-$a->strings["It's complicated"] = "Es complicado";
-$a->strings["Don't care"] = "No te importa";
-$a->strings["Ask me"] = "Pregúntame";
-$a->strings["Cannot locate DNS info for database server '%s'"] = "No se puede encontrar información DNS para la base de datos del servidor '%s'";
+$a->strings["System"] = "Sistema";
+$a->strings["Network"] = "Red";
+$a->strings["Personal"] = "Personal";
+$a->strings["Home"] = "Inicio";
+$a->strings["Introductions"] = "Presentaciones";
+$a->strings["%s commented on %s's post"] = "%s comentó la publicación de %s";
+$a->strings["%s created a new post"] = "%s creó una nueva publicación";
+$a->strings["%s liked %s's post"] = "A %s le gusta la publicación de %s";
+$a->strings["%s disliked %s's post"] = "A %s no le gusta la publicación de %s";
+$a->strings["%s is attending %s's event"] = "%s está asistiendo al evento %s's";
+$a->strings["%s is not attending %s's event"] = "%s no está asistiendo al evento %s's";
+$a->strings["%s may attend %s's event"] = "%s podría asistir al evento %s's";
+$a->strings["%s is now friends with %s"] = "%s es ahora es amigo de %s";
+$a->strings["Friend Suggestion"] = "Propuestas de amistad";
+$a->strings["Friend/Connect Request"] = "Solicitud de Amistad/Conexión";
+$a->strings["New Follower"] = "Nuevo seguidor";
+$a->strings["Wall Photos"] = "Foto del Muro";
+$a->strings["Post to Email"] = "Publicar mediante correo electrónico";
+$a->strings["Connectors disabled, since \"%s\" is enabled."] = "Conectores deshabilitados, ya que \"%s\" es habilitado.";
+$a->strings["Hide your profile details from unknown viewers?"] = "¿Quieres que los detalles de tu perfil permanezcan ocultos a los desconocidos?";
+$a->strings["Visible to everybody"] = "Visible para cualquiera";
+$a->strings["show"] = "mostrar";
+$a->strings["don't show"] = "no mostrar";
+$a->strings["CC: email addresses"] = "CC: dirección de correo electrónico";
+$a->strings["Example: bob@example.com, mary@example.com"] = "Ejemplo: juan@ejemplo.com, sofia@ejemplo.com";
+$a->strings["Permissions"] = "Permisos";
+$a->strings["Close"] = "Cerrado";
+$a->strings["Daily posting limit of %d posts reached. The post was rejected."] = "Limite diario de publicaciones %d alcanzado. La publicación fue rechazada.";
+$a->strings["Weekly posting limit of %d posts reached. The post was rejected."] = "Limite semanal de publicaciones %d alcanzado. La publicación fue rechazada.";
+$a->strings["Monthly posting limit of %d posts reached. The post was rejected."] = "Limite mensual de publicaciones %d alcanzado. La publicación fue rechazada.";
 $a->strings["Logged out."] = "Sesión finalizada";
 $a->strings["Login failed."] = "Accesso fallido.";
 $a->strings["We encountered a problem while logging in with the OpenID you provided. Please check the correct spelling of the ID."] = "Se ha encontrado un problema para acceder con el OpenID que has escrito. Verifica que lo hayas escrito correctamente.";
 $a->strings["The error message was:"] = "El mensaje del error fue:";
-$a->strings["A deleted group with this name was revived. Existing item permissions <strong>may</strong> apply to this group and any future members. If this is not what you intended, please create another group with a different name."] = "Un grupo eliminado con este nombre fue restablecido. Los permisos existentes <strong>pueden</strong> aplicarse a este grupo y a sus futuros miembros. Si esto no es lo que pretendes, por favor, crea otro grupo con un nombre diferente.";
-$a->strings["Default privacy group for new contacts"] = "Grupo por defecto para nuevos contactos";
-$a->strings["Everybody"] = "Todo el mundo";
-$a->strings["edit"] = "editar";
-$a->strings["Groups"] = "Grupos";
-$a->strings["Edit groups"] = "Editar grupo";
-$a->strings["Edit group"] = "Editar grupo";
-$a->strings["Create a new group"] = "Crear un nuevo grupo";
-$a->strings["Group Name: "] = "Nombre del grupo: ";
-$a->strings["Contacts not in any group"] = "Contactos sin grupo";
-$a->strings["add"] = "añadir";
+$a->strings["l F d, Y \\@ g:i A"] = "l F d, Y \\@ g:i A";
+$a->strings["Starts:"] = "Inicio:";
+$a->strings["Finishes:"] = "Final:";
+$a->strings["Location:"] = "Localización:";
+$a->strings["Image/photo"] = "Imagen/Foto";
+$a->strings["<a href=\"%1\$s\" target=\"_blank\">%2\$s</a> %3\$s"] = "<a href=\"%1\$s\" target=\"_blank\">%2\$s</a> %3\$s";
+$a->strings["$1 wrote:"] = "$1 escribió:";
+$a->strings["Encrypted content"] = "Contenido cifrado";
+$a->strings["Invalid source protocol"] = "Protocolo de fuente inválido";
+$a->strings["Invalid link protocol"] = "Protocolo de enlace inválido";
 $a->strings["Unknown | Not categorised"] = "Desconocido | No clasificado";
 $a->strings["Block immediately"] = "Bloquear inmediatamente";
 $a->strings["Shady, spammer, self-marketer"] = "Sospechoso, spammer, auto-publicidad";
@@ -138,70 +108,173 @@ $a->strings["pump.io"] = "pump.io";
 $a->strings["Twitter"] = "Twitter";
 $a->strings["Diaspora Connector"] = "Conector Diaspora";
 $a->strings["GNU Social"] = "GNUsocial (OStatus)";
+$a->strings["pnut"] = "pnut";
 $a->strings["App.net"] = "App.net";
 $a->strings["Hubzilla/Redmatrix"] = "Hubzilla/Redmatrix";
-$a->strings["Post to Email"] = "Publicar mediante correo electrónico";
-$a->strings["Connectors disabled, since \"%s\" is enabled."] = "Conectores deshabilitados, ya que \"%s\" es habilitado.";
-$a->strings["Hide your profile details from unknown viewers?"] = "¿Quieres que los detalles de tu perfil permanezcan ocultos a los desconocidos?";
-$a->strings["Visible to everybody"] = "Visible para cualquiera";
-$a->strings["show"] = "mostrar";
-$a->strings["don't show"] = "no mostrar";
-$a->strings["CC: email addresses"] = "CC: dirección de correo electrónico";
-$a->strings["Example: bob@example.com, mary@example.com"] = "Ejemplo: juan@ejemplo.com, sofia@ejemplo.com";
-$a->strings["Permissions"] = "Permisos";
-$a->strings["Close"] = "Cerrado";
-$a->strings["photo"] = "foto";
-$a->strings["status"] = "estado";
+$a->strings["Add New Contact"] = "Añadir nuevo contacto";
+$a->strings["Enter address or web location"] = "Escribe la dirección o página web";
+$a->strings["Example: bob@example.com, http://example.com/barbara"] = "Ejemplo: miguel@ejemplo.com, http://ejemplo.com/miguel";
+$a->strings["Connect"] = "Conectar";
+$a->strings["%d invitation available"] = array(
+       0 => "%d invitación disponible",
+       1 => "%d invitaviones disponibles",
+);
+$a->strings["Find People"] = "Buscar personas";
+$a->strings["Enter name or interest"] = "Introduzce nombre o intereses";
+$a->strings["Examples: Robert Morgenstein, Fishing"] = "Ejemplos: Robert Morgenstein, Pesca";
+$a->strings["Find"] = "Buscar";
+$a->strings["Friend Suggestions"] = "Sugerencias de amigos";
+$a->strings["Similar Interests"] = "Intereses similares";
+$a->strings["Random Profile"] = "Perfil aleatorio";
+$a->strings["Invite Friends"] = "Invitar amigos";
+$a->strings["Networks"] = "Redes";
+$a->strings["All Networks"] = "Todas las redes";
+$a->strings["Saved Folders"] = "Directorios guardados";
+$a->strings["Everything"] = "Todo";
+$a->strings["Categories"] = "Categorías";
+$a->strings["%d contact in common"] = array(
+       0 => "%d contacto en común",
+       1 => "%d contactos en común",
+);
 $a->strings["event"] = "evento";
+$a->strings["status"] = "estado";
+$a->strings["photo"] = "foto";
 $a->strings["%1\$s likes %2\$s's %3\$s"] = "A %1\$s le gusta %3\$s de %2\$s";
 $a->strings["%1\$s doesn't like %2\$s's %3\$s"] = "A %1\$s no le gusta %3\$s de %2\$s";
-$a->strings["%1\$s is attending %2\$s's %3\$s"] = "%1\$s atenderá %2\$s's %3\$s";
-$a->strings["%1\$s is not attending %2\$s's %3\$s"] = "%1\$s no atenderá %2\$s's %3\$s";
-$a->strings["%1\$s may attend %2\$s's %3\$s"] = "%1\$s puede que atienda %2\$s's %3\$s";
-$a->strings["[no subject]"] = "[sin asunto]";
-$a->strings["Wall Photos"] = "Foto del Muro";
-$a->strings["Click here to upgrade."] = "Pulsa aquí para actualizar.";
-$a->strings["This action exceeds the limits set by your subscription plan."] = "Esta acción excede los límites permitidos por tu subscripción.";
-$a->strings["This action is not available under your subscription plan."] = "Esta acción no está permitida para tu subscripción.";
-$a->strings["Error decoding account file"] = "Error decodificando el archivo de cuenta";
-$a->strings["Error! No version data in file! This is not a Friendica account file?"] = "Error! No hay datos de versión en el archivo! ¿Es esto de una cuenta friendica? ";
-$a->strings["Error! Cannot check nickname"] = "Error! No puedo consultar el apodo";
-$a->strings["User '%s' already exists on this server!"] = "La cuenta '%s' ya existe en este servidor!";
-$a->strings["User creation error"] = "Error al crear la cuenta";
-$a->strings["User profile creation error"] = "Error de creación del perfil de la cuenta";
-$a->strings["%d contact not imported"] = array(
-       0 => "%d contactos no encontrado",
-       1 => "%d contactos no importado",
+$a->strings["%1\$s attends %2\$s's %3\$s"] = "%1\$s atenderá %2\$s's %3\$s";
+$a->strings["%1\$s doesn't attend %2\$s's %3\$s"] = "%1\$s no atenderá %2\$s's %3\$s";
+$a->strings["%1\$s attends maybe %2\$s's %3\$s"] = "%1\$s atenderá quizás %2\$s's %3\$s";
+$a->strings["%1\$s is now friends with %2\$s"] = "%1\$s ahora es amigo de %2\$s";
+$a->strings["%1\$s poked %2\$s"] = "%1\$s le dio un toque a %2\$s";
+$a->strings["%1\$s is currently %2\$s"] = "%1\$s está actualmente %2\$s";
+$a->strings["%1\$s tagged %2\$s's %3\$s with %4\$s"] = "%1\$s ha etiquetado el %3\$s de %2\$s con %4\$s";
+$a->strings["post/item"] = "publicación/tema";
+$a->strings["%1\$s marked %2\$s's %3\$s as favorite"] = "%1\$s ha marcado %3\$s de %2\$s como Favorito";
+$a->strings["Likes"] = "Me gusta";
+$a->strings["Dislikes"] = "No me gusta";
+$a->strings["Attending"] = array(
+       0 => "Atendiendo",
+       1 => "Atendiendo",
 );
-$a->strings["Done. You can now login with your username and password"] = "Hecho. Ahora podes ingresar con tu nombre de cuenta y la contraseña.";
-$a->strings["Miscellaneous"] = "Varios";
-$a->strings["Birthday:"] = "Fecha de nacimiento:";
-$a->strings["Age: "] = "Edad: ";
-$a->strings["YYYY-MM-DD or MM-DD"] = "YYYY-MM-DD o MM-DD";
-$a->strings["never"] = "nunca";
-$a->strings["less than a second ago"] = "hace menos de un segundo";
-$a->strings["year"] = "año";
-$a->strings["years"] = "años";
-$a->strings["month"] = "mes";
-$a->strings["months"] = "meses";
-$a->strings["week"] = "semana";
-$a->strings["weeks"] = "semanas";
-$a->strings["day"] = "día";
-$a->strings["days"] = "días";
-$a->strings["hour"] = "hora";
-$a->strings["hours"] = "horas";
-$a->strings["minute"] = "minuto";
+$a->strings["Not attending"] = "No atendiendo";
+$a->strings["Might attend"] = "Puede que atienda";
+$a->strings["Select"] = "Seleccionar";
+$a->strings["Delete"] = "Eliminar";
+$a->strings["View %s's profile @ %s"] = "Ver perfil de %s @ %s";
+$a->strings["Categories:"] = "Categorías:";
+$a->strings["Filed under:"] = "Archivado en:";
+$a->strings["%s from %s"] = "%s de %s";
+$a->strings["View in context"] = "Verlo en contexto";
+$a->strings["Please wait"] = "Por favor, espera";
+$a->strings["remove"] = "eliminar";
+$a->strings["Delete Selected Items"] = "Eliminar el elemento seleccionado";
+$a->strings["Follow Thread"] = "Seguir publicacion";
+$a->strings["%s likes this."] = "A %s le gusta esto.";
+$a->strings["%s doesn't like this."] = "A %s no le gusta esto.";
+$a->strings["%s attends."] = "%s atiende.";
+$a->strings["%s doesn't attend."] = "%s no atenderá.";
+$a->strings["%s attends maybe."] = "%s quizás atenderá";
+$a->strings["and"] = "y";
+$a->strings[", and %d other people"] = " y a otras %d personas";
+$a->strings["<span  %1\$s>%2\$d people</span> like this"] = "<span  %1\$s>%2\$d personas</span> les gusta esto";
+$a->strings["%s like this."] = "A %s le gusta esto.";
+$a->strings["<span  %1\$s>%2\$d people</span> don't like this"] = "<span  %1\$s>%2\$d personas</span> no les gusta esto";
+$a->strings["%s don't like this."] = "A %s no le gusta esto.";
+$a->strings["<span  %1\$s>%2\$d people</span> attend"] = "<span  %1\$s>%2\$d personas</span> atienden";
+$a->strings["%s attend."] = "%s atiende.";
+$a->strings["<span  %1\$s>%2\$d people</span> don't attend"] = "<span  %1\$s>%2\$d personas</span>no atienden";
+$a->strings["%s don't attend."] = "%s no atiende.";
+$a->strings["<span  %1\$s>%2\$d people</span> attend maybe"] = "<span  %1\$s>%2\$d people</span> quizá asistan";
+$a->strings["%s anttend maybe."] = "%s atiende quizás.";
+$a->strings["Visible to <strong>everybody</strong>"] = "Visible para <strong>cualquiera</strong>";
+$a->strings["Please enter a link URL:"] = "Introduce la dirección del enlace:";
+$a->strings["Please enter a video link/URL:"] = "Por favor, introduce la URL/enlace del vídeo:";
+$a->strings["Please enter an audio link/URL:"] = "Por favor, introduce la URL/enlace del audio:";
+$a->strings["Tag term:"] = "Etiquetar:";
+$a->strings["Save to Folder:"] = "Guardar en directorio:";
+$a->strings["Where are you right now?"] = "¿Dónde estás ahora?";
+$a->strings["Delete item(s)?"] = "¿Borrar objeto(s)?";
+$a->strings["Share"] = "Compartir";
+$a->strings["Upload photo"] = "Subir foto";
+$a->strings["upload photo"] = "subir imagen";
+$a->strings["Attach file"] = "Adjuntar archivo";
+$a->strings["attach file"] = "adjuntar archivo";
+$a->strings["Insert web link"] = "Insertar enlace";
+$a->strings["web link"] = "enlace web";
+$a->strings["Insert video link"] = "Insertar enlace del vídeo";
+$a->strings["video link"] = "enlace de video";
+$a->strings["Insert audio link"] = "Insertar vínculo del audio";
+$a->strings["audio link"] = "enlace de audio";
+$a->strings["Set your location"] = "Configurar tu localización";
+$a->strings["set location"] = "establecer tu ubicación";
+$a->strings["Clear browser location"] = "Borrar la localización del navegador";
+$a->strings["clear location"] = "limpiar la localización";
+$a->strings["Set title"] = "Establecer el título";
+$a->strings["Categories (comma-separated list)"] = "Categorías (lista separada por comas)";
+$a->strings["Permission settings"] = "Configuración de permisos";
+$a->strings["permissions"] = "permisos";
+$a->strings["Public post"] = "Publicación pública";
+$a->strings["Preview"] = "Vista previa";
+$a->strings["Cancel"] = "Cancelar";
+$a->strings["Post to Groups"] = "Publicar hacia grupos";
+$a->strings["Post to Contacts"] = "Publicar hacia contactos";
+$a->strings["Private post"] = "Publicación privada";
+$a->strings["Message"] = "Mensaje";
+$a->strings["Browser"] = "Navegador";
+$a->strings["View all"] = "Ver todos los contactos";
+$a->strings["Like"] = array(
+       0 => "Me gusta",
+       1 => "Me gusta",
+);
+$a->strings["Dislike"] = array(
+       0 => "No me gusta",
+       1 => "No me gusta",
+);
+$a->strings["Not Attending"] = array(
+       0 => "No atendiendo",
+       1 => "No atendiendo",
+);
+$a->strings["Undecided"] = array(
+       0 => "Indeciso",
+       1 => "Indeciso",
+);
+$a->strings["Miscellaneous"] = "Varios";
+$a->strings["Birthday:"] = "Fecha de nacimiento:";
+$a->strings["Age: "] = "Edad: ";
+$a->strings["YYYY-MM-DD or MM-DD"] = "YYYY-MM-DD o MM-DD";
+$a->strings["never"] = "nunca";
+$a->strings["less than a second ago"] = "hace menos de un segundo";
+$a->strings["year"] = "año";
+$a->strings["years"] = "años";
+$a->strings["month"] = "mes";
+$a->strings["months"] = "meses";
+$a->strings["week"] = "semana";
+$a->strings["weeks"] = "semanas";
+$a->strings["day"] = "día";
+$a->strings["days"] = "días";
+$a->strings["hour"] = "hora";
+$a->strings["hours"] = "horas";
+$a->strings["minute"] = "minuto";
 $a->strings["minutes"] = "minutos";
 $a->strings["second"] = "segundo";
 $a->strings["seconds"] = "segundos";
 $a->strings["%1\$d %2\$s ago"] = "hace %1\$d %2\$s";
 $a->strings["%s's birthday"] = "Cumpleaños de %s";
 $a->strings["Happy Birthday %s"] = "Feliz cumpleaños %s";
+$a->strings["Cannot locate DNS info for database server '%s'"] = "No se puede encontrar información DNS para la base de datos del servidor '%s'";
+$a->strings["\n\t\t\tThe friendica developers released update %s recently,\n\t\t\tbut when I tried to install it, something went terribly wrong.\n\t\t\tThis needs to be fixed soon and I can't do it alone. Please contact a\n\t\t\tfriendica developer if you can not help me on your own. My database might be invalid."] = "\n\t\t\tLos desarolladores de friendica publicaron una actualización  %s recientemente\n\t\t\tpero cuando intento de instalarla,algo salio terriblemente mal.\n\t\t\tEsto necesita ser arreglado pronto y no puedo hacerlo solo. Por favor contacta\n\t\t\tlos desarolladores de friendica si no me podes ayudar por ti solo. Mi base de datos puede estar invalido.";
+$a->strings["The error message is\n[pre]%s[/pre]"] = "El mensaje de error es\n[pre]%s[/pre]";
+$a->strings["Errors encountered creating database tables."] = "Se han encontrados errores creando las tablas de la base de datos.";
+$a->strings["Errors encountered performing database changes."] = "Errores encontrados al ejecutar cambios en la base de datos.";
+$a->strings["(no subject)"] = "(sin asunto)";
+$a->strings["noreply"] = "no responder";
+$a->strings["%s\\'s birthday"] = "%s\\'s cumpleaños";
+$a->strings["Sharing notification from Diaspora network"] = "Compartir notificaciones con la red Diaspora*";
+$a->strings["Attachments:"] = "Archivos adjuntos:";
 $a->strings["Friendica Notification"] = "Notificación de Friendica";
 $a->strings["Thank You,"] = "Gracias,";
 $a->strings["%s Administrator"] = "%s Administrador";
 $a->strings["%1\$s, %2\$s Administrator"] = "%1\$s, %2\$s Administrador";
-$a->strings["noreply"] = "no responder";
 $a->strings["%s <!item_type!>"] = "%s <!item_type!>";
 $a->strings["[Friendica:Notify] New mail received at %s"] = "[Friendica:Notificación] Nuevo correo recibido de %s";
 $a->strings["%1\$s sent you a new private message at %2\$s."] = "%1\$s te ha enviado un mensaje privado desde %2\$s.";
@@ -257,10 +330,6 @@ $a->strings["You've received a registration request from '%1\$s' at %2\$s"] = "R
 $a->strings["You've received a [url=%1\$s]registration request[/url] from %2\$s."] = "Recibiste una [url=%1\$s]consulta de registro[/url] from %2\$s.";
 $a->strings["Full Name:\t%1\$s\\nSite Location:\t%2\$s\\nLogin Name:\t%3\$s (%4\$s)"] = "Nombre completo:\t%1\$s\\nUbicación del sitio:\t%2\$s\\nLogin Nombre:\t%3\$s (%4\$s)";
 $a->strings["Please visit %s to approve or reject the request."] = "Por favor visita %s para aprobar o negar la solicitud.";
-$a->strings["l F d, Y \\@ g:i A"] = "l F d, Y \\@ g:i A";
-$a->strings["Starts:"] = "Inicio:";
-$a->strings["Finishes:"] = "Final:";
-$a->strings["Location:"] = "Localización:";
 $a->strings["Sun"] = "Dom";
 $a->strings["Mon"] = "Lun";
 $a->strings["Tue"] = "Mar";
@@ -307,28 +376,161 @@ $a->strings["link to source"] = "Enlace al original";
 $a->strings["Export"] = "Exportar";
 $a->strings["Export calendar as ical"] = "Exportar calendario como ical";
 $a->strings["Export calendar as csv"] = "Exportar calendario como csv";
-$a->strings["Nothing new here"] = "Nada nuevo por aquí";
-$a->strings["Clear notifications"] = "Limpiar notificaciones";
-$a->strings["@name, !forum, #tags, content"] = "@name, !forum, #tags, contenido";
-$a->strings["Logout"] = "Salir";
-$a->strings["End this session"] = "Cerrar la sesión";
-$a->strings["Status"] = "Estado";
-$a->strings["Your posts and conversations"] = "Tus publicaciones y conversaciones";
+$a->strings["General Features"] = "Opciones generales";
+$a->strings["Multiple Profiles"] = "Perfiles multiples";
+$a->strings["Ability to create multiple profiles"] = "Capacidad de crear perfiles multiples. Cada pagina/perfil/usuario puede tener diferentes perfiles/apariencias. Las mismas pueden ser visibles para determinados contactos seleccionados dentro de la red friendica.";
+$a->strings["Photo Location"] = "Localización foto";
+$a->strings["Photo metadata is normally stripped. This extracts the location (if present) prior to stripping metadata and links it to a map."] = "Normalmente los meta datos de las imágenes son eliminados. Esto extraerá la localización si presente antes de eliminar los meta datos y enlaza la misma con el mapa.";
+$a->strings["Export Public Calendar"] = "Exportar Calendario Público";
+$a->strings["Ability for visitors to download the public calendar"] = "Posibilidad de los visitantes de descargar el calendario público";
+$a->strings["Post Composition Features"] = "Opciones de edición de publicaciones.";
+$a->strings["Post Preview"] = "Previsualizar publicaciones";
+$a->strings["Allow previewing posts and comments before publishing them"] = "Permitir la previsualización de publicaciones antes de publicar las mismas.";
+$a->strings["Auto-mention Forums"] = "Auto-mencionar foros";
+$a->strings["Add/remove mention when a forum page is selected/deselected in ACL window."] = "Añadir/eliminar mención cuando un foro es seleccionado/deseleccionado en la ventana ACL.";
+$a->strings["Network Sidebar Widgets"] = "Accesorios de red del panel lateral";
+$a->strings["Search by Date"] = "Buscar por fecha";
+$a->strings["Ability to select posts by date ranges"] = "Habilidad de seleccionar publicaciones por fecha";
+$a->strings["List Forums"] = "Listar foros";
+$a->strings["Enable widget to display the forums your are connected with"] = "Habilitar la pestaña para mostrar los foros en que estas participando.";
+$a->strings["Group Filter"] = "Filtro del grupo";
+$a->strings["Enable widget to display Network posts only from selected group"] = "Habilitar accesorios para visualizar publicaciones en la red solo de grupos seleccionados";
+$a->strings["Network Filter"] = "Filtro de red";
+$a->strings["Enable widget to display Network posts only from selected network"] = "Habilitar accesorios para visualizar publicaciones solo de las redes seleccionadas.";
+$a->strings["Saved Searches"] = "Búsquedas guardadas";
+$a->strings["Save search terms for re-use"] = "Guardar términos de búsqueda para su reutilizacion";
+$a->strings["Network Tabs"] = "Pestañas de redes";
+$a->strings["Network Personal Tab"] = "Pestaña actividad personal";
+$a->strings["Enable tab to display only Network posts that you've interacted on"] = "Habilitar para visualizar solo publicaciones con las que se ha interactuado";
+$a->strings["Network New Tab"] = "Pestaña nuevo en la red";
+$a->strings["Enable tab to display only new Network posts (from the last 12 hours)"] = "Activar para mostrar solo publicaciones nuevas en la red (de las ultimas 12 horas)";
+$a->strings["Network Shared Links Tab"] = "Pestaña publicaciones con enlaces";
+$a->strings["Enable tab to display only Network posts with links in them"] = "Habilitar para visualizar solo publicaciones que contienen enlaces";
+$a->strings["Post/Comment Tools"] = "Herramienta de publicaciones/respuestas";
+$a->strings["Multiple Deletion"] = "Borrar múltiples publicaciones";
+$a->strings["Select and delete multiple posts/comments at once"] = "Habilidad de seleccionar y borrar varias publicaciones/comentarios a la vez";
+$a->strings["Edit Sent Posts"] = "Editar temas enviados";
+$a->strings["Edit and correct posts and comments after sending"] = "Editar y corregir publicaciones y respuestas enviados. Las ediciones solo son comunicados dentro de la red friendica. No se modificaran copias enviadas a diaspora, OStatus/GNUsocial/Quitter u otros servicios conectados.";
+$a->strings["Tagging"] = "taggear";
+$a->strings["Ability to tag existing posts"] = "Habilidad de taggear publicaciones existentes";
+$a->strings["Post Categories"] = "Categorías de publicaciones";
+$a->strings["Add categories to your posts"] = "Agregue categorías a sus publicaciones. Las mismas serán visualizadas en su pagina de inicio.";
+$a->strings["Ability to file posts under folders"] = "Archivar publicaciones en carpetas";
+$a->strings["Dislike Posts"] = "Desaprobar publicación (dislike)";
+$a->strings["Ability to dislike posts/comments"] = "Habilidad de expresar desacuerdo en publicaciones y comentarios. Esta función solo es visualizado en la red friendica.";
+$a->strings["Star Posts"] = "Fijar publicaciones";
+$a->strings["Ability to mark special posts with a star indicator"] = "Habilidad de marcar - observar fijamente publicaciones.\nEl simbolo de estrella es habilitado. Se recibirán notificaciones sobre comentarios, además una pestaña de publicaciones fijadas es habilitada. En las opciones de expiración de publicaciones se puede filtrar estas publicaciones para no ser eliminados contrario a las publicaciones demás de los contactos.";
+$a->strings["Mute Post Notifications"] = "Silenciar notificaciones de una publicacion";
+$a->strings["Ability to mute notifications for a thread"] = "Habilidad de silenciar notificaciones sobre nuevos comentarios en una publicación.";
+$a->strings["Advanced Profile Settings"] = "Ajustes avanzados del perfil";
+$a->strings["Show visitors public community forums at the Advanced Profile Page"] = "Mostrar a los visitantes foros públicos en las que se esta participando en el pagina avanzada de perfiles.";
+$a->strings["Disallowed profile URL."] = "Dirección de perfil no permitida.";
+$a->strings["Connect URL missing."] = "Falta el conector URL.";
+$a->strings["This site is not configured to allow communications with other networks."] = "Este sitio no está configurado para permitir la comunicación con otras redes.";
+$a->strings["No compatible communication protocols or feeds were discovered."] = "No se ha descubierto protocolos de comunicación o fuentes compatibles.";
+$a->strings["The profile address specified does not provide adequate information."] = "La dirección del perfil especificado no proporciona información adecuada.";
+$a->strings["An author or name was not found."] = "No se ha encontrado un autor o nombre.";
+$a->strings["No browser URL could be matched to this address."] = "Ninguna dirección concuerda con la suministrada.";
+$a->strings["Unable to match @-style Identity Address with a known protocol or email contact."] = "Imposible identificar la dirección @ con algún protocolo conocido o dirección de contacto.";
+$a->strings["Use mailto: in front of address to force email check."] = "Escribe mailto: al principio de la dirección para forzar el envío.";
+$a->strings["The profile address specified belongs to a network which has been disabled on this site."] = "La dirección del perfil especificada pertenece a una red que ha sido deshabilitada en este sitio.";
+$a->strings["Limited profile. This person will be unable to receive direct/personal notifications from you."] = "Perfil limitado. Esta persona no podrá recibir notificaciones directas/personales tuyas.";
+$a->strings["Unable to retrieve contact information."] = "No ha sido posible recibir la información del contacto.";
+$a->strings["A deleted group with this name was revived. Existing item permissions <strong>may</strong> apply to this group and any future members. If this is not what you intended, please create another group with a different name."] = "Un grupo eliminado con este nombre fue restablecido. Los permisos existentes <strong>pueden</strong> aplicarse a este grupo y a sus futuros miembros. Si esto no es lo que pretendes, por favor, crea otro grupo con un nombre diferente.";
+$a->strings["Default privacy group for new contacts"] = "Grupo por defecto para nuevos contactos";
+$a->strings["Everybody"] = "Todo el mundo";
+$a->strings["edit"] = "editar";
+$a->strings["Groups"] = "Grupos";
+$a->strings["Edit groups"] = "Editar grupo";
+$a->strings["Edit group"] = "Editar grupo";
+$a->strings["Create a new group"] = "Crear un nuevo grupo";
+$a->strings["Group Name: "] = "Nombre del grupo: ";
+$a->strings["Contacts not in any group"] = "Contactos sin grupo";
+$a->strings["add"] = "añadir";
+$a->strings["Requested account is not available."] = "La cuenta solicitada no está disponible.";
+$a->strings["Requested profile is not available."] = "El perfil solicitado no está disponible.";
+$a->strings["Edit profile"] = "Editar perfil";
+$a->strings["Atom feed"] = "Atom feed";
+$a->strings["Profiles"] = "Perfiles";
+$a->strings["Manage/edit profiles"] = "Administrar/editar perfiles";
+$a->strings["Change profile photo"] = "Cambiar foto del perfil";
+$a->strings["Create New Profile"] = "Crear nuevo perfil";
+$a->strings["Profile Image"] = "Imagen del Perfil";
+$a->strings["visible to everybody"] = "Visible para todos";
+$a->strings["Edit visibility"] = "Editar visibilidad";
+$a->strings["Gender:"] = "Género:";
+$a->strings["Status:"] = "Estado:";
+$a->strings["Homepage:"] = "Página de inicio:";
+$a->strings["About:"] = "Acerca de:";
+$a->strings["XMPP:"] = "XMPP:";
+$a->strings["Network:"] = "Red:";
+$a->strings["g A l F d"] = "g A l F d";
+$a->strings["F d"] = "F d";
+$a->strings["[today]"] = "[hoy]";
+$a->strings["Birthday Reminders"] = "Recordatorios de cumpleaños";
+$a->strings["Birthdays this week:"] = "Cumpleaños esta semana:";
+$a->strings["[No description]"] = "[Sin descripción]";
+$a->strings["Event Reminders"] = "Recordatorios de eventos";
+$a->strings["Events this week:"] = "Eventos de esta semana:";
 $a->strings["Profile"] = "Perfil";
-$a->strings["Your profile page"] = "Tu página de perfil";
+$a->strings["Full Name:"] = "Nombre completo:";
+$a->strings["j F, Y"] = "j F, Y";
+$a->strings["j F"] = "j F";
+$a->strings["Age:"] = "Edad:";
+$a->strings["for %1\$d %2\$s"] = "por %1\$d %2\$s";
+$a->strings["Sexual Preference:"] = "Preferencia sexual:";
+$a->strings["Hometown:"] = "Ciudad de origen:";
+$a->strings["Tags:"] = "Etiquetas:";
+$a->strings["Political Views:"] = "Ideas políticas:";
+$a->strings["Religion:"] = "Religión:";
+$a->strings["Hobbies/Interests:"] = "Aficiones/Intereses:";
+$a->strings["Likes:"] = "Me gusta:";
+$a->strings["Dislikes:"] = "No me gusta:";
+$a->strings["Contact information and Social Networks:"] = "Información de contacto y Redes sociales:";
+$a->strings["Musical interests:"] = "Intereses musicales:";
+$a->strings["Books, literature:"] = "Libros, literatura:";
+$a->strings["Television:"] = "Televisión:";
+$a->strings["Film/dance/culture/entertainment:"] = "Películas/baile/cultura/entretenimiento:";
+$a->strings["Love/Romance:"] = "Amor/Romance:";
+$a->strings["Work/employment:"] = "Trabajo/ocupación:";
+$a->strings["School/education:"] = "Escuela/estudios:";
+$a->strings["Forums:"] = "Foros:";
+$a->strings["Basic"] = "Basic";
+$a->strings["Advanced"] = "Avanzado";
+$a->strings["Status"] = "Estado";
+$a->strings["Status Messages and Posts"] = "Mensajes de Estado y Publicaciones";
+$a->strings["Profile Details"] = "Detalles del Perfil";
 $a->strings["Photos"] = "Fotografías";
-$a->strings["Your photos"] = "Tus fotos";
+$a->strings["Photo Albums"] = "Álbum de Fotos";
 $a->strings["Videos"] = "Videos";
-$a->strings["Your videos"] = "Tus videos";
 $a->strings["Events"] = "Eventos";
-$a->strings["Your events"] = "Tus eventos";
-$a->strings["Personal notes"] = "Notas personales";
-$a->strings["Your personal notes"] = "Tus notas personales";
-$a->strings["Login"] = "Acceder";
-$a->strings["Sign in"] = "Date de alta";
-$a->strings["Home"] = "Inicio";
-$a->strings["Home Page"] = "Página de inicio";
-$a->strings["Register"] = "Registrarse";
+$a->strings["Events and Calendar"] = "Eventos y Calendario";
+$a->strings["Personal Notes"] = "Notas personales";
+$a->strings["Only You Can See This"] = "Únicamente tú puedes ver esto";
+$a->strings["Contacts"] = "Contactos";
+$a->strings["[Name Withheld]"] = "[Nombre oculto]";
+$a->strings["Item not found."] = "Elemento no encontrado.";
+$a->strings["Do you really want to delete this item?"] = "¿Realmente quieres borrar este objeto?";
+$a->strings["Yes"] = "Sí";
+$a->strings["Permission denied."] = "Permiso denegado.";
+$a->strings["Archives"] = "Archivos";
+$a->strings["%1\$s is attending %2\$s's %3\$s"] = "%1\$s atenderá %2\$s's %3\$s";
+$a->strings["%1\$s is not attending %2\$s's %3\$s"] = "%1\$s no atenderá %2\$s's %3\$s";
+$a->strings["%1\$s may attend %2\$s's %3\$s"] = "%1\$s puede que atienda %2\$s's %3\$s";
+$a->strings["[no subject]"] = "[sin asunto]";
+$a->strings["Nothing new here"] = "Nada nuevo por aquí";
+$a->strings["Clear notifications"] = "Limpiar notificaciones";
+$a->strings["@name, !forum, #tags, content"] = "@name, !forum, #tags, contenido";
+$a->strings["End this session"] = "Cerrar la sesión";
+$a->strings["Your posts and conversations"] = "Tus publicaciones y conversaciones";
+$a->strings["Your profile page"] = "Tu página de perfil";
+$a->strings["Your photos"] = "Tus fotos";
+$a->strings["Your videos"] = "Tus videos";
+$a->strings["Your events"] = "Tus eventos";
+$a->strings["Personal notes"] = "Notas personales";
+$a->strings["Your personal notes"] = "Tus notas personales";
+$a->strings["Sign in"] = "Date de alta";
+$a->strings["Home Page"] = "Página de inicio";
 $a->strings["Create an account"] = "Crea una cuenta";
 $a->strings["Help"] = "Ayuda";
 $a->strings["Help and documentation"] = "Ayuda y documentación";
@@ -338,20 +540,16 @@ $a->strings["Search"] = "Buscar";
 $a->strings["Search site content"] = " Busca contenido en la página";
 $a->strings["Full Text"] = "Texto completo";
 $a->strings["Tags"] = "Tags";
-$a->strings["Contacts"] = "Contactos";
 $a->strings["Community"] = "Comunidad";
 $a->strings["Conversations on this site"] = "Conversaciones en este sitio";
 $a->strings["Conversations on the network"] = "Conversaciones en la red";
-$a->strings["Events and Calendar"] = "Eventos y Calendario";
 $a->strings["Directory"] = "Directorio";
 $a->strings["People directory"] = "Directorio de usuarios";
 $a->strings["Information"] = "Información";
 $a->strings["Information about this friendica instance"] = "Información sobre esta instancia de friendica";
-$a->strings["Network"] = "Red";
 $a->strings["Conversations from your friends"] = "Conversaciones de tus amigos";
 $a->strings["Network Reset"] = "Reseteo de la red";
 $a->strings["Load Network page with no filters"] = "Cargar pagina de redes sin filtros";
-$a->strings["Introductions"] = "Presentaciones";
 $a->strings["Friend Requests"] = "Solicitudes de amistad";
 $a->strings["Notifications"] = "Notificaciones";
 $a->strings["See all notifications"] = "Ver todas las notificaciones";
@@ -368,292 +566,96 @@ $a->strings["Delegations"] = "Delegaciones";
 $a->strings["Delegate Page Management"] = "Delegar la administración de la página";
 $a->strings["Settings"] = "Configuración";
 $a->strings["Account settings"] = "Configuración de tu cuenta";
-$a->strings["Profiles"] = "Perfiles";
 $a->strings["Manage/Edit Profiles"] = "Manejar/editar Perfiles";
 $a->strings["Manage/edit friends and contacts"] = "Administrar/editar amigos y contactos";
 $a->strings["Admin"] = "Admin";
 $a->strings["Site setup and configuration"] = "Opciones y configuración del sitio";
 $a->strings["Navigation"] = "Navegación";
 $a->strings["Site map"] = "Mapa del sitio";
+$a->strings["view full size"] = "Ver a tamaño completo";
+$a->strings["Embedded content"] = "Contenido integrado";
+$a->strings["Embedding disabled"] = "Contenido incrustrado desabilitado";
+$a->strings["%s is now following %s."] = "%s sigue ahora a %s.";
+$a->strings["following"] = "siguiendo";
+$a->strings["%s stopped following %s."] = "%s dejó de seguir a %s.";
+$a->strings["stopped following"] = "dejó de seguir";
 $a->strings["Contact Photos"] = "Foto del contacto";
+$a->strings["Click here to upgrade."] = "Pulsa aquí para actualizar.";
+$a->strings["This action exceeds the limits set by your subscription plan."] = "Esta acción excede los límites permitidos por tu subscripción.";
+$a->strings["This action is not available under your subscription plan."] = "Esta acción no está permitida para tu subscripción.";
+$a->strings["Male"] = "Hombre";
+$a->strings["Female"] = "Mujer";
+$a->strings["Currently Male"] = "Actualmente Hombre";
+$a->strings["Currently Female"] = "Actualmente Mujer";
+$a->strings["Mostly Male"] = "Mayormente Hombre";
+$a->strings["Mostly Female"] = "Mayormente Mujer";
+$a->strings["Transgender"] = "Transgenérico";
+$a->strings["Intersex"] = "Bisexual";
+$a->strings["Transsexual"] = "Transexual";
+$a->strings["Hermaphrodite"] = "Hermafrodita";
+$a->strings["Neuter"] = "Neutro";
+$a->strings["Non-specific"] = "Sin especificar";
+$a->strings["Other"] = "Otro";
+$a->strings["Males"] = "Hombres";
+$a->strings["Females"] = "Mujeres";
+$a->strings["Gay"] = "Gay";
+$a->strings["Lesbian"] = "Lesbiana";
+$a->strings["No Preference"] = "Sin preferencias";
+$a->strings["Bisexual"] = "Bisexual";
+$a->strings["Autosexual"] = "Autosexual";
+$a->strings["Abstinent"] = "Célibe";
+$a->strings["Virgin"] = "Virgen";
+$a->strings["Deviant"] = "Desviado";
+$a->strings["Fetish"] = "Fetichista";
+$a->strings["Oodles"] = "Orgiástico";
+$a->strings["Nonsexual"] = "Asexual";
+$a->strings["Single"] = "Soltero";
+$a->strings["Lonely"] = "Solitario";
+$a->strings["Available"] = "Disponible";
+$a->strings["Unavailable"] = "No disponible";
+$a->strings["Has crush"] = "Enamorado";
+$a->strings["Infatuated"] = "Loco/a por alguien";
+$a->strings["Dating"] = "De citas";
+$a->strings["Unfaithful"] = "Infiel";
+$a->strings["Sex Addict"] = "Adicto al sexo";
+$a->strings["Friends"] = "Amigos";
+$a->strings["Friends/Benefits"] = "Amigos con beneficios";
+$a->strings["Casual"] = "Casual";
+$a->strings["Engaged"] = "Comprometido/a";
+$a->strings["Married"] = "Casado/a";
+$a->strings["Imaginarily married"] = "Casado imaginario";
+$a->strings["Partners"] = "Socios";
+$a->strings["Cohabiting"] = "Cohabitando";
+$a->strings["Common law"] = "Pareja de hecho";
+$a->strings["Happy"] = "Feliz";
+$a->strings["Not looking"] = "No busca relación";
+$a->strings["Swinger"] = "Swinger";
+$a->strings["Betrayed"] = "Traicionado/a";
+$a->strings["Separated"] = "Separado/a";
+$a->strings["Unstable"] = "Inestable";
+$a->strings["Divorced"] = "Divorciado/a";
+$a->strings["Imaginarily divorced"] = "Divorciado imaginario";
+$a->strings["Widowed"] = "Viudo/a";
+$a->strings["Uncertain"] = "Incierto";
+$a->strings["It's complicated"] = "Es complicado";
+$a->strings["Don't care"] = "No te importa";
+$a->strings["Ask me"] = "Pregúntame";
 $a->strings["Welcome "] = "Bienvenido ";
 $a->strings["Please upload a profile photo."] = "Por favor sube una foto para tu perfil.";
 $a->strings["Welcome back "] = "Bienvenido de nuevo ";
 $a->strings["The form security token was not correct. This probably happened because the form has been opened for too long (>3 hours) before submitting it."] = "La ficha de seguridad no es correcta. Seguramente haya ocurrido por haber dejado el formulario abierto demasiado tiempo (>3 horas) antes de enviarlo.";
-$a->strings["System"] = "Sistema";
-$a->strings["Personal"] = "Personal";
-$a->strings["%s commented on %s's post"] = "%s comentó la publicación de %s";
-$a->strings["%s created a new post"] = "%s creó una nueva publicación";
-$a->strings["%s liked %s's post"] = "A %s le gusta la publicación de %s";
-$a->strings["%s disliked %s's post"] = "A %s no le gusta la publicación de %s";
-$a->strings["%s is attending %s's event"] = "%s está asistiendo al evento %s's";
-$a->strings["%s is not attending %s's event"] = "%s no está asistiendo al evento %s's";
-$a->strings["%s may attend %s's event"] = "%s podría asistir al evento %s's";
-$a->strings["%s is now friends with %s"] = "%s es ahora es amigo de %s";
-$a->strings["Friend Suggestion"] = "Propuestas de amistad";
-$a->strings["Friend/Connect Request"] = "Solicitud de Amistad/Conexión";
-$a->strings["New Follower"] = "Nuevo seguidor";
-$a->strings["\n\t\t\tThe friendica developers released update %s recently,\n\t\t\tbut when I tried to install it, something went terribly wrong.\n\t\t\tThis needs to be fixed soon and I can't do it alone. Please contact a\n\t\t\tfriendica developer if you can not help me on your own. My database might be invalid."] = "\n\t\t\tLos desarolladores de friendica publicaron una actualización  %s recientemente\n\t\t\tpero cuando intento de instalarla,algo salio terriblemente mal.\n\t\t\tEsto necesita ser arreglado pronto y no puedo hacerlo solo. Por favor contacta\n\t\t\tlos desarolladores de friendica si no me podes ayudar por ti solo. Mi base de datos puede estar invalido.";
-$a->strings["The error message is\n[pre]%s[/pre]"] = "El mensaje de error es\n[pre]%s[/pre]";
-$a->strings["Errors encountered creating database tables."] = "Se han encontrados errores creando las tablas de la base de datos.";
-$a->strings["Errors encountered performing database changes."] = "Errores encontrados al ejecutar cambios en la base de datos.";
-$a->strings["(no subject)"] = "(sin asunto)";
-$a->strings["Sharing notification from Diaspora network"] = "Compartir notificaciones con la red Diaspora*";
-$a->strings["Attachments:"] = "Archivos adjuntos:";
-$a->strings["view full size"] = "Ver a tamaño completo";
-$a->strings["View Profile"] = "Ver perfil";
-$a->strings["View Status"] = "Ver estado";
-$a->strings["View Photos"] = "Ver fotos";
-$a->strings["Network Posts"] = "Publicaciones en la red";
-$a->strings["View Contact"] = "Ver contacto";
-$a->strings["Drop Contact"] = "Eliminar contacto";
-$a->strings["Send PM"] = "Enviar mensaje privado";
-$a->strings["Poke"] = "Toque";
-$a->strings["Organisation"] = "Organización";
-$a->strings["News"] = "Noticias";
-$a->strings["Forum"] = "Foro";
-$a->strings["Daily posting limit of %d posts reached. The post was rejected."] = "Limite diario de publicaciones %d alcanzado. La publicación fue rechazada.";
-$a->strings["Weekly posting limit of %d posts reached. The post was rejected."] = "Limite semanal de publicaciones %d alcanzado. La publicación fue rechazada.";
-$a->strings["Monthly posting limit of %d posts reached. The post was rejected."] = "Limite mensual de publicaciones %d alcanzado. La publicación fue rechazada.";
-$a->strings["Image/photo"] = "Imagen/Foto";
-$a->strings["<a href=\"%1\$s\" target=\"_blank\">%2\$s</a> %3\$s"] = "<a href=\"%1\$s\" target=\"_blank\">%2\$s</a> %3\$s";
-$a->strings["$1 wrote:"] = "$1 escribió:";
-$a->strings["Encrypted content"] = "Contenido cifrado";
-$a->strings["Invalid source protocol"] = "Protocolo de fuente inválido";
-$a->strings["Invalid link protocol"] = "Protocolo de enlace inválido";
-$a->strings["%1\$s attends %2\$s's %3\$s"] = "%1\$s atenderá %2\$s's %3\$s";
-$a->strings["%1\$s doesn't attend %2\$s's %3\$s"] = "%1\$s no atenderá %2\$s's %3\$s";
-$a->strings["%1\$s attends maybe %2\$s's %3\$s"] = "%1\$s atenderá quizás %2\$s's %3\$s";
-$a->strings["%1\$s is now friends with %2\$s"] = "%1\$s ahora es amigo de %2\$s";
-$a->strings["%1\$s poked %2\$s"] = "%1\$s le dio un toque a %2\$s";
-$a->strings["%1\$s is currently %2\$s"] = "%1\$s está actualmente %2\$s";
-$a->strings["%1\$s tagged %2\$s's %3\$s with %4\$s"] = "%1\$s ha etiquetado el %3\$s de %2\$s con %4\$s";
-$a->strings["post/item"] = "publicación/tema";
-$a->strings["%1\$s marked %2\$s's %3\$s as favorite"] = "%1\$s ha marcado %3\$s de %2\$s como Favorito";
-$a->strings["Likes"] = "Me gusta";
-$a->strings["Dislikes"] = "No me gusta";
-$a->strings["Attending"] = array(
-       0 => "Atendiendo",
-       1 => "Atendiendo",
-);
-$a->strings["Not attending"] = "No atendiendo";
-$a->strings["Might attend"] = "Puede que atienda";
-$a->strings["Select"] = "Seleccionar";
-$a->strings["Delete"] = "Eliminar";
-$a->strings["View %s's profile @ %s"] = "Ver perfil de %s @ %s";
-$a->strings["Categories:"] = "Categorías:";
-$a->strings["Filed under:"] = "Archivado en:";
-$a->strings["%s from %s"] = "%s de %s";
-$a->strings["View in context"] = "Verlo en contexto";
-$a->strings["Please wait"] = "Por favor, espera";
-$a->strings["remove"] = "eliminar";
-$a->strings["Delete Selected Items"] = "Eliminar el elemento seleccionado";
-$a->strings["Follow Thread"] = "Seguir publicacion";
-$a->strings["%s likes this."] = "A %s le gusta esto.";
-$a->strings["%s doesn't like this."] = "A %s no le gusta esto.";
-$a->strings["%s attends."] = "%s atiende.";
-$a->strings["%s doesn't attend."] = "%s no atenderá.";
-$a->strings["%s attends maybe."] = "%s quizás atenderá";
-$a->strings["and"] = "y";
-$a->strings[", and %d other people"] = " y a otras %d personas";
-$a->strings["<span  %1\$s>%2\$d people</span> like this"] = "<span  %1\$s>%2\$d personas</span> les gusta esto";
-$a->strings["%s like this."] = "A %s le gusta esto.";
-$a->strings["<span  %1\$s>%2\$d people</span> don't like this"] = "<span  %1\$s>%2\$d personas</span> no les gusta esto";
-$a->strings["%s don't like this."] = "A %s no le gusta esto.";
-$a->strings["<span  %1\$s>%2\$d people</span> attend"] = "<span  %1\$s>%2\$d personas</span> atienden";
-$a->strings["%s attend."] = "%s atiende.";
-$a->strings["<span  %1\$s>%2\$d people</span> don't attend"] = "<span  %1\$s>%2\$d personas</span>no atienden";
-$a->strings["%s don't attend."] = "%s no atiende.";
-$a->strings["<span  %1\$s>%2\$d people</span> attend maybe"] = "<span  %1\$s>%2\$d people</span> quizá asistan";
-$a->strings["%s anttend maybe."] = "%s atiende quizás.";
-$a->strings["Visible to <strong>everybody</strong>"] = "Visible para <strong>cualquiera</strong>";
-$a->strings["Please enter a link URL:"] = "Introduce la dirección del enlace:";
-$a->strings["Please enter a video link/URL:"] = "Por favor, introduce la URL/enlace del vídeo:";
-$a->strings["Please enter an audio link/URL:"] = "Por favor, introduce la URL/enlace del audio:";
-$a->strings["Tag term:"] = "Etiquetar:";
-$a->strings["Save to Folder:"] = "Guardar en directorio:";
-$a->strings["Where are you right now?"] = "¿Dónde estás ahora?";
-$a->strings["Delete item(s)?"] = "¿Borrar objeto(s)?";
-$a->strings["Share"] = "Compartir";
-$a->strings["Upload photo"] = "Subir foto";
-$a->strings["upload photo"] = "subir imagen";
-$a->strings["Attach file"] = "Adjuntar archivo";
-$a->strings["attach file"] = "adjuntar archivo";
-$a->strings["Insert web link"] = "Insertar enlace";
-$a->strings["web link"] = "enlace web";
-$a->strings["Insert video link"] = "Insertar enlace del vídeo";
-$a->strings["video link"] = "enlace de video";
-$a->strings["Insert audio link"] = "Insertar vínculo del audio";
-$a->strings["audio link"] = "enlace de audio";
-$a->strings["Set your location"] = "Configurar tu localización";
-$a->strings["set location"] = "establecer tu ubicación";
-$a->strings["Clear browser location"] = "Borrar la localización del navegador";
-$a->strings["clear location"] = "limpiar la localización";
-$a->strings["Set title"] = "Establecer el título";
-$a->strings["Categories (comma-separated list)"] = "Categorías (lista separada por comas)";
-$a->strings["Permission settings"] = "Configuración de permisos";
-$a->strings["permissions"] = "permisos";
-$a->strings["Public post"] = "Publicación pública";
-$a->strings["Preview"] = "Vista previa";
-$a->strings["Cancel"] = "Cancelar";
-$a->strings["Post to Groups"] = "Publicar hacia grupos";
-$a->strings["Post to Contacts"] = "Publicar hacia contactos";
-$a->strings["Private post"] = "Publicación privada";
-$a->strings["Message"] = "Mensaje";
-$a->strings["Browser"] = "Navegador";
-$a->strings["View all"] = "Ver todos los contactos";
-$a->strings["Like"] = array(
-       0 => "Me gusta",
-       1 => "Me gusta",
-);
-$a->strings["Dislike"] = array(
-       0 => "No me gusta",
-       1 => "No me gusta",
-);
-$a->strings["Not Attending"] = array(
-       0 => "No atendiendo",
-       1 => "No atendiendo",
-);
-$a->strings["%s\\'s birthday"] = "%s\\'s cumpleaños";
-$a->strings["General Features"] = "Opciones generales";
-$a->strings["Multiple Profiles"] = "Perfiles multiples";
-$a->strings["Ability to create multiple profiles"] = "Capacidad de crear perfiles multiples. Cada pagina/perfil/usuario puede tener diferentes perfiles/apariencias. Las mismas pueden ser visibles para determinados contactos seleccionados dentro de la red friendica.";
-$a->strings["Photo Location"] = "Localización foto";
-$a->strings["Photo metadata is normally stripped. This extracts the location (if present) prior to stripping metadata and links it to a map."] = "Normalmente los meta datos de las imágenes son eliminados. Esto extraerá la localización si presente antes de eliminar los meta datos y enlaza la misma con el mapa.";
-$a->strings["Export Public Calendar"] = "Exportar Calendario Público";
-$a->strings["Ability for visitors to download the public calendar"] = "Posibilidad de los visitantes de descargar el calendario público";
-$a->strings["Post Composition Features"] = "Opciones de edición de publicaciones.";
-$a->strings["Richtext Editor"] = "Editor de texto sofisticado (richt text editor)";
-$a->strings["Enable richtext editor"] = "Habilitar editor de textos sofisticado";
-$a->strings["Post Preview"] = "Previsualizar publicaciones";
-$a->strings["Allow previewing posts and comments before publishing them"] = "Permitir la previsualización de publicaciones antes de publicar las mismas.";
-$a->strings["Auto-mention Forums"] = "Auto-mencionar foros";
-$a->strings["Add/remove mention when a forum page is selected/deselected in ACL window."] = "Añadir/eliminar mención cuando un foro es seleccionado/deseleccionado en la ventana ACL.";
-$a->strings["Network Sidebar Widgets"] = "Accesorios de red del panel lateral";
-$a->strings["Search by Date"] = "Buscar por fecha";
-$a->strings["Ability to select posts by date ranges"] = "Habilidad de seleccionar publicaciones por fecha";
-$a->strings["List Forums"] = "Listar foros";
-$a->strings["Enable widget to display the forums your are connected with"] = "Habilitar la pestaña para mostrar los foros en que estas participando.";
-$a->strings["Group Filter"] = "Filtro del grupo";
-$a->strings["Enable widget to display Network posts only from selected group"] = "Habilitar accesorios para visualizar publicaciones en la red solo de grupos seleccionados";
-$a->strings["Network Filter"] = "Filtro de red";
-$a->strings["Enable widget to display Network posts only from selected network"] = "Habilitar accesorios para visualizar publicaciones solo de las redes seleccionadas.";
-$a->strings["Saved Searches"] = "Búsquedas guardadas";
-$a->strings["Save search terms for re-use"] = "Guardar términos de búsqueda para su reutilizacion";
-$a->strings["Network Tabs"] = "Pestañas de redes";
-$a->strings["Network Personal Tab"] = "Pestaña actividad personal";
-$a->strings["Enable tab to display only Network posts that you've interacted on"] = "Habilitar para visualizar solo publicaciones con las que se ha interactuado";
-$a->strings["Network New Tab"] = "Pestaña nuevo en la red";
-$a->strings["Enable tab to display only new Network posts (from the last 12 hours)"] = "Activar para mostrar solo publicaciones nuevas en la red (de las ultimas 12 horas)";
-$a->strings["Network Shared Links Tab"] = "Pestaña publicaciones con enlaces";
-$a->strings["Enable tab to display only Network posts with links in them"] = "Habilitar para visualizar solo publicaciones que contienen enlaces";
-$a->strings["Post/Comment Tools"] = "Herramienta de publicaciones/respuestas";
-$a->strings["Multiple Deletion"] = "Borrar múltiples publicaciones";
-$a->strings["Select and delete multiple posts/comments at once"] = "Habilidad de seleccionar y borrar varias publicaciones/comentarios a la vez";
-$a->strings["Edit Sent Posts"] = "Editar temas enviados";
-$a->strings["Edit and correct posts and comments after sending"] = "Editar y corregir publicaciones y respuestas enviados. Las ediciones solo son comunicados dentro de la red friendica. No se modificaran copias enviadas a diaspora, OStatus/GNUsocial/Quitter u otros servicios conectados.";
-$a->strings["Tagging"] = "taggear";
-$a->strings["Ability to tag existing posts"] = "Habilidad de taggear publicaciones existentes";
-$a->strings["Post Categories"] = "Categorías de publicaciones";
-$a->strings["Add categories to your posts"] = "Agregue categorías a sus publicaciones. Las mismas serán visualizadas en su pagina de inicio.";
-$a->strings["Ability to file posts under folders"] = "Archivar publicaciones en carpetas";
-$a->strings["Dislike Posts"] = "Desaprobar publicación (dislike)";
-$a->strings["Ability to dislike posts/comments"] = "Habilidad de expresar desacuerdo en publicaciones y comentarios. Esta función solo es visualizado en la red friendica.";
-$a->strings["Star Posts"] = "Fijar publicaciones";
-$a->strings["Ability to mark special posts with a star indicator"] = "Habilidad de marcar - observar fijamente publicaciones.\nEl simbolo de estrella es habilitado. Se recibirán notificaciones sobre comentarios, además una pestaña de publicaciones fijadas es habilitada. En las opciones de expiración de publicaciones se puede filtrar estas publicaciones para no ser eliminados contrario a las publicaciones demás de los contactos.";
-$a->strings["Mute Post Notifications"] = "Silenciar notificaciones de una publicacion";
-$a->strings["Ability to mute notifications for a thread"] = "Habilidad de silenciar notificaciones sobre nuevos comentarios en una publicación.";
-$a->strings["Advanced Profile Settings"] = "Ajustes avanzados del perfil";
-$a->strings["Show visitors public community forums at the Advanced Profile Page"] = "Mostrar a los visitantes foros públicos en las que se esta participando en el pagina avanzada de perfiles.";
-$a->strings["Disallowed profile URL."] = "Dirección de perfil no permitida.";
-$a->strings["Connect URL missing."] = "Falta el conector URL.";
-$a->strings["This site is not configured to allow communications with other networks."] = "Este sitio no está configurado para permitir la comunicación con otras redes.";
-$a->strings["No compatible communication protocols or feeds were discovered."] = "No se ha descubierto protocolos de comunicación o fuentes compatibles.";
-$a->strings["The profile address specified does not provide adequate information."] = "La dirección del perfil especificado no proporciona información adecuada.";
-$a->strings["An author or name was not found."] = "No se ha encontrado un autor o nombre.";
-$a->strings["No browser URL could be matched to this address."] = "Ninguna dirección concuerda con la suministrada.";
-$a->strings["Unable to match @-style Identity Address with a known protocol or email contact."] = "Imposible identificar la dirección @ con algún protocolo conocido o dirección de contacto.";
-$a->strings["Use mailto: in front of address to force email check."] = "Escribe mailto: al principio de la dirección para forzar el envío.";
-$a->strings["The profile address specified belongs to a network which has been disabled on this site."] = "La dirección del perfil especificada pertenece a una red que ha sido deshabilitada en este sitio.";
-$a->strings["Limited profile. This person will be unable to receive direct/personal notifications from you."] = "Perfil limitado. Esta persona no podrá recibir notificaciones directas/personales tuyas.";
-$a->strings["Unable to retrieve contact information."] = "No ha sido posible recibir la información del contacto.";
-$a->strings["Requested account is not available."] = "La cuenta solicitada no está disponible.";
-$a->strings["Requested profile is not available."] = "El perfil solicitado no está disponible.";
-$a->strings["Edit profile"] = "Editar perfil";
-$a->strings["Atom feed"] = "Atom feed";
-$a->strings["Manage/edit profiles"] = "Administrar/editar perfiles";
-$a->strings["Change profile photo"] = "Cambiar foto del perfil";
-$a->strings["Create New Profile"] = "Crear nuevo perfil";
-$a->strings["Profile Image"] = "Imagen del Perfil";
-$a->strings["visible to everybody"] = "Visible para todos";
-$a->strings["Edit visibility"] = "Editar visibilidad";
-$a->strings["Gender:"] = "Género:";
-$a->strings["Status:"] = "Estado:";
-$a->strings["Homepage:"] = "Página de inicio:";
-$a->strings["About:"] = "Acerca de:";
-$a->strings["XMPP:"] = "XMPP:";
-$a->strings["Network:"] = "Red:";
-$a->strings["g A l F d"] = "g A l F d";
-$a->strings["F d"] = "F d";
-$a->strings["[today]"] = "[hoy]";
-$a->strings["Birthday Reminders"] = "Recordatorios de cumpleaños";
-$a->strings["Birthdays this week:"] = "Cumpleaños esta semana:";
-$a->strings["[No description]"] = "[Sin descripción]";
-$a->strings["Event Reminders"] = "Recordatorios de eventos";
-$a->strings["Events this week:"] = "Eventos de esta semana:";
-$a->strings["Full Name:"] = "Nombre completo:";
-$a->strings["j F, Y"] = "j F, Y";
-$a->strings["j F"] = "j F";
-$a->strings["Age:"] = "Edad:";
-$a->strings["for %1\$d %2\$s"] = "por %1\$d %2\$s";
-$a->strings["Sexual Preference:"] = "Preferencia sexual:";
-$a->strings["Hometown:"] = "Ciudad de origen:";
-$a->strings["Tags:"] = "Etiquetas:";
-$a->strings["Political Views:"] = "Ideas políticas:";
-$a->strings["Religion:"] = "Religión:";
-$a->strings["Hobbies/Interests:"] = "Aficiones/Intereses:";
-$a->strings["Likes:"] = "Me gusta:";
-$a->strings["Dislikes:"] = "No me gusta:";
-$a->strings["Contact information and Social Networks:"] = "Información de contacto y Redes sociales:";
-$a->strings["Musical interests:"] = "Intereses musicales:";
-$a->strings["Books, literature:"] = "Libros, literatura:";
-$a->strings["Television:"] = "Televisión:";
-$a->strings["Film/dance/culture/entertainment:"] = "Películas/baile/cultura/entretenimiento:";
-$a->strings["Love/Romance:"] = "Amor/Romance:";
-$a->strings["Work/employment:"] = "Trabajo/ocupación:";
-$a->strings["School/education:"] = "Escuela/estudios:";
-$a->strings["Forums:"] = "Foros:";
-$a->strings["Basic"] = "Basic";
-$a->strings["Advanced"] = "Avanzado";
-$a->strings["Status Messages and Posts"] = "Mensajes de Estado y Publicaciones";
-$a->strings["Profile Details"] = "Detalles del Perfil";
-$a->strings["Photo Albums"] = "Álbum de Fotos";
-$a->strings["Personal Notes"] = "Notas personales";
-$a->strings["Only You Can See This"] = "Únicamente tú puedes ver esto";
-$a->strings["[Name Withheld]"] = "[Nombre oculto]";
-$a->strings["Item not found."] = "Elemento no encontrado.";
-$a->strings["Do you really want to delete this item?"] = "¿Realmente quieres borrar este objeto?";
-$a->strings["Yes"] = "Sí";
-$a->strings["Permission denied."] = "Permiso denegado.";
-$a->strings["Archives"] = "Archivos";
-$a->strings["Embedded content"] = "Contenido integrado";
-$a->strings["Embedding disabled"] = "Contenido incrustrado desabilitado";
-$a->strings["%s is now following %s."] = "%s sigue ahora a %s.";
-$a->strings["following"] = "siguiendo";
-$a->strings["%s stopped following %s."] = "%s dejó de seguir a %s.";
-$a->strings["stopped following"] = "dejó de seguir";
-$a->strings["newer"] = "más nuevo";
-$a->strings["older"] = "más antiguo";
-$a->strings["prev"] = "ant.";
-$a->strings["first"] = "primera";
-$a->strings["last"] = "última";
-$a->strings["next"] = "sig.";
-$a->strings["Loading more entries..."] = "Cargar mas entradas ..";
-$a->strings["The end"] = "El fin";
-$a->strings["No contacts"] = "Sin contactos";
-$a->strings["%d Contact"] = array(
-       0 => "%d Contacto",
-       1 => "%d Contactos",
+$a->strings["newer"] = "más nuevo";
+$a->strings["older"] = "más antiguo";
+$a->strings["first"] = "primera";
+$a->strings["prev"] = "ant.";
+$a->strings["next"] = "sig.";
+$a->strings["last"] = "última";
+$a->strings["Loading more entries..."] = "Cargar mas entradas ..";
+$a->strings["The end"] = "El fin";
+$a->strings["No contacts"] = "Sin contactos";
+$a->strings["%d Contact"] = array(
+       0 => "%d Contacto",
+       1 => "%d Contactos",
 );
 $a->strings["View Contacts"] = "Ver contactos";
 $a->strings["Save"] = "Guardar";
@@ -701,6 +703,17 @@ $a->strings["comment"] = array(
 );
 $a->strings["post"] = "Publicación";
 $a->strings["Item filed"] = "Elemento archivado";
+$a->strings["Error decoding account file"] = "Error decodificando el archivo de cuenta";
+$a->strings["Error! No version data in file! This is not a Friendica account file?"] = "Error! No hay datos de versión en el archivo! ¿Es esto de una cuenta friendica? ";
+$a->strings["Error! Cannot check nickname"] = "Error! No puedo consultar el apodo";
+$a->strings["User '%s' already exists on this server!"] = "La cuenta '%s' ya existe en este servidor!";
+$a->strings["User creation error"] = "Error al crear la cuenta";
+$a->strings["User profile creation error"] = "Error de creación del perfil de la cuenta";
+$a->strings["%d contact not imported"] = array(
+       0 => "%d contactos no encontrado",
+       1 => "%d contactos no importado",
+);
+$a->strings["Done. You can now login with your username and password"] = "Hecho. Ahora podes ingresar con tu nombre de cuenta y la contraseña.";
 $a->strings["Passwords do not match. Password unchanged."] = "Las contraseñas no coinciden. La contraseña no ha sido modificada.";
 $a->strings["An invitation is required."] = "Se necesita invitación.";
 $a->strings["Invitation could not be verified."] = "No se puede verificar la invitación.";
@@ -725,735 +738,17 @@ $a->strings["Registration at %s"] = "Registro en %s";
 $a->strings["\n\t\tDear %1\$s,\n\t\t\tThank you for registering at %2\$s. Your account has been created.\n\t"] = "\n\t\tEstimado %1\$s,\n\t\t\tGracias por registrar en %2\$s. Su cuenta ha sido creada.\n\t";
 $a->strings["\n\t\tThe login details are as follows:\n\t\t\tSite Location:\t%3\$s\n\t\t\tLogin Name:\t%1\$s\n\t\t\tPassword:\t%5\$s\n\n\t\tYou may change your password from your account \"Settings\" page after logging\n\t\tin.\n\n\t\tPlease take a few moments to review the other account settings on that page.\n\n\t\tYou may also wish to add some basic information to your default profile\n\t\t(on the \"Profiles\" page) so that other people can easily find you.\n\n\t\tWe recommend setting your full name, adding a profile photo,\n\t\tadding some profile \"keywords\" (very useful in making new friends) - and\n\t\tperhaps what country you live in; if you do not wish to be more specific\n\t\tthan that.\n\n\t\tWe fully respect your right to privacy, and none of these items are necessary.\n\t\tIf you are new and do not know anybody here, they may help\n\t\tyou to make some new and interesting friends.\n\n\n\t\tThank you and welcome to %2\$s."] = "\n\t\t\tLos detalles de acceso son las siguientes:\n\n\t\t\tDirección del sitio:\t%3\$s\n\t\t\tNombre de la cuenta:\t\t%1\$s\n\t\t\tContraseña:\t\t%5\$s\n\n\t\t\tPodrá cambiar la contraseña desde la pagina de configuración de su cuenta después de acceder a la misma\n\t\t\ten.\n\n\t\t\tPor favor tome unos minutos para revisar las opciones demás de la cuenta en dicha pagina de configuración.\n\n\t\t\tTambién podrá agregar informaciones adicionales a su pagina de perfil predeterminado. \n\t\t\t(en la pagina \"Perfiles\") para que otras personas pueden encontrarlo fácilmente.\n\n\t\t\tRecomendamos que elija un nombre apropiado, agregando una imagen de perfil,\n\t\t\tagregando algunas palabras claves de la cuenta (muy útil para hacer nuevos amigos) - y \n\t\t\tquizás el país en donde vive; si no quiere ser mas especifico\n\t\t\tque eso.\n\n\t\t\tRespetamos absolutamente su derecho a la privacidad y ninguno de estos detalles es necesario.\n\t\t\tSi eres nuevo aquí y no conoces a nadie, estos detalles pueden ayudarte\n\t\t\tpara hacer nuevas e interesantes amistades.\n\n\t\t\tGracias y bienvenido a  %2\$s.";
 $a->strings["Registration details for %s"] = "Detalles de registro para %s";
-$a->strings["Post successful."] = "¡Publicado!";
-$a->strings["Access denied."] = "Acceso denegado.";
-$a->strings["Welcome to %s"] = "Bienvenido a %s";
-$a->strings["No more system notifications."] = "No hay más notificaciones del sistema.";
-$a->strings["System Notifications"] = "Notificaciones del sistema";
-$a->strings["Remove term"] = "Eliminar término";
-$a->strings["Public access denied."] = "Acceso público denegado.";
-$a->strings["Only logged in users are permitted to perform a search."] = "Solo usuarios activos tienen permiso para ejecutar búsquedas.";
-$a->strings["Too Many Requests"] = "Demasiadas consultas";
-$a->strings["Only one search per minute is permitted for not logged in users."] = "Se permite solo una búsqueda por minuto para usuarios no identificados.";
-$a->strings["No results."] = "Sin resultados.";
-$a->strings["Items tagged with: %s"] = "Objetos taggeado con: %s";
-$a->strings["Results for: %s"] = "Resultados para: %s";
-$a->strings["This is Friendica, version"] = "Esto es Friendica, versión";
-$a->strings["running at web location"] = "ejecutándose en la dirección web";
-$a->strings["Please visit <a href=\"http://friendica.com\">Friendica.com</a> to learn more about the Friendica project."] = "Por favor, visita <a href=\"http://friendica.com\">Friendica.com</a> para saber más sobre el proyecto Friendica.";
-$a->strings["Bug reports and issues: please visit"] = "Reporte de fallos y problemas: por favor visita";
-$a->strings["the bugtracker at github"] = "aviso de fallas (bugs) en github";
-$a->strings["Suggestions, praise, donations, etc. - please email \"Info\" at Friendica - dot com"] = "Sugerencias, elogios, donaciones, etc. por favor manda un correo a Info arroba Friendica punto com";
-$a->strings["Installed plugins/addons/apps:"] = "Módulos/extensiones/aplicaciones instalados:";
-$a->strings["No installed plugins/addons/apps"] = "Módulos/extensiones/aplicaciones no instalados";
-$a->strings["No valid account found."] = "No se ha encontrado ninguna cuenta válida";
-$a->strings["Password reset request issued. Check your email."] = "Solicitud de restablecimiento de contraseña enviada. Revisa tu correo.";
-$a->strings["\n\t\tDear %1\$s,\n\t\t\tA request was recently received at \"%2\$s\" to reset your account\n\t\tpassword. In order to confirm this request, please select the verification link\n\t\tbelow or paste it into your web browser address bar.\n\n\t\tIf you did NOT request this change, please DO NOT follow the link\n\t\tprovided and ignore and/or delete this email.\n\n\t\tYour password will not be changed unless we can verify that you\n\t\tissued this request."] = "\n\t\tEstimado %1\$s,\n\t\t\tUna consulta llego recientemente a \"%2\$s\" para renovar su\n\t\tcontraseña. Para confirmar esta solicitud por favor seleccione el enlace de verificación mas \n\t\tabajo o copie a pegue el mismo en la barra de dirección de su navegador.\n\n\t\tSi NO ha solicitado este cambio por favor NO SIGA este enlace\n\t\tproporcionado y ignore o borre este mail.\n\n\t\tSu contraseña no sera cambiada hasta que podamos verificar que usted haza\n\t\tsolicitado este cambio..";
-$a->strings["\n\t\tFollow this link to verify your identity:\n\n\t\t%1\$s\n\n\t\tYou will then receive a follow-up message containing the new password.\n\t\tYou may change that password from your account settings page after logging in.\n\n\t\tThe login details are as follows:\n\n\t\tSite Location:\t%2\$s\n\t\tLogin Name:\t%3\$s"] = "\n\t\tSiga este enlace para verificar su identidad:\n\n\t\t%1\$s\n\n\t\tA continuación recibirá un mensaje consecutivo conteniendo la nueva contraseña.\n\t\tPodrá cambiar la contraseña después de haber accedido a la cuenta.\n\n\t\tLos detalles del acceso son las siguientes:\n\n\t\tDirección del sitio:\t%2\$s\n\t\tNombre de la cuenta:\t%3\$s";
-$a->strings["Password reset requested at %s"] = "Contraseña restablecida enviada a %s";
-$a->strings["Request could not be verified. (You may have previously submitted it.) Password reset failed."] = "La solicitud no puede ser verificada (deberías haberla proporcionado antes). Falló el restablecimiento de la contraseña.";
-$a->strings["Password Reset"] = "Restablecer la contraseña";
-$a->strings["Your password has been reset as requested."] = "Tu contraseña ha sido restablecida como solicitaste.";
-$a->strings["Your new password is"] = "Tu nueva contraseña es";
-$a->strings["Save or copy your new password - and then"] = "Guarda o copia tu nueva contraseña y luego";
-$a->strings["click here to login"] = "pulsa aquí para acceder";
-$a->strings["Your password may be changed from the <em>Settings</em> page after successful login."] = "Puedes cambiar tu contraseña desde la página de <em>Configuración</em> después de acceder con éxito.";
-$a->strings["\n\t\t\t\tDear %1\$s,\n\t\t\t\t\tYour password has been changed as requested. Please retain this\n\t\t\t\tinformation for your records (or change your password immediately to\n\t\t\t\tsomething that you will remember).\n\t\t\t"] = "\n\t\t\t\tEstimado %1\$s,\n\t\t\t\t\tSu contraseña ha cambiado como solicitado. Por favor guarde esta\n\t\t\t\tinformación para sus documentación (o cambie su contraseña inmediatamente a\n\t\t\t\talgo que pueda recordar).\n\t\t";
-$a->strings["\n\t\t\t\tYour login details are as follows:\n\n\t\t\t\tSite Location:\t%1\$s\n\t\t\t\tLogin Name:\t%2\$s\n\t\t\t\tPassword:\t%3\$s\n\n\t\t\t\tYou may change that password from your account settings page after logging in.\n\t\t\t"] = "\n\t\t\t\tSus datos de acceso son las siguientes:\n\n\t\t\t\tDirección del sitio:\t%1\$s\n\t\t\t\tNombre de cuenta:\t%2\$s\n\t\t\t\tContraseña:\t%3\$s\n\n\t\t\t\tPodrá cambiar esta contraseña después de ingresar al sitio en su pagina de configuración.\n\t\t\t";
-$a->strings["Your password has been changed at %s"] = "Tu contraseña se ha cambiado por %s";
-$a->strings["Forgot your Password?"] = "¿Olvidaste tu contraseña?";
-$a->strings["Enter your email address and submit to have your password reset. Then check your email for further instructions."] = "Introduce tu correo para restablecer tu contraseña. Luego comprueba tu correo para las instrucciones adicionales.";
-$a->strings["Nickname or Email: "] = "Apodo o Correo electrónico: ";
-$a->strings["Reset"] = "Restablecer";
-$a->strings["No profile"] = "Nigún perfil";
-$a->strings["Help:"] = "Ayuda:";
+$a->strings["You must be logged in to use addons. "] = "Tienes que estar registrado para tener acceso a los accesorios.";
 $a->strings["Not Found"] = "No se ha encontrado";
 $a->strings["Page not found."] = "Página no encontrada.";
-$a->strings["Remote privacy information not available."] = "Privacidad de la información remota no disponible.";
-$a->strings["Visible to:"] = "Visible para:";
-$a->strings["OpenID protocol error. No ID returned."] = "Error de protocolo OpenID. ID no devuelta.";
-$a->strings["Account not found and OpenID registration is not permitted on this site."] = "Cuenta no encontrada y el registro OpenID no está permitido en ese sitio.";
-$a->strings["This site has exceeded the number of allowed daily account registrations. Please try again tomorrow."] = "Este sitio ha excedido el número de registros diarios permitidos. Inténtalo de nuevo mañana por favor.";
-$a->strings["Import"] = "Importar";
-$a->strings["Move account"] = "Mover cuenta";
-$a->strings["You can import an account from another Friendica server."] = "Puedes importar una cuenta desde otro servidor de Friendica.";
-$a->strings["You need to export your account from the old server and upload it here. We will recreate your old account here with all your contacts. We will try also to inform your friends that you moved here."] = "Necesitas exportar tu cuenta del antiguo servidor y subirla aquí. Volveremos a crear tu antigua cuenta con todos tus contactos aquí. También intentaremos de informar a tus amigos de que te has mudado.";
-$a->strings["This feature is experimental. We can't import contacts from the OStatus network (GNU Social/Statusnet) or from Diaspora"] = "Esta característica es experimental. No podemos importar contactos desde la red OStatus (statusnet/identi.ca) o desde Diaspora*";
-$a->strings["Account file"] = "Archivo de la cuenta";
-$a->strings["To export your account, go to \"Settings->Export your personal data\" and select \"Export account\""] = "Para exportar el perfil vaya a \"Configuracion -> Exportar sus datos personales\" y seleccione \"Exportar cuenta\"";
-$a->strings["Visit %s's profile [%s]"] = "Ver el perfil de %s [%s]";
-$a->strings["Edit contact"] = "Modificar contacto";
-$a->strings["Contacts who are not members of a group"] = "Contactos sin grupo";
-$a->strings["Export account"] = "Exportar cuenta";
-$a->strings["Export your account info and contacts. Use this to make a backup of your account and/or to move it to another server."] = "Exporta la información de tu cuenta y tus contactos. Úsalo para guardar una copia de seguridad de tu cuenta y/o moverla a otro servidor.";
-$a->strings["Export all"] = "Exportar todo";
-$a->strings["Export your accout info, contacts and all your items as json. Could be a very big file, and could take a lot of time. Use this to make a full backup of your account (photos are not exported)"] = "Exporta la información de tu cuenta, contactos y lo demás en JSON. Puede ser un archivo bastante grande, por lo que llevará tiempo. Úsalo para hacer una copia de seguridad completa de tu cuenta (las fotos no se exportarán)";
-$a->strings["Export personal data"] = "Exportación de datos personales";
-$a->strings["Total invitation limit exceeded."] = "Límite total de invitaciones excedido.";
-$a->strings["%s : Not a valid email address."] = "%s : No es una dirección de correo válida.";
-$a->strings["Please join us on Friendica"] = "Únete a nosotros en Friendica";
-$a->strings["Invitation limit exceeded. Please contact your site administrator."] = "Límite de invitaciones sobrepasado. Contacta con el administrador del sitio.";
-$a->strings["%s : Message delivery failed."] = "%s : Ha fallado la entrega del mensaje.";
-$a->strings["%d message sent."] = array(
-       0 => "%d mensaje enviado.",
-       1 => "%d mensajes enviados.",
-);
-$a->strings["You have no more invitations available"] = "No tienes más invitaciones disponibles";
-$a->strings["Visit %s for a list of public sites that you can join. Friendica members on other sites can all connect with each other, as well as with members of many other social networks."] = "Visita %s para ver una lista de servidores públicos donde puedes darte de alta. Los miembros de otros servidores de Friendica pueden conectarse entre ellos, así como con miembros de otras redes sociales diferentes.";
-$a->strings["To accept this invitation, please visit and register at %s or any other public Friendica website."] = "Para aceptar la invitación visita y regístrate en %s o en cualquier otro servidor público de Friendica.";
-$a->strings["Friendica sites all inter-connect to create a huge privacy-enhanced social web that is owned and controlled by its members. They can also connect with many traditional social networks. See %s for a list of alternate Friendica sites you can join."] = "Los servidores de Friendica están interconectados para crear una enorme red social centrada en la privacidad y controlada por sus miembros. También se puede conectar con muchas redes sociales tradicionales. Mira en %s para poder ver un listado de servidores alternativos de Friendica donde puedes darte de alta.";
-$a->strings["Our apologies. This system is not currently configured to connect with other public sites or invite members."] = "Discúlpanos. Este sistema no está configurado actualmente para conectar con otros servidores públicos o invitar nuevos miembros.";
-$a->strings["Send invitations"] = "Enviar invitaciones";
-$a->strings["Enter email addresses, one per line:"] = "Introduce las direcciones de correo, una por línea:";
-$a->strings["Your message:"] = "Tu mensaje:";
-$a->strings["You are cordially invited to join me and other close friends on Friendica - and help us to create a better social web."] = "Estás cordialmente invitado a unirte a mi y a otros amigos en Friendica, creemos juntos una red social mejor.";
-$a->strings["You will need to supply this invitation code: \$invite_code"] = "Tienes que proporcionar el siguiente código: \$invite_code";
-$a->strings["Once you have registered, please connect with me via my profile page at:"] = "Una vez registrado, por favor contacta conmigo a través de mi página de perfil en:";
-$a->strings["For more information about the Friendica project and why we feel it is important, please visit http://friendica.com"] = "Para más información sobre el Proyecto Friendica y sobre por qué pensamos que es algo importante, visita http://friendica.com";
-$a->strings["Submit"] = "Envíar";
-$a->strings["Files"] = "Archivos";
 $a->strings["Permission denied"] = "Permiso denegado";
-$a->strings["Invalid profile identifier."] = "Identificador de perfil no válido.";
-$a->strings["Profile Visibility Editor"] = "Editor de visibilidad del perfil";
-$a->strings["Click on a contact to add or remove."] = "Pulsa en un contacto para añadirlo o eliminarlo.";
-$a->strings["Visible To"] = "Visible para";
-$a->strings["All Contacts (with secure profile access)"] = "Todos los contactos (con perfil de acceso seguro)";
-$a->strings["Tag removed"] = "Etiqueta eliminada";
-$a->strings["Remove Item Tag"] = "Eliminar etiqueta";
-$a->strings["Select a tag to remove: "] = "Selecciona una etiqueta para eliminar: ";
-$a->strings["Remove"] = "Eliminar";
-$a->strings["Resubscribing to OStatus contacts"] = "Resubscribir a contactos de OStatus";
-$a->strings["Error"] = "error";
-$a->strings["Done"] = "hecho!";
-$a->strings["Keep this window open until done."] = "Mantén esta ventana abierta hasta que el proceso ha terminado.";
-$a->strings["No potential page delegates located."] = "No se han localizado delegados potenciales de la página.";
-$a->strings["Delegates are able to manage all aspects of this account/page except for basic account settings. Please do not delegate your personal account to anybody that you do not trust completely."] = "Los delegados tienen la capacidad de gestionar todos los aspectos de esta cuenta/página, excepto los ajustes básicos de la cuenta. Por favor, no delegues tu cuenta personal a nadie en quien no confíes completamente.";
-$a->strings["Existing Page Managers"] = "Administradores actuales de la página";
-$a->strings["Existing Page Delegates"] = "Delegados actuales de la página";
-$a->strings["Potential Delegates"] = "Delegados potenciales";
-$a->strings["Add"] = "Añadir";
-$a->strings["No entries."] = "Sin entradas.";
-$a->strings["Credits"] = "Creditos";
-$a->strings["Friendica is a community project, that would not be possible without the help of many people. Here is a list of those who have contributed to the code or the translation of Friendica. Thank you all!"] = "Friendica es un proyecto comunitario, que no seria posible sin la ayuda de mucha gente. Aquí una lista de de aquellos que aportaron al código o la traducción de friendica.\nGracias a todos! ";
-$a->strings["- select -"] = "- seleccionar -";
-$a->strings["%1\$s is following %2\$s's %3\$s"] = "%1\$s está siguiendo las %3\$s de %2\$s";
-$a->strings["Item not available."] = "Elemento no disponible.";
-$a->strings["Item was not found."] = "Elemento no encontrado.";
-$a->strings["You must be logged in to use addons. "] = "Tienes que estar registrado para tener acceso a los accesorios.";
-$a->strings["Applications"] = "Aplicaciones";
-$a->strings["No installed applications."] = "Sin aplicaciones";
-$a->strings["Not Extended"] = "No extendido";
-$a->strings["Welcome to Friendica"] = "Bienvenido a Friendica ";
-$a->strings["New Member Checklist"] = "Listado de nuevos miembros";
-$a->strings["We would like to offer some tips and links to help make your experience enjoyable. Click any item to visit the relevant page. A link to this page will be visible from your home page for two weeks after your initial registration and then will quietly disappear."] = "Nos gustaría ofrecerte algunos consejos y enlaces para ayudar a hacer tu experiencia más amena. Pulsa en cualquier elemento para visitar la página correspondiente. Un enlace a esta página será visible desde tu página de inicio durante las dos semanas siguientes a tu inscripción y luego desaparecerá.";
-$a->strings["Getting Started"] = "Empezando";
-$a->strings["Friendica Walk-Through"] = "Visita guiada a Friendica";
-$a->strings["On your <em>Quick Start</em> page - find a brief introduction to your profile and network tabs, make some new connections, and find some groups to join."] = "En tu página de <em>Inicio Rápido</em> - busca una introducción breve para tus pestañas de perfil y red, haz algunas conexiones nuevas, y busca algunos grupos a los que unirte.";
-$a->strings["Go to Your Settings"] = "Ir a tus ajustes";
-$a->strings["On your <em>Settings</em> page -  change your initial password. Also make a note of your Identity Address. This looks just like an email address - and will be useful in making friends on the free social web."] = "En la página de <em>Configuración</em> puedes cambiar tu contraseña inicial. También aparece tu ID (Identity Address). Es parecida a una dirección de correo y te servirá para conectar con gente de redes sociales libres.";
-$a->strings["Review the other settings, particularly the privacy settings. An unpublished directory listing is like having an unlisted phone number. In general, you should probably publish your listing - unless all of your friends and potential friends know exactly how to find you."] = "Revisa las otras configuraciones, especialmente la configuración de privacidad. Un listado de directorio sin publicar es como tener un número de teléfono sin publicar. Normalmente querrás publicar tu listado, a menos que tus amigos y amigos potenciales sepan cómo ponerse en contacto contigo.";
-$a->strings["Upload Profile Photo"] = "Subir foto del Perfil";
-$a->strings["Upload a profile photo if you have not done so already. Studies have shown that people with real photos of themselves are ten times more likely to make friends than people who do not."] = "Sube una foto para tu perfil si no lo has hecho aún. Los estudios han demostrado que la gente que usa fotos suyas reales tienen diez veces más éxito a la hora de entablar amistad que las que no.";
-$a->strings["Edit Your Profile"] = "Editar tu perfil";
-$a->strings["Edit your <strong>default</strong> profile to your liking. Review the settings for hiding your list of friends and hiding the profile from unknown visitors."] = "Edita tu perfil <strong>predeterminado</strong> como quieras. Revisa la configuración para ocultar tu lista de amigos o tu perfil a los visitantes desconocidos.";
-$a->strings["Profile Keywords"] = "Palabras clave del perfil";
-$a->strings["Set some public keywords for your default profile which describe your interests. We may be able to find other people with similar interests and suggest friendships."] = "Define en tu perfil público algunas palabras que describan tus intereses. Así podremos buscar otras personas con los mismos gustos y sugerirte posibles amigos.";
-$a->strings["Connecting"] = "Conectando";
-$a->strings["Importing Emails"] = "Importando correos electrónicos";
-$a->strings["Enter your email access information on your Connector Settings page if you wish to import and interact with friends or mailing lists from your email INBOX"] = "Introduce la información para acceder a tu correo en la página de Configuración del conector si quieres importar e interactuar con amigos o listas de correos del buzón de entrada de tu correo electrónico.";
-$a->strings["Go to Your Contacts Page"] = "Ir a tu página de contactos";
-$a->strings["Your Contacts page is your gateway to managing friendships and connecting with friends on other networks. Typically you enter their address or site URL in the <em>Add New Contact</em> dialog."] = "Tu página de Contactos es el portal desde donde podrás manejar tus amistades y conectarte con amigos de otras redes. Normalmente introduces su dirección o la dirección de su sitio web en el recuadro \"Añadir contacto nuevo\".";
-$a->strings["Go to Your Site's Directory"] = "Ir al directorio de tu sitio";
-$a->strings["The Directory page lets you find other people in this network or other federated sites. Look for a <em>Connect</em> or <em>Follow</em> link on their profile page. Provide your own Identity Address if requested."] = "El Directorio te permite encontrar otras personas en esta red o en cualquier otro sitio federado. Busca algún enlace de <em>Conectar</em> o <em>Seguir</em> en su perfil. Proporciona tu direción personal si es necesario.";
-$a->strings["Finding New People"] = "Encontrando nueva gente";
-$a->strings["On the side panel of the Contacts page are several tools to find new friends. We can match people by interest, look up people by name or interest, and provide suggestions based on network relationships. On a brand new site, friend suggestions will usually begin to be populated within 24 hours."] = "En el panel lateral de la página de Contactos existen varias herramientas para encontrar nuevos amigos. Podemos filtrar personas por sus intereses, buscar personas por nombre o por sus intereses, y ofrecerte sugerencias basadas en sus relaciones de la red. En un sitio nuevo, las sugerencias de amigos por lo general comienzan pasadas las 24 horas.";
-$a->strings["Group Your Contacts"] = "Agrupa tus contactos";
-$a->strings["Once you have made some friends, organize them into private conversation groups from the sidebar of your Contacts page and then you can interact with each group privately on your Network page."] = "Una vez que tengas algunos amigos, puedes organizarlos en grupos privados de conversación mediante el memnú en tu página de Contactos y luego puedes interactuar con cada grupo por separado desde tu página de Red.";
-$a->strings["Why Aren't My Posts Public?"] = "¿Por qué mis publicaciones no son públicas?";
-$a->strings["Friendica respects your privacy. By default, your posts will only show up to people you've added as friends. For more information, see the help section from the link above."] = "Friendica respeta tu privacidad. Por defecto, tus publicaciones solo se mostrarán a personas que hayas añadido como amistades. Para más información, mira la sección de ayuda en el enlace de más arriba.";
-$a->strings["Getting Help"] = "Consiguiendo ayuda";
-$a->strings["Go to the Help Section"] = "Ir a la sección de ayuda";
-$a->strings["Our <strong>help</strong> pages may be consulted for detail on other program features and resources."] = "Puedes consultar nuestra página de <strong>Ayuda</strong> para más información y recursos de ayuda.";
-$a->strings["Remove My Account"] = "Eliminar mi cuenta";
-$a->strings["This will completely remove your account. Once this has been done it is not recoverable."] = "Esto eliminará por completo tu cuenta. Una vez hecho no se puede deshacer.";
-$a->strings["Please enter your password for verification:"] = "Por favor, introduce tu contraseña para la verificación:";
-$a->strings["Item not found"] = "Elemento no encontrado";
-$a->strings["Edit post"] = "Editar publicación";
-$a->strings["Time Conversion"] = "Conversión horária";
-$a->strings["Friendica provides this service for sharing events with other networks and friends in unknown timezones."] = "Friendica ofrece este servicio para compartir eventos con otros servidores de la red friendica y amigos en zonas de horarios desconocidos.";
-$a->strings["UTC time: %s"] = "Tiempo UTC: %s";
-$a->strings["Current timezone: %s"] = "Zona horaria actual: %s";
-$a->strings["Converted localtime: %s"] = "Zona horaria local convertida: %s";
-$a->strings["Please select your timezone:"] = "Por favor, selecciona tu zona horaria:";
-$a->strings["The post was created"] = "La publicación fue creada";
-$a->strings["Group created."] = "Grupo creado.";
-$a->strings["Could not create group."] = "Imposible crear el grupo.";
-$a->strings["Group not found."] = "Grupo no encontrado.";
-$a->strings["Group name changed."] = "El nombre del grupo ha cambiado.";
-$a->strings["Save Group"] = "Guardar grupo";
-$a->strings["Create a group of contacts/friends."] = "Crea un grupo de contactos/amigos.";
-$a->strings["Group removed."] = "Grupo eliminado.";
-$a->strings["Unable to remove group."] = "No se puede eliminar el grupo.";
-$a->strings["Group Editor"] = "Editor de grupos";
-$a->strings["Members"] = "Miembros";
-$a->strings["All Contacts"] = "Todos los contactos";
-$a->strings["Group is empty"] = "El grupo está vacío";
-$a->strings["Number of daily wall messages for %s exceeded. Message failed."] = "Excedido el número máximo de mensajes para %s. El mensaje no se ha enviado.";
-$a->strings["No recipient selected."] = "Ningún destinatario seleccionado";
-$a->strings["Unable to check your home location."] = "Imposible comprobar tu servidor de inicio.";
-$a->strings["Message could not be sent."] = "El mensaje no ha podido ser enviado.";
-$a->strings["Message collection failure."] = "Fallo en la recolección de mensajes.";
-$a->strings["Message sent."] = "Mensaje enviado.";
-$a->strings["No recipient."] = "Sin receptor.";
-$a->strings["Send Private Message"] = "Enviar mensaje privado";
-$a->strings["If you wish for %s to respond, please check that the privacy settings on your site allow private mail from unknown senders."] = "Si quieres que %s te responda, asegúrate de que la configuración de privacidad permite enviar correo privado a desconocidos.";
-$a->strings["To:"] = "Para:";
-$a->strings["Subject:"] = "Asunto:";
-$a->strings["link"] = "enlace";
-$a->strings["Authorize application connection"] = "Autorizar la conexión de la aplicación";
-$a->strings["Return to your app and insert this Securty Code:"] = "Regresa a tu aplicación e introduce este código de seguridad:";
-$a->strings["Please login to continue."] = "Inicia sesión para continuar.";
-$a->strings["Do you want to authorize this application to access your posts and contacts, and/or create new posts for you?"] = "¿Quieres autorizar a esta aplicación el acceso a tus mensajes y contactos, y/o crear nuevas publicaciones para ti?";
-$a->strings["No"] = "No";
-$a->strings["Source (bbcode) text:"] = "Texto fuente (bbcode):";
-$a->strings["Source (Diaspora) text to convert to BBcode:"] = "Fuente (Diaspora) para pasar a BBcode:";
-$a->strings["Source input: "] = "Entrada: ";
-$a->strings["bb2html (raw HTML): "] = "bb2html (raw HTML): ";
-$a->strings["bb2html: "] = "bb2html: ";
-$a->strings["bb2html2bb: "] = "bb2html2bb: ";
-$a->strings["bb2md: "] = "bb2md: ";
-$a->strings["bb2md2html: "] = "bb2md2html: ";
-$a->strings["bb2dia2bb: "] = "bb2dia2bb: ";
-$a->strings["bb2md2html2bb: "] = "bb2md2html2bb: ";
-$a->strings["Source input (Diaspora format): "] = "Fuente (formato Diaspora): ";
-$a->strings["diaspora2bb: "] = "diaspora2bb: ";
-$a->strings["Subscribing to OStatus contacts"] = "Subscribir a los contactos de OStatus";
-$a->strings["No contact provided."] = "Sin suministro de datos de contacto.";
-$a->strings["Couldn't fetch information for contact."] = "No se ha podido conseguir la información del contacto.";
-$a->strings["Couldn't fetch friends for contact."] = "No se ha podido conseguir datos de amigos para contactar.";
-$a->strings["success"] = "exito!";
-$a->strings["failed"] = "fallido!";
-$a->strings["ignored"] = "ignorado";
-$a->strings["%1\$s welcomes %2\$s"] = "%1\$s te da la bienvenida a %2\$s";
-$a->strings["Unable to locate contact information."] = "No se puede encontrar información del contacto.";
-$a->strings["Do you really want to delete this message?"] = "¿Estás seguro de que quieres borrar este mensaje?";
-$a->strings["Message deleted."] = "Mensaje eliminado.";
-$a->strings["Conversation removed."] = "Conversación eliminada.";
-$a->strings["No messages."] = "No hay mensajes.";
-$a->strings["Message not available."] = "Mensaje no disponibile.";
-$a->strings["Delete message"] = "Borrar mensaje";
-$a->strings["Delete conversation"] = "Eliminar conversación";
-$a->strings["No secure communications available. You <strong>may</strong> be able to respond from the sender's profile page."] = "No hay comunicaciones seguras disponibles. <strong>Podrías</strong> responder desde la página de perfil del remitente. ";
-$a->strings["Send Reply"] = "Enviar respuesta";
-$a->strings["Unknown sender - %s"] = "Remitente desconocido - %s";
-$a->strings["You and %s"] = "Tú y %s";
-$a->strings["%s and You"] = "%s y Tú";
-$a->strings["D, d M Y - g:i A"] = "D, d M Y - g:i A";
-$a->strings["%d message"] = array(
-       0 => "%d mensaje",
-       1 => "%d mensajes",
-);
-$a->strings["Manage Identities and/or Pages"] = "Administrar identidades y/o páginas";
-$a->strings["Toggle between different identities or community/group pages which share your account details or which you have been granted \"manage\" permissions"] = "Cambia entre diferentes identidades o páginas de Comunidad/Grupos que comparten los detalles de tu cuenta o sobre los que tienes permisos para administrar";
-$a->strings["Select an identity to manage: "] = "Selecciona una identidad a gestionar:";
-$a->strings["Contact settings applied."] = "Contacto configurado con éxito.";
-$a->strings["Contact update failed."] = "Error al actualizar el Contacto.";
-$a->strings["Contact not found."] = "Contacto no encontrado.";
-$a->strings["<strong>WARNING: This is highly advanced</strong> and if you enter incorrect information your communications with this contact may stop working."] = "<strong>ADVERTENCIA: Esto es muy avanzado</strong> y si se introduce información incorrecta tu conexión con este contacto puede dejar de funcionar.";
-$a->strings["Please use your browser 'Back' button <strong>now</strong> if you are uncertain what to do on this page."] = "Por favor usa el botón 'Atás' de tu navegador <strong>ahora</strong> si no tienes claro qué hacer en esta página.";
-$a->strings["No mirroring"] = "No espejar";
-$a->strings["Mirror as forwarded posting"] = "Espejar como reenvio";
-$a->strings["Mirror as my own posting"] = "Espejar como publicación propia";
-$a->strings["Return to contact editor"] = "Volver al editor de contactos";
-$a->strings["Refetch contact data"] = "Volver a solicitar datos del contacto.";
-$a->strings["Remote Self"] = "Perfil remoto";
-$a->strings["Mirror postings from this contact"] = "Espejar publicaciones de este contacto";
-$a->strings["Mark this contact as remote_self, this will cause friendica to repost new entries from this contact."] = "Marcar este contacto como perfil_remoto, esto generara que friendica reenvía nuevas publicaciones desde esta cuenta.";
-$a->strings["Name"] = "Nombre";
-$a->strings["Account Nickname"] = "Apodo de la cuenta";
-$a->strings["@Tagname - overrides Name/Nickname"] = "@Etiqueta - Sobrescribe el Nombre/Apodo";
-$a->strings["Account URL"] = "Dirección de la cuenta";
-$a->strings["Friend Request URL"] = "Dirección de la solicitud de amistad";
-$a->strings["Friend Confirm URL"] = "Dirección de confirmación de tu amigo ";
-$a->strings["Notification Endpoint URL"] = "Dirección URL de la notificación";
-$a->strings["Poll/Feed URL"] = "Dirección del Sondeo/Fuentes";
-$a->strings["New photo from this URL"] = "Nueva foto de esta dirección";
-$a->strings["No such group"] = "Ningún grupo";
-$a->strings["Group: %s"] = "Grupo: %s";
-$a->strings["This entry was edited"] = "Esta entrada fue editada";
-$a->strings["%d comment"] = array(
-       0 => "%d comentario",
-       1 => "%d comentarios",
-);
-$a->strings["Private Message"] = "Mensaje privado";
-$a->strings["I like this (toggle)"] = "Me gusta esto (cambiar)";
-$a->strings["like"] = "me gusta";
-$a->strings["I don't like this (toggle)"] = "No me gusta esto (cambiar)";
-$a->strings["dislike"] = "no me gusta";
-$a->strings["Share this"] = "Compartir esto";
-$a->strings["share"] = "compartir";
-$a->strings["This is you"] = "Este eres tú";
-$a->strings["Comment"] = "Comentar";
-$a->strings["Bold"] = "Negrita";
-$a->strings["Italic"] = "Cursiva";
-$a->strings["Underline"] = "Subrayado";
-$a->strings["Quote"] = "Cita";
-$a->strings["Code"] = "Código";
-$a->strings["Image"] = "Imagen";
-$a->strings["Link"] = "Enlace";
-$a->strings["Video"] = "Vídeo";
-$a->strings["Edit"] = "Editar";
-$a->strings["add star"] = "Añadir estrella";
-$a->strings["remove star"] = "Quitar estrella";
-$a->strings["toggle star status"] = "Añadir a destacados";
-$a->strings["starred"] = "marcados con estrellas";
-$a->strings["add tag"] = "añadir etiqueta";
-$a->strings["ignore thread"] = "ignorar publicación";
-$a->strings["unignore thread"] = "revertir ignorar publicacion";
-$a->strings["toggle ignore status"] = "cambiar estatus de observación";
-$a->strings["save to folder"] = "grabado en directorio";
-$a->strings["I will attend"] = "Voy a estar presente";
-$a->strings["I will not attend"] = "No voy a estar presente";
-$a->strings["I might attend"] = "Puede que voy a estar presente";
-$a->strings["to"] = "a";
-$a->strings["Wall-to-Wall"] = "Muro-A-Muro";
-$a->strings["via Wall-To-Wall:"] = "via Muro-A-Muro:";
-$a->strings["Friend suggestion sent."] = "Solicitud de amistad enviada.";
-$a->strings["Suggest Friends"] = "Sugerencias de amistad";
-$a->strings["Suggest a friend for %s"] = "Recomienda un amigo a %s";
-$a->strings["Mood"] = "Ánimo";
-$a->strings["Set your current mood and tell your friends"] = "Coloca tu ánimo actual y cuéntaselo a tus amigos";
-$a->strings["Poke/Prod"] = "Toque/Empujón";
-$a->strings["poke, prod or do other things to somebody"] = "da un toque, empujón o similar a alguien";
-$a->strings["Recipient"] = "Receptor";
-$a->strings["Choose what you wish to do to recipient"] = "Elige qué desea hacer con el receptor";
-$a->strings["Make this post private"] = "Hacer esta publicación privada";
-$a->strings["Image uploaded but image cropping failed."] = "Imagen recibida, pero ha fallado al recortarla.";
-$a->strings["Image size reduction [%s] failed."] = "Ha fallado la reducción de las dimensiones de la imagen [%s].";
-$a->strings["Shift-reload the page or clear browser cache if the new photo does not display immediately."] = "Recarga la página o limpia la caché del navegador si la foto nueva no aparece inmediatamente.";
-$a->strings["Unable to process image"] = "Imposible procesar la imagen";
-$a->strings["Image exceeds size limit of %s"] = "La imagen excede el limite de %s";
-$a->strings["Unable to process image."] = "Imposible procesar la imagen.";
-$a->strings["Upload File:"] = "Subir archivo:";
-$a->strings["Select a profile:"] = "Elige un perfil:";
-$a->strings["Upload"] = "Subir";
-$a->strings["or"] = "o";
-$a->strings["skip this step"] = "saltar este paso";
-$a->strings["select a photo from your photo albums"] = "elige una foto de tus álbumes";
-$a->strings["Crop Image"] = "Recortar imagen";
-$a->strings["Please adjust the image cropping for optimum viewing."] = "Por favor, ajusta el recorte de la imagen para optimizarla.";
-$a->strings["Done Editing"] = "Editado";
-$a->strings["Image uploaded successfully."] = "Imagen subida con éxito.";
-$a->strings["Image upload failed."] = "Error al subir la imagen.";
-$a->strings["Account approved."] = "Cuenta aprobada.";
-$a->strings["Registration revoked for %s"] = "Registro anulado para %s";
-$a->strings["Please login."] = "Por favor accede.";
-$a->strings["Invalid request identifier."] = "Solicitud de identificación no válida.";
-$a->strings["Discard"] = "Descartar";
-$a->strings["Ignore"] = "Ignorar";
-$a->strings["Network Notifications"] = "Notificaciones de Red";
-$a->strings["Personal Notifications"] = "Notificaciones personales";
-$a->strings["Home Notifications"] = "Notificaciones de Inicio";
-$a->strings["Show Ignored Requests"] = "Mostrar peticiones ignoradas";
-$a->strings["Hide Ignored Requests"] = "Ocultar peticiones ignoradas";
-$a->strings["Notification type: "] = "Tipo de notificación: ";
-$a->strings["suggested by %s"] = "sugerido por %s";
-$a->strings["Hide this contact from others"] = "Ocultar este contacto a los demás.";
-$a->strings["Post a new friend activity"] = "Publica tu nueva amistad";
-$a->strings["if applicable"] = "Si corresponde";
-$a->strings["Approve"] = "Aprobar";
-$a->strings["Claims to be known to you: "] = "Dice conocerte: ";
-$a->strings["yes"] = "sí";
-$a->strings["no"] = "no";
-$a->strings["Shall your connection be bidirectional or not? \"Friend\" implies that you allow to read and you subscribe to their posts. \"Fan/Admirer\" means that you allow to read but you do not want to read theirs. Approve as: "] = "¿Deberá la coneccion ser bidireccional?\n\"Amigo\" implica que permitas la lectura y subscribas a las publicaciones del contacto.\n\"Admirador\" significa que permitas la lectura de tus publicaciones pero que no quieras ver sus publicaciones.\n\nAprobar como:";
-$a->strings["Shall your connection be bidirectional or not? \"Friend\" implies that you allow to read and you subscribe to their posts. \"Sharer\" means that you allow to read but you do not want to read theirs. Approve as: "] = "¿Deberá la coneccion ser bidireccional?\n\"Amigo\" implica que permitas la lectura y subscribas a las publicaciones del contacto.\n\"Sharer\" significa que permitas la lectura de tus publicaciones pero que no quieras ver sus publicaciones.\n\nAprobar como:";
-$a->strings["Friend"] = "Amigo";
-$a->strings["Sharer"] = "Lector";
-$a->strings["Fan/Admirer"] = "Fan/Admirador";
-$a->strings["Profile URL"] = "URL Perfil";
-$a->strings["No introductions."] = "Sin presentaciones.";
-$a->strings["Show unread"] = "Mostrar no leído";
-$a->strings["Show all"] = "Mostrar todo";
-$a->strings["No more %s notifications."] = "No más notificaciones de %s.";
-$a->strings["Profile not found."] = "Perfil no encontrado.";
-$a->strings["Profile deleted."] = "Perfil eliminado.";
-$a->strings["Profile-"] = "Perfil-";
-$a->strings["New profile created."] = "Nuevo perfil creado.";
-$a->strings["Profile unavailable to clone."] = "Imposible duplicar el perfil.";
-$a->strings["Profile Name is required."] = "Se necesita un nombre de perfil.";
-$a->strings["Marital Status"] = "Estado civil";
-$a->strings["Romantic Partner"] = "Pareja sentimental";
-$a->strings["Work/Employment"] = "Trabajo/estudios";
-$a->strings["Religion"] = "Religión";
-$a->strings["Political Views"] = "Preferencias políticas";
-$a->strings["Gender"] = "Género";
-$a->strings["Sexual Preference"] = "Orientación sexual";
-$a->strings["XMPP"] = "XMPP";
-$a->strings["Homepage"] = "Página de inicio";
-$a->strings["Interests"] = "Intereses";
-$a->strings["Address"] = "Dirección";
-$a->strings["Location"] = "Ubicación";
-$a->strings["Profile updated."] = "Perfil actualizado.";
-$a->strings[" and "] = " y ";
-$a->strings["public profile"] = "perfil público";
-$a->strings["%1\$s changed %2\$s to &ldquo;%3\$s&rdquo;"] = "%1\$s cambió su %2\$s a &ldquo;%3\$s&rdquo;";
-$a->strings[" - Visit %1\$s's %2\$s"] = " - Visita %1\$s's %2\$s";
-$a->strings["%1\$s has an updated %2\$s, changing %3\$s."] = "%1\$s tiene una actualización %2\$s, cambiando %3\$s.";
-$a->strings["Hide contacts and friends:"] = "Ocultar contactos y amigos";
-$a->strings["Hide your contact/friend list from viewers of this profile?"] = "¿Ocultar tu lista de contactos/amigos en este perfil?";
-$a->strings["Show more profile fields:"] = "Mostrar mas campos del perfil:";
-$a->strings["Profile Actions"] = "Acciones de perfil";
-$a->strings["Edit Profile Details"] = "Editar detalles de tu perfil";
-$a->strings["Change Profile Photo"] = "Cambiar imagen del Perfil";
-$a->strings["View this profile"] = "Ver este perfil";
-$a->strings["Create a new profile using these settings"] = "¿Crear un nuevo perfil con esta configuración?";
-$a->strings["Clone this profile"] = "Clonar este perfil";
-$a->strings["Delete this profile"] = "Eliminar este perfil";
-$a->strings["Basic information"] = "Información básica";
-$a->strings["Profile picture"] = "Imagen del perfil";
-$a->strings["Preferences"] = "Preferencias";
-$a->strings["Status information"] = "Información del estatus";
-$a->strings["Additional information"] = "Información addicional";
-$a->strings["Relation"] = "Relación";
-$a->strings["Your Gender:"] = "Género:";
-$a->strings["<span class=\"heart\">&hearts;</span> Marital Status:"] = "<span class=\"heart\"&hearts;</span> Estado civil:";
-$a->strings["Example: fishing photography software"] = "Ejemplo: pesca fotografía software";
-$a->strings["Profile Name:"] = "Nombres del perfil:";
-$a->strings["Required"] = "Obligatorio";
-$a->strings["This is your <strong>public</strong> profile.<br />It <strong>may</strong> be visible to anybody using the internet."] = "Éste es tu perfil <strong>público</strong>.<br /><strong>Puede</strong> ser visto por cualquier usuario de internet.";
-$a->strings["Your Full Name:"] = "Tu nombre completo:";
-$a->strings["Title/Description:"] = "Título/Descrición:";
-$a->strings["Street Address:"] = "Dirección";
-$a->strings["Locality/City:"] = "Localidad/Ciudad:";
-$a->strings["Region/State:"] = "Región/Estado:";
-$a->strings["Postal/Zip Code:"] = "Código postal:";
-$a->strings["Country:"] = "País";
-$a->strings["Who: (if applicable)"] = "¿Quién? (si es aplicable)";
-$a->strings["Examples: cathy123, Cathy Williams, cathy@example.com"] = "Ejemplos: cathy123, Cathy Williams, cathy@example.com";
-$a->strings["Since [date]:"] = "Desde [fecha]:";
-$a->strings["Tell us about yourself..."] = "Háblanos sobre ti...";
-$a->strings["XMPP (Jabber) address:"] = "Dirección XMPP (Jabber):";
-$a->strings["The XMPP address will be propagated to your contacts so that they can follow you."] = "La dirección XMPP será propagada entre sus contactos para que puedan seguirle.";
-$a->strings["Homepage URL:"] = "Dirección de tu página:";
-$a->strings["Religious Views:"] = "Creencias religiosas:";
-$a->strings["Public Keywords:"] = "Palabras clave públicas:";
-$a->strings["(Used for suggesting potential friends, can be seen by others)"] = "(Utilizadas para sugerir amigos potenciales, otros pueden verlo)";
-$a->strings["Private Keywords:"] = "Palabras clave privadas:";
-$a->strings["(Used for searching profiles, never shown to others)"] = "(Utilizadas para buscar perfiles, nunca se muestra a otros)";
-$a->strings["Musical interests"] = "Gustos musicales";
-$a->strings["Books, literature"] = "Libros, literatura";
-$a->strings["Television"] = "Televisión";
-$a->strings["Film/dance/culture/entertainment"] = "Películas/baile/cultura/entretenimiento";
-$a->strings["Hobbies/Interests"] = "Aficiones/Intereses";
-$a->strings["Love/romance"] = "Amor/Romance";
-$a->strings["Work/employment"] = "Trabajo/ocupación";
-$a->strings["School/education"] = "Escuela/estudios";
-$a->strings["Contact information and Social Networks"] = "Informacioń de contacto y Redes sociales";
-$a->strings["Edit/Manage Profiles"] = "Editar/Administrar perfiles";
-$a->strings["No friends to display."] = "No hay amigos para mostrar.";
-$a->strings["Access to this profile has been restricted."] = "El acceso a este perfil ha sido restringido.";
-$a->strings["View"] = "Vista";
-$a->strings["Previous"] = "Previo";
-$a->strings["Next"] = "Siguiente";
-$a->strings["list"] = "lista";
-$a->strings["User not found"] = "Usuario no encontrado";
-$a->strings["This calendar format is not supported"] = "Este formato de calendario no se soporta";
-$a->strings["No exportable data found"] = "No se ha encontrado información exportable";
-$a->strings["calendar"] = "calendario";
-$a->strings["No contacts in common."] = "Sin contactos en común.";
-$a->strings["Common Friends"] = "Amigos comunes";
-$a->strings["Not available."] = "No disponible";
-$a->strings["Global Directory"] = "Directorio global";
-$a->strings["Find on this site"] = "Buscar en este sitio";
-$a->strings["Results for:"] = "Resultados para:";
-$a->strings["Site Directory"] = "Directorio del sitio";
-$a->strings["No entries (some entries may be hidden)."] = "Sin entradas (algunas pueden que estén ocultas).";
-$a->strings["People Search - %s"] = "Buscar perfiles - %s";
-$a->strings["Forum Search - %s"] = "Búsqueda de foro - %s";
-$a->strings["No matches"] = "Sin conincidencias";
-$a->strings["Item has been removed."] = "El elemento ha sido eliminado.";
-$a->strings["Event can not end before it has started."] = "Un evento no puede terminar antes de su comienzo.";
-$a->strings["Event title and start time are required."] = "Título del evento y hora de inicio requeridas.";
-$a->strings["Create New Event"] = "Crea un evento nuevo";
-$a->strings["Event details"] = "Detalles del evento";
-$a->strings["Starting date and Title are required."] = "Se requiere fecha de comienzo y titulo";
-$a->strings["Event Starts:"] = "Inicio del evento:";
-$a->strings["Finish date/time is not known or not relevant"] = "La fecha/hora de finalización no es conocida o es irrelevante.";
-$a->strings["Event Finishes:"] = "Finalización del evento:";
-$a->strings["Adjust for viewer timezone"] = "Ajuste de zona horaria";
-$a->strings["Description:"] = "Descripción:";
-$a->strings["Title:"] = "Título:";
-$a->strings["Share this event"] = "Comparte este evento";
-$a->strings["System down for maintenance"] = "Servicio suspendido por mantenimiento";
-$a->strings["No keywords to match. Please add keywords to your default profile."] = "No hay palabras clave que coincidan. Por favor, agrega algunas palabras claves en tu perfil predeterminado.";
-$a->strings["is interested in:"] = "estás interesado en:";
-$a->strings["Profile Match"] = "Coincidencias de Perfil";
-$a->strings["Tips for New Members"] = "Consejos para nuevos miembros";
-$a->strings["Do you really want to delete this suggestion?"] = "¿Estás seguro de que quieres borrar esta sugerencia?";
-$a->strings["No suggestions available. If this is a new site, please try again in 24 hours."] = "No hay sugerencias disponibles. Si el sitio web es nuevo inténtalo de nuevo dentro de 24 horas.";
-$a->strings["Ignore/Hide"] = "Ignorar/Ocultar";
-$a->strings["[Embedded content - reload page to view]"] = "[Contenido incrustado - recarga la página para verlo]";
-$a->strings["Recent Photos"] = "Fotos recientes";
-$a->strings["Upload New Photos"] = "Subir nuevas fotos";
-$a->strings["everybody"] = "todos";
-$a->strings["Contact information unavailable"] = "Información del contacto no disponible";
-$a->strings["Album not found."] = "Álbum no encontrado.";
-$a->strings["Delete Album"] = "Eliminar álbum";
-$a->strings["Do you really want to delete this photo album and all its photos?"] = "¿Estás seguro de quieres borrar este álbum y todas sus fotos?";
-$a->strings["Delete Photo"] = "Eliminar foto";
-$a->strings["Do you really want to delete this photo?"] = "¿Estás seguro de que quieres borrar esta foto?";
-$a->strings["%1\$s was tagged in %2\$s by %3\$s"] = "%1\$s fue etiquetado en %2\$s por %3\$s";
-$a->strings["a photo"] = "una foto";
-$a->strings["Image file is empty."] = "El archivo de imagen está vacío.";
-$a->strings["No photos selected"] = "Ninguna foto seleccionada";
-$a->strings["Access to this item is restricted."] = "El acceso a este elemento está restringido.";
-$a->strings["You have used %1$.2f Mbytes of %2$.2f Mbytes photo storage."] = "Has usado %1$.2f MB de %2$.2f MB de tu álbum de fotos.";
-$a->strings["Upload Photos"] = "Subir fotos";
-$a->strings["New album name: "] = "Nombre del nuevo álbum: ";
-$a->strings["or existing album name: "] = "o nombre de un álbum existente: ";
-$a->strings["Do not show a status post for this upload"] = "No actualizar tu estado con este envío";
-$a->strings["Show to Groups"] = "Mostrar a los Grupos";
-$a->strings["Show to Contacts"] = "Mostrar a los Contactos";
-$a->strings["Private Photo"] = "Foto Privada";
-$a->strings["Public Photo"] = "Foto Pública";
-$a->strings["Edit Album"] = "Modificar álbum";
-$a->strings["Show Newest First"] = "Mostrar más nuevos primero";
-$a->strings["Show Oldest First"] = "Mostrar más antiguos primero";
-$a->strings["View Photo"] = "Ver foto";
-$a->strings["Permission denied. Access to this item may be restricted."] = "Permiso denegado. El acceso a este elemento puede estar restringido.";
-$a->strings["Photo not available"] = "Foto no disponible";
-$a->strings["View photo"] = "Ver foto";
-$a->strings["Edit photo"] = "Modificar foto";
-$a->strings["Use as profile photo"] = "Usar como foto del perfil";
-$a->strings["View Full Size"] = "Ver a tamaño completo";
-$a->strings["Tags: "] = "Etiquetas: ";
-$a->strings["[Remove any tag]"] = "[Borrar todas las etiquetas]";
-$a->strings["New album name"] = "Nuevo nombre del álbum";
-$a->strings["Caption"] = "Título";
-$a->strings["Add a Tag"] = "Añadir una etiqueta";
-$a->strings["Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping"] = "Ejemplo: @juan, @Barbara_Ruiz, @julia@example.com, #California, #camping";
-$a->strings["Do not rotate"] = "No rotar";
-$a->strings["Rotate CW (right)"] = "Girar a la derecha";
-$a->strings["Rotate CCW (left)"] = "Girar a la izquierda";
-$a->strings["Private photo"] = "Foto privada";
-$a->strings["Public photo"] = "Foto pública";
-$a->strings["Map"] = "Mapa";
-$a->strings["View Album"] = "Ver Álbum";
-$a->strings["Registration successful. Please check your email for further instructions."] = "Te has registrado con éxito. Por favor, consulta tu correo para más información.";
-$a->strings["Failed to send email message. Here your accout details:<br> login: %s<br> password: %s<br><br>You can change your password after login."] = "Error al intentar de enviar mensaje de correo. Aquí los detalles de su cuenta: <br> login: %s<br> contraseña: %s<br><br>Puede cambiar su contraseña después de ingresar al sitio.";
-$a->strings["Registration successful."] = "Registro exitoso.";
-$a->strings["Your registration can not be processed."] = "Tu registro no se puede procesar.";
-$a->strings["Your registration is pending approval by the site owner."] = "Tu registro está pendiente de aprobación por el propietario del sitio.";
-$a->strings["You may (optionally) fill in this form via OpenID by supplying your OpenID and clicking 'Register'."] = "Puedes (opcionalmente) rellenar este formulario a través de OpenID escribiendo tu OpenID y pulsando en \"Registrar\".";
-$a->strings["If you are not familiar with OpenID, please leave that field blank and fill in the rest of the items."] = "Si no estás familiarizado con OpenID, por favor deja ese campo en blanco y rellena el resto de los elementos.";
-$a->strings["Your OpenID (optional): "] = "Tu OpenID (opcional):";
-$a->strings["Include your profile in member directory?"] = "¿Incluir tu perfil en el directorio de miembros?";
-$a->strings["Note for the admin"] = "Nota para el administrador";
-$a->strings["Leave a message for the admin, why you want to join this node"] = "Deje un mensaje para el administrador sobre por qué quiere unirse a este nodo";
-$a->strings["Membership on this site is by invitation only."] = "Sitio solo accesible mediante invitación.";
-$a->strings["Your invitation ID: "] = "ID de tu invitación: ";
-$a->strings["Registration"] = "Registro";
-$a->strings["Your Full Name (e.g. Joe Smith, real or real-looking): "] = "Nombre completo (ej. Joe Smith, real o real aparente):";
-$a->strings["Your Email Address: "] = "Tu dirección de correo: ";
-$a->strings["New Password:"] = "Contraseña nueva:";
-$a->strings["Leave empty for an auto generated password."] = "Dejar vacío para autogenerar una contraseña";
-$a->strings["Confirm:"] = "Confirmar:";
-$a->strings["Choose a profile nickname. This must begin with a text character. Your profile address on this site will then be '<strong>nickname@\$sitename</strong>'."] = "Elije un apodo. Debe comenzar con una letra. Tu dirección de perfil en este sitio va a ser \"<strong>apodo@\$nombredelsitio</strong>\".";
-$a->strings["Choose a nickname: "] = "Escoge un apodo: ";
-$a->strings["Import your profile to this friendica instance"] = "Importar tu perfil a esta instancia de friendica";
-$a->strings["Account"] = "Cuenta";
-$a->strings["Additional features"] = "Características adicionales";
-$a->strings["Display"] = "Interfaz del usuario";
-$a->strings["Social Networks"] = "Redes sociales";
-$a->strings["Plugins"] = "Módulos";
-$a->strings["Connected apps"] = "Aplicaciones conectadas";
-$a->strings["Remove account"] = "Eliminar cuenta";
-$a->strings["Missing some important data!"] = "¡Faltan algunos datos importantes!";
-$a->strings["Update"] = "Actualizar";
-$a->strings["Failed to connect with email account using the settings provided."] = "Error al conectar con la cuenta de correo mediante la configuración suministrada.";
-$a->strings["Email settings updated."] = "Configuración de correo actualizada.";
-$a->strings["Features updated"] = "Actualizaciones";
-$a->strings["Relocate message has been send to your contacts"] = "Mensaje de reubicación ha sido enviado a sus contactos.";
-$a->strings["Empty passwords are not allowed. Password unchanged."] = "No se permiten contraseñas vacías. La contraseña no ha sido modificada.";
-$a->strings["Wrong password."] = "Contraseña incorrecta";
-$a->strings["Password changed."] = "Contraseña modificada.";
-$a->strings["Password update failed. Please try again."] = "La actualización de la contraseña ha fallado. Por favor, prueba otra vez.";
-$a->strings[" Please use a shorter name."] = " Usa un nombre más corto.";
-$a->strings[" Name too short."] = " Nombre demasiado corto.";
-$a->strings["Wrong Password"] = "Contraseña incorrecta";
-$a->strings[" Not valid email."] = " Correo no válido.";
-$a->strings[" Cannot change to that email."] = " No se puede usar ese correo.";
-$a->strings["Private forum has no privacy permissions. Using default privacy group."] = "El foro privado no tiene permisos de privacidad. Usando el grupo de privacidad por defecto.";
-$a->strings["Private forum has no privacy permissions and no default privacy group."] = "El foro privado no tiene permisos de privacidad ni grupo por defecto de privacidad.";
-$a->strings["Settings updated."] = "Configuración actualizada.";
-$a->strings["Add application"] = "Agregar aplicación";
-$a->strings["Save Settings"] = "Guardar configuración";
-$a->strings["Consumer Key"] = "Clave del consumidor";
-$a->strings["Consumer Secret"] = "Secreto del consumidor";
-$a->strings["Redirect"] = "Redirigir";
-$a->strings["Icon url"] = "Dirección del ícono";
-$a->strings["You can't edit this application."] = "No puedes editar esta aplicación.";
-$a->strings["Connected Apps"] = "Aplicaciones conectadas";
-$a->strings["Client key starts with"] = "Clave de cliente comienza por";
-$a->strings["No name"] = "Sin nombre";
-$a->strings["Remove authorization"] = "Suprimir la autorización";
-$a->strings["No Plugin settings configured"] = "No se ha configurado ningún módulo";
-$a->strings["Plugin Settings"] = "Configuración de los módulos";
-$a->strings["Off"] = "Apagado";
-$a->strings["On"] = "Encendido";
-$a->strings["Additional Features"] = "Características adicionales";
-$a->strings["General Social Media Settings"] = "Configuración general de social media ";
-$a->strings["Disable intelligent shortening"] = "Deshabilitar recorte inteligente de URL";
-$a->strings["Normally the system tries to find the best link to add to shortened posts. If this option is enabled then every shortened post will always point to the original friendica post."] = "Normalemente el sistema intenta de encontrara el mejor enlace para agregar a envíos recortados (twitter, OStatus). Si esta opción se encuentra habilitado, todo envío recortado apuntara siempre al tema original en friendica.";
-$a->strings["Automatically follow any GNU Social (OStatus) followers/mentioners"] = "Automáticamente seguir cualquier GNUsocial (OStatus) seguidores o menciones ";
-$a->strings["If you receive a message from an unknown OStatus user, this option decides what to do. If it is checked, a new contact will be created for every unknown user."] = "Cuando se recibe un mensaje de un perfil desconocido de OStatus, esta opción define que hacer.\nSi es habilitado, un nuevo contacto sera creado para cada usuario.";
-$a->strings["Default group for OStatus contacts"] = "Grupo por defecto para contactos OStatus";
-$a->strings["Your legacy GNU Social account"] = "Tu cuenta GNU social conectada";
-$a->strings["If you enter your old GNU Social/Statusnet account name here (in the format user@domain.tld), your contacts will be added automatically. The field will be emptied when done."] = "Si agrega su viejo nombre de perfil  GNUsocial/Statusnet aqui (en el formato de usuario@dominio.tld), sus contactos serán añadidos automáticamente.\nEl campo sera vaciado cuando termine el proceso. ";
-$a->strings["Repair OStatus subscriptions"] = "Reparar subscripciones de OStatus";
-$a->strings["Built-in support for %s connectivity is %s"] = "El soporte integrado de conexión con %s está %s";
-$a->strings["enabled"] = "habilitado";
-$a->strings["disabled"] = "deshabilitado";
-$a->strings["GNU Social (OStatus)"] = "GNUsocial (OStatus)";
-$a->strings["Email access is disabled on this site."] = "El acceso por correo está deshabilitado en esta web.";
-$a->strings["Email/Mailbox Setup"] = "Configuración del correo/buzón";
-$a->strings["If you wish to communicate with email contacts using this service (optional), please specify how to connect to your mailbox."] = "Si quieres comunicarte con tus contactos de correo usando este servicio (opcional), por favor, especifica cómo conectar con tu buzón.";
-$a->strings["Last successful email check:"] = "Última comprobación del correo con éxito:";
-$a->strings["IMAP server name:"] = "Nombre del servidor IMAP:";
-$a->strings["IMAP port:"] = "Puerto IMAP:";
-$a->strings["Security:"] = "Seguridad:";
-$a->strings["None"] = "Ninguna";
-$a->strings["Email login name:"] = "Nombre de usuario:";
-$a->strings["Email password:"] = "Contraseña:";
-$a->strings["Reply-to address:"] = "Dirección de respuesta:";
-$a->strings["Send public posts to all email contacts:"] = "Enviar publicaciones públicas a todos los contactos de correo:";
-$a->strings["Action after import:"] = "Acción después de importar:";
-$a->strings["Move to folder"] = "Mover a un directorio";
-$a->strings["Move to folder:"] = "Mover al directorio:";
-$a->strings["No special theme for mobile devices"] = "No hay tema especial para dispositivos móviles";
-$a->strings["Display Settings"] = "Configuración Tema/Visualización";
-$a->strings["Display Theme:"] = "Utilizar tema:";
-$a->strings["Mobile Theme:"] = "Tema móvil:";
-$a->strings["Suppress warning of insecure networks"] = "Suprimir el aviso de redes inseguras";
-$a->strings["Should the system suppress the warning that the current group contains members of networks that can't receive non public postings."] = "Debería el sistema suprimir el aviso de que el grupo actual contiene miembros de redes que no pueden recibir publicaciones públicas.";
-$a->strings["Update browser every xx seconds"] = "Actualizar navegador cada xx segundos";
-$a->strings["Minimum of 10 seconds. Enter -1 to disable it."] = "Minimo 10 segundos. Ingrese -1 para deshabilitar.";
-$a->strings["Number of items to display per page:"] = "Número de elementos a mostrar por página:";
-$a->strings["Maximum of 100 items"] = "Máximo 100 elementos";
-$a->strings["Number of items to display per page when viewed from mobile device:"] = "Cantidad de objetos a visualizar cuando se usa un movil";
-$a->strings["Don't show emoticons"] = "No mostrar emoticones";
-$a->strings["Calendar"] = "Calendario";
-$a->strings["Beginning of week:"] = "Principio de la semana:";
-$a->strings["Don't show notices"] = "No mostrara avisos";
-$a->strings["Infinite scroll"] = "pagina infinita (sroll)";
-$a->strings["Automatic updates only at the top of the network page"] = "Actualizaciones automaticas solo estando al principio de la pagina";
-$a->strings["Bandwith Saver Mode"] = "Modo de guardado de ancho de banda";
-$a->strings["When enabled, embedded content is not displayed on automatic updates, they only show on page reload."] = "Cuando está habilitado, el contenido incrustado no se muestra en las actualizaciones automáticas, sólo en las páginas recargadas.";
-$a->strings["General Theme Settings"] = "Ajustes generales de tema";
-$a->strings["Custom Theme Settings"] = "Ajustes personalizados de tema";
-$a->strings["Content Settings"] = "Ajustes de contenido";
-$a->strings["Theme settings"] = "Configuración del Tema";
-$a->strings["Account Types"] = "Tipos de cuenta";
-$a->strings["Personal Page Subtypes"] = "Subtipos de página personal";
-$a->strings["Community Forum Subtypes"] = "Subtipos de foro de comunidad";
-$a->strings["Personal Page"] = "Página personal";
-$a->strings["This account is a regular personal profile"] = "Esta cuenta es un perfil personal corriente";
-$a->strings["Organisation Page"] = "Página de organización";
-$a->strings["This account is a profile for an organisation"] = "Esta cuenta es un perfil de una organización";
-$a->strings["News Page"] = "Página de noticias";
-$a->strings["This account is a news account/reflector"] = "Esta cuenta es una cuenta de noticias/reflectora";
-$a->strings["Community Forum"] = "Foro de la comunidad";
-$a->strings["This account is a community forum where people can discuss with each other"] = "Esta cuenta es un foro de comunidad donde la gente puede debatir con otros";
-$a->strings["Normal Account Page"] = "Página de cuenta normal";
-$a->strings["This account is a normal personal profile"] = "Esta cuenta es el perfil personal normal";
-$a->strings["Soapbox Page"] = "Página de tribuna";
-$a->strings["Automatically approve all connection/friend requests as read-only fans"] = "Acepta automáticamente todas las peticiones de conexión/amistad como seguidores de solo-lectura";
-$a->strings["Public Forum"] = "Foro público";
-$a->strings["Automatically approve all contact requests"] = "Aprovar autimáticamente todas las solicitudes de contacto";
-$a->strings["Automatic Friend Page"] = "Página de Amistad autómatica";
-$a->strings["Automatically approve all connection/friend requests as friends"] = "Aceptar automáticamente todas las solicitudes de conexión/amistad como amigos";
-$a->strings["Private Forum [Experimental]"] = "Foro privado [Experimental]";
-$a->strings["Private forum - approved members only"] = "Foro privado - solo miembros";
-$a->strings["OpenID:"] = "OpenID:";
-$a->strings["(Optional) Allow this OpenID to login to this account."] = "(Opcional) Permitir a este OpenID acceder a esta cuenta.";
-$a->strings["Publish your default profile in your local site directory?"] = "¿Quieres publicar tu perfil predeterminado en el directorio local del sitio?";
-$a->strings["Publish your default profile in the global social directory?"] = "¿Quieres publicar tu perfil predeterminado en el directorio social de forma global?";
-$a->strings["Hide your contact/friend list from viewers of your default profile?"] = "¿Quieres ocultar tu lista de contactos/amigos en la vista de tu perfil predeterminado?";
-$a->strings["If enabled, posting public messages to Diaspora and other networks isn't possible."] = "Si habilitado, enviar temas públicos a  a Diaspora* y otras redes no es posible. ";
-$a->strings["Allow friends to post to your profile page?"] = "¿Permites que tus amigos publiquen en tu página de perfil?";
-$a->strings["Allow friends to tag your posts?"] = "¿Permites a los amigos etiquetar tus publicaciones?";
-$a->strings["Allow us to suggest you as a potential friend to new members?"] = "¿Nos permite recomendarte como amigo potencial a los nuevos miembros?";
-$a->strings["Permit unknown people to send you private mail?"] = "¿Permites que desconocidos te manden correos privados?";
-$a->strings["Profile is <strong>not published</strong>."] = "El perfil <strong>no está publicado</strong>.";
-$a->strings["Your Identity Address is <strong>'%s'</strong> or '%s'."] = "Su dirección de identidad es <strong>'%s'</strong> o '%s'.";
-$a->strings["Automatically expire posts after this many days:"] = "Las publicaciones expirarán automáticamente después de estos días:";
-$a->strings["If empty, posts will not expire. Expired posts will be deleted"] = "Si lo dejas vacío no expirarán nunca. Las publicaciones que hayan expirado se borrarán";
-$a->strings["Advanced expiration settings"] = "Configuración avanzada de expiración";
-$a->strings["Advanced Expiration"] = "Expiración avanzada";
-$a->strings["Expire posts:"] = "¿Expiran las publicaciones?";
-$a->strings["Expire personal notes:"] = "¿Expiran las notas personales?";
-$a->strings["Expire starred posts:"] = "¿Expiran los favoritos?";
-$a->strings["Expire photos:"] = "¿Expiran las fotografías?";
-$a->strings["Only expire posts by others:"] = "Solo expiran los mensajes de los demás:";
-$a->strings["Account Settings"] = "Configuración de la cuenta";
-$a->strings["Password Settings"] = "Configuración de la contraseña";
-$a->strings["Leave password fields blank unless changing"] = "Deja la contraseña en blanco si no quieres cambiarla";
-$a->strings["Current Password:"] = "Contraseña actual:";
-$a->strings["Your current password to confirm the changes"] = "Su contraseña actual para confirmar los cambios.";
-$a->strings["Password:"] = "Contraseña:";
-$a->strings["Basic Settings"] = "Configuración básica";
-$a->strings["Email Address:"] = "Dirección de correo:";
-$a->strings["Your Timezone:"] = "Zona horaria:";
-$a->strings["Your Language:"] = "Tu idioma:";
-$a->strings["Set the language we use to show you friendica interface and to send you emails"] = "Selecciona el idioma que se usara para la interfaz del usuario y para el envío de correo.";
-$a->strings["Default Post Location:"] = "Localización predeterminada:";
-$a->strings["Use Browser Location:"] = "Usar localización del navegador:";
-$a->strings["Security and Privacy Settings"] = "Configuración de seguridad y privacidad";
-$a->strings["Maximum Friend Requests/Day:"] = "Máximo número de peticiones de amistad por día:";
-$a->strings["(to prevent spam abuse)"] = "(para prevenir el abuso de spam)";
-$a->strings["Default Post Permissions"] = "Permisos por defecto para las publicaciones";
-$a->strings["(click to open/close)"] = "(pulsa para abrir/cerrar)";
-$a->strings["Default Private Post"] = "Publicación Privada por defecto";
-$a->strings["Default Public Post"] = "Publicación Pública por defecto";
-$a->strings["Default Permissions for New Posts"] = "Permisos por defecto para nuevas publicaciones";
-$a->strings["Maximum private messages per day from unknown people:"] = "Número máximo de mensajes diarios para desconocidos:";
-$a->strings["Notification Settings"] = "Configuración de notificaciones";
-$a->strings["By default post a status message when:"] = "Publicar en tu estado cuando:";
-$a->strings["accepting a friend request"] = "aceptes una solicitud de amistad";
-$a->strings["joining a forum/community"] = "te unas a un foro/comunidad";
-$a->strings["making an <em>interesting</em> profile change"] = "hagas un cambio <em>interesante</em> en tu perfil";
-$a->strings["Send a notification email when:"] = "Enviar notificación por correo cuando:";
-$a->strings["You receive an introduction"] = "Recibas una presentación";
-$a->strings["Your introductions are confirmed"] = "Tu presentación sea confirmada";
-$a->strings["Someone writes on your profile wall"] = "Alguien escriba en el muro de mi perfil";
-$a->strings["Someone writes a followup comment"] = "Algien escriba en un comentario que sigo";
-$a->strings["You receive a private message"] = "Recibas un mensaje privado";
-$a->strings["You receive a friend suggestion"] = "Recibas una sugerencia de amistad";
-$a->strings["You are tagged in a post"] = "Seas etiquetado en una publicación";
-$a->strings["You are poked/prodded/etc. in a post"] = "Te han tocado/empujado/etc. en una publicación";
-$a->strings["Activate desktop notifications"] = "Activar notificaciones en pantalla.";
-$a->strings["Show desktop popup on new notifications"] = "Mostrar notificaciones emergentes en caso de nuevos eventos.";
-$a->strings["Text-only notification emails"] = "Notificaciones e-mail de solo texto";
-$a->strings["Send text only notification emails, without the html part"] = "Enviar las notificaciones por correo con formato de solo texto sin html.";
-$a->strings["Advanced Account/Page Type Settings"] = "Configuración avanzada de tipo de Cuenta/Página";
-$a->strings["Change the behaviour of this account for special situations"] = "Cambiar el comportamiento de esta cuenta para situaciones especiales";
-$a->strings["Relocate"] = "Relocalizar";
-$a->strings["If you have moved this profile from another server, and some of your contacts don't receive your updates, try pushing this button."] = "Si ha migrado este perfil desde otro servidor aquí y algunos contactos no reciben sus publicaciones intente  recomunicar su ubicación a traves este botón. (Como para decir el botón de los botones)";
-$a->strings["Resend relocate message to contacts"] = "Reenviar mensaje de relocalización a los contactos";
-$a->strings["Do you really want to delete this video?"] = "Realmente quieres eliminar este vídeo?";
-$a->strings["Delete Video"] = "Borrar vídeo";
-$a->strings["No videos selected"] = "Ningún vídeo seleccionado";
-$a->strings["Recent Videos"] = "Vídeos recientes";
-$a->strings["Upload New Videos"] = "Subir nuevos vídeos";
-$a->strings["Invalid request."] = "Consulta invalida";
-$a->strings["Sorry, maybe your upload is bigger than the PHP configuration allows"] = "Disculpa, posiblemente el archivo subido es mas grande que la PHP configuración permite.";
-$a->strings["Or - did you try to upload an empty file?"] = "Si no - intento de subir un archivo vacío?";
-$a->strings["File exceeds size limit of %s"] = "El archivo excede el limite de tamaño de %s";
-$a->strings["File upload failed."] = "Ha fallado la subida del archivo.";
+$a->strings["toggle mobile"] = "Cambiar a versión móvil";
 $a->strings["Theme settings updated."] = "Configuración de la apariencia actualizada.";
 $a->strings["Site"] = "Sitio";
 $a->strings["Users"] = "Usuarios";
+$a->strings["Plugins"] = "Módulos";
 $a->strings["Themes"] = "Temas";
+$a->strings["Additional features"] = "Características adicionales";
 $a->strings["DB updates"] = "Actualizaciones de la Base de Datos";
 $a->strings["Inspect Queue"] = "Inspeccionar cola";
 $a->strings["Federation Statistics"] = "Estadísticas de federación";
@@ -1492,6 +787,7 @@ $a->strings["Active plugins"] = "Módulos activos";
 $a->strings["Can not parse base url. Must have at least <scheme>://<domain>"] = "No se puede resolver la direccion URL base.\nDeberá tener al menos <scheme>://<domain>";
 $a->strings["RINO2 needs mcrypt php extension to work."] = "RINO2 precisa la extensión mcrypt para funcionar.  ";
 $a->strings["Site settings updated."] = "Configuración de actualización.";
+$a->strings["No special theme for mobile devices"] = "No hay tema especial para dispositivos móviles";
 $a->strings["No community page"] = "No hay pagina de comunidad";
 $a->strings["Public postings from users of this site"] = "Temas públicos de perfiles de este sitio.";
 $a->strings["Global community page"] = "Pagina global de comunidad";
@@ -1511,6 +807,8 @@ $a->strings["Open"] = "Abierto";
 $a->strings["No SSL policy, links will track page SSL state"] = "No existe una política de SSL, los vínculos harán un seguimiento del estado de SSL en la página";
 $a->strings["Force all links to use SSL"] = "Forzar todos los enlaces a utilizar SSL";
 $a->strings["Self-signed certificate, use SSL for local links only (discouraged)"] = "Certificación personal, usa SSL solo para enlaces locales (no recomendado)";
+$a->strings["Save Settings"] = "Guardar configuración";
+$a->strings["Registration"] = "Registro";
 $a->strings["File upload"] = "Subida de archivo";
 $a->strings["Policies"] = "Políticas";
 $a->strings["Auto Discovered Contact Directory"] = "Directorio de contactos descubierto automáticamente";
@@ -1537,8 +835,6 @@ $a->strings["SSL link policy"] = "Política de enlaces SSL";
 $a->strings["Determines whether generated links should be forced to use SSL"] = "Determina si los enlaces generados deben ser forzados a utilizar SSL";
 $a->strings["Force SSL"] = "Forzar SSL";
 $a->strings["Force all Non-SSL requests to SSL - Attention: on some systems it could lead to endless loops."] = "Forzar todos las consultas No-SSL a SSL. - ATENCIÓN: en algunos sistemas esto puede generar comportamiento recursivo interminable.";
-$a->strings["Old style 'Share'"] = "Viejo estilo de 'reenviar'";
-$a->strings["Deactivates the bbcode element 'share' for repeating items."] = "Desactiva el elemento bbcode 'reenviar' para objetos repetidos.";
 $a->strings["Hide help entry from navigation menu"] = "Ocultar la ayuda en el menú de navegación";
 $a->strings["Hides the menu entry for the Help pages from the navigation menu. You can still access it calling /help directly."] = "Oculta la entrada de las páginas de Ayuda en el menú de navegación. Todavía se puede acceder escribiendo /ayuda directamente.";
 $a->strings["Single user instance"] = "Sesión de usuario único";
@@ -1608,10 +904,6 @@ $a->strings["Proxy user"] = "Usuario proxy";
 $a->strings["Proxy URL"] = "Dirección proxy";
 $a->strings["Network timeout"] = "Tiempo de espera de red";
 $a->strings["Value is in seconds. Set to 0 for unlimited (not recommended)."] = "Valor en segundos. Usar 0 para dejarlo sin límites (no se recomienda).";
-$a->strings["Delivery interval"] = "Intervalo de actualización";
-$a->strings["Delay background delivery processes by this many seconds to reduce system load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 for large dedicated servers."] = "Retrasar la entrega de procesos en segundo plano por esta cantidad de segundos para reducir la carga del sistema. Recomendamos: 4-5 para los servidores compartidos, 2-3 para servidores privados virtuales, 0-1 para los grandes servidores dedicados.";
-$a->strings["Poll interval"] = "Intervalo de sondeo";
-$a->strings["Delay background polling processes by this many seconds to reduce system load. If 0, use delivery interval."] = "Retrasar los procesos en segundo plano de sondeo en esta cantidad de segundos para reducir la carga del sistema. Si es 0, se usará el intervalo de entrega.";
 $a->strings["Maximum Load Average"] = "Promedio de carga máxima";
 $a->strings["Maximum system load before delivery and poll processes are deferred - default 50."] = "Carga máxima del sistema antes de que la entrega y los procesos de sondeo sean retrasados - por defecto 50.";
 $a->strings["Maximum Load Average (Frontend)"] = "Carga máxima promedio (frontend)";
@@ -1634,8 +926,6 @@ $a->strings["Publish server information"] = "Publicar información del servidor"
 $a->strings["If enabled, general server and usage data will be published. The data contains the name and version of the server, number of users with public profiles, number of posts and the activated protocols and connectors. See <a href='http://the-federation.info/'>the-federation.info</a> for details."] = "Si habilitado, datos generales del servidor y estadisticas de uso serán publicados. Los datos contienen el nombre y la versión del servidor, numero de usuarios con perfiles públicos, cantidad de temas publicados y los protocolos y conectores activados. Vea <a href='http://the-federation.info/'>the-federation.info</a> por detalles.";
 $a->strings["Use MySQL full text engine"] = "Usar motor MySQL de texto completo";
 $a->strings["Activates the full text engine. Speeds up search - but can only search for four and more characters."] = "Activa el motor de texto completo. Agiliza las búsquedas, pero solo busca cuatro o más caracteres.";
-$a->strings["Suppress Language"] = "Suprimir idiomas";
-$a->strings["Suppress language information in meta information about a posting."] = "Suprimir la información de datos meta sobre informaciones de idiomas en las publicaciones.";
 $a->strings["Suppress Tags"] = "Suprimir tags";
 $a->strings["Suppress showing a list of hashtags at the end of the posting."] = "Suprimir la lista de tags al final de una publicación.";
 $a->strings["Path to item cache"] = "Ruta a la caché del objeto";
@@ -1644,16 +934,12 @@ $a->strings["Cache duration in seconds"] = "Duración de la caché en segundos";
 $a->strings["How long should the cache files be hold? Default value is 86400 seconds (One day). To disable the item cache, set the value to -1."] = "¿Por cuanto tiempo deberían los archives ser almacenados en el cache? Valor por defecto 86400 segundos (un día). Para deshabilita el item cache, ajuste el valor a -1.";
 $a->strings["Maximum numbers of comments per post"] = "Numero máximo de respuestas por tema";
 $a->strings["How much comments should be shown for each post? Default value is 100."] = "¿Cuantos comentarios deberían ser mostrados por tema? Valor por defecto es 100.";
-$a->strings["Path for lock file"] = "Ruta al archivo protegido";
-$a->strings["The lock file is used to avoid multiple pollers at one time. Only define a folder here."] = "El archivo lock es usado para evitar multiples pooler (recolectores de información) a la vez. Defina solo una carpeta aquí.";
 $a->strings["Temp path"] = "Ruta a los temporales";
 $a->strings["If you have a restricted system where the webserver can't access the system temp path, enter another path here."] = "Si tiene un sistema restringido en donde el servidor web no puede acceder la dirección del sistema temp, ingrese una dirección alternativa aquí. ";
 $a->strings["Base path to installation"] = "Ruta base para la instalación";
 $a->strings["If the system cannot detect the correct path to your installation, enter the correct path here. This setting should only be set if you are using a restricted system and symbolic links to your webroot."] = "Si el sistema no puede detectar el acceso correcto a la instalación, ingrese la dirección correcta aquí. Esta configuración solo debería utilizarse si si usa un sistema restringido y enlaces simbolicos a su webroot.";
 $a->strings["Disable picture proxy"] = "Deshabilitar proxy de imagen";
 $a->strings["The picture proxy increases performance and privacy. It shouldn't be used on systems with very low bandwith."] = "El proxy de imagen mejora el performance y privacidad. No debería ser usado en sistemas con poco ancho de banda.";
-$a->strings["Enable old style pager"] = "Habilitar paginación estilo viejo";
-$a->strings["The old style pager has page numbers but slows down massively the page speed."] = "La paginación al estilo viejo tiene números de paginas pero enlentece masivamente la velocidad de la pagina.";
 $a->strings["Only search in tags"] = "Solo buscar en tags";
 $a->strings["On large systems the text search can slow down the system extremely."] = "En sistemas grandes, la búsqueda de texto puede enlentecer el sistema gravemente.";
 $a->strings["New base url"] = "Nueva URLbase";
@@ -1662,8 +948,6 @@ $a->strings["RINO Encryption"] = "Encryptado RINO";
 $a->strings["Encryption layer between nodes."] = "Capa de encryptación entre nodos.";
 $a->strings["Embedly API key"] = "Embedly llave de API (API key) ";
 $a->strings["<a href='http://embed.ly'>Embedly</a> is used to fetch additional data for web pages. This is an optional parameter."] = "<a href='http://embed.ly'>Embedly</a> es usado para recolectar datos adicionales para paginas web. Esto es un parámetro opcional.";
-$a->strings["Enable 'worker' background processing"] = "Habilitar procesos de fondo del \"trabajador\"";
-$a->strings["The worker background processing limits the number of parallel background jobs to a maximum number and respects the system load."] = "Limita los procesos del trabajo de fondo del numero paralelo de trabajos a un numero máximo que respeta la carga del sistema.";
 $a->strings["Maximum number of parallel workers"] = "Numero máximo de trabajos paralelos de fondo.";
 $a->strings["On shared hosters set this to 2. On larger systems, values of 10 are great. Default value is 4."] = "Ajustar a 2 en un servidor compartido (shared hosting).\nEn sistemas grandes valores como 10 son excelentes.\nValor por defecto es 4.";
 $a->strings["Don't use 'proc_open' with the worker"] = "No use 'proc_open' junto al \"trabajador\"!";
@@ -1698,9 +982,11 @@ $a->strings["%s user deleted"] = array(
 $a->strings["User '%s' deleted"] = "Usuario '%s' eliminado";
 $a->strings["User '%s' unblocked"] = "Usuario '%s' desbloqueado";
 $a->strings["User '%s' blocked"] = "Usuario '%s' bloqueado'";
+$a->strings["Name"] = "Nombre";
 $a->strings["Register date"] = "Fecha de registro";
 $a->strings["Last login"] = "Último acceso";
 $a->strings["Last item"] = "Último elemento";
+$a->strings["Account"] = "Cuenta";
 $a->strings["Add User"] = "Agregar usuario";
 $a->strings["select all"] = "seleccionar todo";
 $a->strings["User registrations waiting for confirm"] = "Registro de usuarios esperando confirmación";
@@ -1708,6 +994,7 @@ $a->strings["User waiting for permanent deletion"] = "Usuario esperando anulaci
 $a->strings["Request date"] = "Solicitud de fecha";
 $a->strings["No registrations."] = "Sin registros.";
 $a->strings["Note from the user"] = "Nota para el usuario";
+$a->strings["Approve"] = "Aprobar";
 $a->strings["Deny"] = "Denegado";
 $a->strings["Block"] = "Bloquear";
 $a->strings["Unblock"] = "Desbloquear";
@@ -1746,8 +1033,47 @@ $a->strings["Must be writable by web server. Relative to your Friendica top-leve
 $a->strings["Log level"] = "Nivel de registro";
 $a->strings["PHP logging"] = "PHP logging";
 $a->strings["To enable logging of PHP errors and warnings you can add the following to the .htconfig.php file of your installation. The filename set in the 'error_log' line is relative to the friendica top-level directory and must be writeable by the web server. The option '1' for 'log_errors' and 'display_errors' is to enable these options, set to '0' to disable them."] = "Para habilitar la documentación de los errores PHP y las advertencias se puede agregar lo siguiente al archivo .htconfig.php de la instalación (ftp). La dirección definido en el 'error_log' es relativo al directorio friendica principal (top-level directory) y debe de ser habilitado para la escritura por el servidor web. La opción '1' para 'log_errors' y 'display_errors' es para habilitar estas opciones, '0' para deshabilitarlo.";
+$a->strings["Off"] = "Apagado";
+$a->strings["On"] = "Encendido";
 $a->strings["Lock feature %s"] = "Trancar opción %s ";
 $a->strings["Manage Additional Features"] = "Administrar opciones adicionales";
+$a->strings["No friends to display."] = "No hay amigos para mostrar.";
+$a->strings["Authorize application connection"] = "Autorizar la conexión de la aplicación";
+$a->strings["Return to your app and insert this Securty Code:"] = "Regresa a tu aplicación e introduce este código de seguridad:";
+$a->strings["Please login to continue."] = "Inicia sesión para continuar.";
+$a->strings["Do you want to authorize this application to access your posts and contacts, and/or create new posts for you?"] = "¿Quieres autorizar a esta aplicación el acceso a tus mensajes y contactos, y/o crear nuevas publicaciones para ti?";
+$a->strings["No"] = "No";
+$a->strings["Applications"] = "Aplicaciones";
+$a->strings["No installed applications."] = "Sin aplicaciones";
+$a->strings["Item not available."] = "Elemento no disponible.";
+$a->strings["Item was not found."] = "Elemento no encontrado.";
+$a->strings["Source (bbcode) text:"] = "Texto fuente (bbcode):";
+$a->strings["Source (Diaspora) text to convert to BBcode:"] = "Fuente (Diaspora) para pasar a BBcode:";
+$a->strings["Source input: "] = "Entrada: ";
+$a->strings["bb2html (raw HTML): "] = "bb2html (raw HTML): ";
+$a->strings["bb2html: "] = "bb2html: ";
+$a->strings["bb2html2bb: "] = "bb2html2bb: ";
+$a->strings["bb2md: "] = "bb2md: ";
+$a->strings["bb2md2html: "] = "bb2md2html: ";
+$a->strings["bb2dia2bb: "] = "bb2dia2bb: ";
+$a->strings["bb2md2html2bb: "] = "bb2md2html2bb: ";
+$a->strings["Source input (Diaspora format): "] = "Fuente (formato Diaspora): ";
+$a->strings["diaspora2bb: "] = "diaspora2bb: ";
+$a->strings["The post was created"] = "La publicación fue creada";
+$a->strings["Access to this profile has been restricted."] = "El acceso a este perfil ha sido restringido.";
+$a->strings["View"] = "Vista";
+$a->strings["Previous"] = "Previo";
+$a->strings["Next"] = "Siguiente";
+$a->strings["list"] = "lista";
+$a->strings["User not found"] = "Usuario no encontrado";
+$a->strings["This calendar format is not supported"] = "Este formato de calendario no se soporta";
+$a->strings["No exportable data found"] = "No se ha encontrado información exportable";
+$a->strings["calendar"] = "calendario";
+$a->strings["No contacts in common."] = "Sin contactos en común.";
+$a->strings["Common Friends"] = "Amigos comunes";
+$a->strings["Public access denied."] = "Acceso público denegado.";
+$a->strings["Not available."] = "No disponible";
+$a->strings["No results."] = "Sin resultados.";
 $a->strings["%d contact edited."] = array(
        0 => "%d contacto editado.",
        1 => "%d contacts edited.",
@@ -1778,10 +1104,12 @@ $a->strings["Fetch further information for feeds"] = "Recaudar informacion compl
 $a->strings["Fetch information"] = "Recaudar informacion";
 $a->strings["Fetch information and keywords"] = "Recaudar informacion y palabras claves";
 $a->strings["Contact"] = "Contacto";
+$a->strings["Submit"] = "Envíar";
 $a->strings["Profile Visibility"] = "Visibilidad del Perfil";
 $a->strings["Please choose the profile you would like to display to %s when viewing your profile securely."] = "Por favor, selecciona el perfil que quieras mostrar a %s cuando esté viendo tu perfil de forma segura.";
 $a->strings["Contact Information / Notes"] = "Información del Contacto / Notas";
 $a->strings["Edit contact notes"] = "Editar notas del contacto";
+$a->strings["Visit %s's profile [%s]"] = "Ver el perfil de %s [%s]";
 $a->strings["Block/Unblock contact"] = "Boquear/Desbloquear contacto";
 $a->strings["Ignore contact"] = "Ignorar contacto";
 $a->strings["Repair URL settings"] = "Configuración de reparación de la dirección";
@@ -1790,18 +1118,22 @@ $a->strings["Last update:"] = "Última actualización:";
 $a->strings["Update public posts"] = "Actualizar publicaciones públicas";
 $a->strings["Update now"] = "Actualizar ahora";
 $a->strings["Unignore"] = "Quitar de Ignorados";
+$a->strings["Ignore"] = "Ignorar";
 $a->strings["Currently blocked"] = "Bloqueados";
 $a->strings["Currently ignored"] = "Ignorados";
 $a->strings["Currently archived"] = "Archivados";
+$a->strings["Hide this contact from others"] = "Ocultar este contacto a los demás.";
 $a->strings["Replies/likes to your public posts <strong>may</strong> still be visible"] = "Los comentarios o \"me gusta\" en tus publicaciones públicas todavía <strong>pueden</strong> ser visibles.";
 $a->strings["Notification for new posts"] = "Notificacion de nuevos temas.";
 $a->strings["Send a notification of every new post of this contact"] = "Enviar una notificacion por nuevos temas de este contacto.";
 $a->strings["Blacklisted keywords"] = "Lista negra de palabras";
 $a->strings["Comma separated list of keywords that should not be converted to hashtags, when \"Fetch information and keywords\" is selected"] = "Lista separada por comas de palabras claves que no deberian ser convertido en #hashtags cuando \"Recaudar informacion y palabras claves\" es seleccionado";
+$a->strings["Profile URL"] = "URL Perfil";
 $a->strings["Actions"] = "Acciones";
 $a->strings["Contact Settings"] = "Ajustes del contacto";
 $a->strings["Suggestions"] = "Sugerencias";
 $a->strings["Suggest potential friends"] = "Amistades potenciales sugeridas";
+$a->strings["All Contacts"] = "Todos los contactos";
 $a->strings["Show all contacts"] = "Mostrar todos los contactos";
 $a->strings["Unblocked"] = "Desbloqueados";
 $a->strings["Only show unblocked contacts"] = "Mostrar solo contactos sin bloquear";
@@ -1814,6 +1146,8 @@ $a->strings["Only show archived contacts"] = "Mostrar solo contactos archivados"
 $a->strings["Hidden"] = "Ocultos";
 $a->strings["Only show hidden contacts"] = "Mostrar solo contactos ocultos";
 $a->strings["Search your contacts"] = "Buscar en tus contactos";
+$a->strings["Results for: %s"] = "Resultados para: %s";
+$a->strings["Update"] = "Actualizar";
 $a->strings["Archive"] = "Archivo";
 $a->strings["Unarchive"] = "Sin archivar";
 $a->strings["Batch Actions"] = "Accones en lote";
@@ -1823,10 +1157,85 @@ $a->strings["Advanced Contact Settings"] = "Configuración avanzada";
 $a->strings["Mutual Friendship"] = "Amistad recíproca";
 $a->strings["is a fan of yours"] = "es tu fan";
 $a->strings["you are a fan of"] = "eres fan de";
+$a->strings["Edit contact"] = "Modificar contacto";
 $a->strings["Toggle Blocked status"] = "Cambiar bloqueados";
 $a->strings["Toggle Ignored status"] = "Cambiar ignorados";
 $a->strings["Toggle Archive status"] = "Cambiar archivados";
 $a->strings["Delete contact"] = "Eliminar contacto";
+$a->strings["No such group"] = "Ningún grupo";
+$a->strings["Group is empty"] = "El grupo está vacío";
+$a->strings["Group: %s"] = "Grupo: %s";
+$a->strings["This entry was edited"] = "Esta entrada fue editada";
+$a->strings["%d comment"] = array(
+       0 => "%d comentario",
+       1 => "%d comentarios",
+);
+$a->strings["Private Message"] = "Mensaje privado";
+$a->strings["I like this (toggle)"] = "Me gusta esto (cambiar)";
+$a->strings["like"] = "me gusta";
+$a->strings["I don't like this (toggle)"] = "No me gusta esto (cambiar)";
+$a->strings["dislike"] = "no me gusta";
+$a->strings["Share this"] = "Compartir esto";
+$a->strings["share"] = "compartir";
+$a->strings["This is you"] = "Este eres tú";
+$a->strings["Comment"] = "Comentar";
+$a->strings["Bold"] = "Negrita";
+$a->strings["Italic"] = "Cursiva";
+$a->strings["Underline"] = "Subrayado";
+$a->strings["Quote"] = "Cita";
+$a->strings["Code"] = "Código";
+$a->strings["Image"] = "Imagen";
+$a->strings["Link"] = "Enlace";
+$a->strings["Video"] = "Vídeo";
+$a->strings["Edit"] = "Editar";
+$a->strings["add star"] = "Añadir estrella";
+$a->strings["remove star"] = "Quitar estrella";
+$a->strings["toggle star status"] = "Añadir a destacados";
+$a->strings["starred"] = "marcados con estrellas";
+$a->strings["add tag"] = "añadir etiqueta";
+$a->strings["ignore thread"] = "ignorar publicación";
+$a->strings["unignore thread"] = "revertir ignorar publicacion";
+$a->strings["toggle ignore status"] = "cambiar estatus de observación";
+$a->strings["ignored"] = "ignorado";
+$a->strings["save to folder"] = "grabado en directorio";
+$a->strings["I will attend"] = "Voy a estar presente";
+$a->strings["I will not attend"] = "No voy a estar presente";
+$a->strings["I might attend"] = "Puede que voy a estar presente";
+$a->strings["to"] = "a";
+$a->strings["Wall-to-Wall"] = "Muro-A-Muro";
+$a->strings["via Wall-To-Wall:"] = "via Muro-A-Muro:";
+$a->strings["Credits"] = "Creditos";
+$a->strings["Friendica is a community project, that would not be possible without the help of many people. Here is a list of those who have contributed to the code or the translation of Friendica. Thank you all!"] = "Friendica es un proyecto comunitario, que no seria posible sin la ayuda de mucha gente. Aquí una lista de de aquellos que aportaron al código o la traducción de friendica.\nGracias a todos! ";
+$a->strings["Contact settings applied."] = "Contacto configurado con éxito.";
+$a->strings["Contact update failed."] = "Error al actualizar el Contacto.";
+$a->strings["Contact not found."] = "Contacto no encontrado.";
+$a->strings["<strong>WARNING: This is highly advanced</strong> and if you enter incorrect information your communications with this contact may stop working."] = "<strong>ADVERTENCIA: Esto es muy avanzado</strong> y si se introduce información incorrecta tu conexión con este contacto puede dejar de funcionar.";
+$a->strings["Please use your browser 'Back' button <strong>now</strong> if you are uncertain what to do on this page."] = "Por favor usa el botón 'Atás' de tu navegador <strong>ahora</strong> si no tienes claro qué hacer en esta página.";
+$a->strings["No mirroring"] = "No espejar";
+$a->strings["Mirror as forwarded posting"] = "Espejar como reenvio";
+$a->strings["Mirror as my own posting"] = "Espejar como publicación propia";
+$a->strings["Return to contact editor"] = "Volver al editor de contactos";
+$a->strings["Refetch contact data"] = "Volver a solicitar datos del contacto.";
+$a->strings["Remote Self"] = "Perfil remoto";
+$a->strings["Mirror postings from this contact"] = "Espejar publicaciones de este contacto";
+$a->strings["Mark this contact as remote_self, this will cause friendica to repost new entries from this contact."] = "Marcar este contacto como perfil_remoto, esto generara que friendica reenvía nuevas publicaciones desde esta cuenta.";
+$a->strings["Account Nickname"] = "Apodo de la cuenta";
+$a->strings["@Tagname - overrides Name/Nickname"] = "@Etiqueta - Sobrescribe el Nombre/Apodo";
+$a->strings["Account URL"] = "Dirección de la cuenta";
+$a->strings["Friend Request URL"] = "Dirección de la solicitud de amistad";
+$a->strings["Friend Confirm URL"] = "Dirección de confirmación de tu amigo ";
+$a->strings["Notification Endpoint URL"] = "Dirección URL de la notificación";
+$a->strings["Poll/Feed URL"] = "Dirección del Sondeo/Fuentes";
+$a->strings["New photo from this URL"] = "Nueva foto de esta dirección";
+$a->strings["No potential page delegates located."] = "No se han localizado delegados potenciales de la página.";
+$a->strings["Delegates are able to manage all aspects of this account/page except for basic account settings. Please do not delegate your personal account to anybody that you do not trust completely."] = "Los delegados tienen la capacidad de gestionar todos los aspectos de esta cuenta/página, excepto los ajustes básicos de la cuenta. Por favor, no delegues tu cuenta personal a nadie en quien no confíes completamente.";
+$a->strings["Existing Page Managers"] = "Administradores actuales de la página";
+$a->strings["Existing Page Delegates"] = "Delegados actuales de la página";
+$a->strings["Potential Delegates"] = "Delegados potenciales";
+$a->strings["Remove"] = "Eliminar";
+$a->strings["Add"] = "Añadir";
+$a->strings["No entries."] = "Sin entradas.";
+$a->strings["Profile not found."] = "Perfil no encontrado.";
 $a->strings["This may occasionally happen if contact was requested by both persons and it has already been approved."] = "Esto puede ocurrir a veces si la conexión fue solicitada por ambas personas y ya hubiera sido aprobada.";
 $a->strings["Response from remote site was not understood."] = "La respuesta desde el sitio remoto no ha sido entendida.";
 $a->strings["Unexpected response from remote site: "] = "Respuesta inesperada desde el sitio remoto: ";
@@ -1844,6 +1253,7 @@ $a->strings["The ID provided by your system is a duplicate on our system. It sho
 $a->strings["Unable to set your contact credentials on our system."] = "No se puede establecer las credenciales de tu contacto en nuestro sistema.";
 $a->strings["Unable to update your contact profile details on our system"] = "No se puede actualizar los datos de tu perfil de contacto en nuestro sistema";
 $a->strings["%1\$s has joined %2\$s"] = "%1\$s se ha unido a %2\$s";
+$a->strings["%1\$s welcomes %2\$s"] = "%1\$s te da la bienvenida a %2\$s";
 $a->strings["This introduction has already been accepted."] = "Esta presentación ya ha sido aceptada.";
 $a->strings["Profile location is not valid or does not contain profile information."] = "La dirección del perfil no es válida o no contiene información del perfil.";
 $a->strings["Warning: profile location has no identifiable owner name."] = "Aviso: La dirección del perfil no tiene un nombre de propietario identificable.";
@@ -1883,11 +1293,62 @@ $a->strings["StatusNet/Federated Social Web"] = "StatusNet/Web Social Federada";
 $a->strings[" - please do not use this form.  Instead, enter %s into your Diaspora search bar."] = "(En vez de usar este formulario, introduce %s en la barra de búsqueda de Diaspora.";
 $a->strings["Your Identity Address:"] = "Dirección de tu perfil:";
 $a->strings["Submit Request"] = "Enviar solicitud";
+$a->strings["Global Directory"] = "Directorio global";
+$a->strings["Find on this site"] = "Buscar en este sitio";
+$a->strings["Results for:"] = "Resultados para:";
+$a->strings["Site Directory"] = "Directorio del sitio";
+$a->strings["No entries (some entries may be hidden)."] = "Sin entradas (algunas pueden que estén ocultas).";
+$a->strings["People Search - %s"] = "Buscar perfiles - %s";
+$a->strings["Forum Search - %s"] = "Búsqueda de foro - %s";
+$a->strings["No matches"] = "Sin conincidencias";
+$a->strings["Item has been removed."] = "El elemento ha sido eliminado.";
+$a->strings["Item not found"] = "Elemento no encontrado";
+$a->strings["Edit post"] = "Editar publicación";
+$a->strings["Event can not end before it has started."] = "Un evento no puede terminar antes de su comienzo.";
+$a->strings["Event title and start time are required."] = "Título del evento y hora de inicio requeridas.";
+$a->strings["Create New Event"] = "Crea un evento nuevo";
+$a->strings["Event details"] = "Detalles del evento";
+$a->strings["Starting date and Title are required."] = "Se requiere fecha de comienzo y titulo";
+$a->strings["Event Starts:"] = "Inicio del evento:";
+$a->strings["Required"] = "Obligatorio";
+$a->strings["Finish date/time is not known or not relevant"] = "La fecha/hora de finalización no es conocida o es irrelevante.";
+$a->strings["Event Finishes:"] = "Finalización del evento:";
+$a->strings["Adjust for viewer timezone"] = "Ajuste de zona horaria";
+$a->strings["Description:"] = "Descripción:";
+$a->strings["Title:"] = "Título:";
+$a->strings["Share this event"] = "Comparte este evento";
+$a->strings["Files"] = "Archivos";
+$a->strings["- select -"] = "- seleccionar -";
 $a->strings["You already added this contact."] = "Ya has añadido este contacto.";
 $a->strings["Diaspora support isn't enabled. Contact can't be added."] = "El soporte de Diaspora* no esta habilitado, el contacto no puede ser agregado.";
 $a->strings["OStatus support is disabled. Contact can't be added."] = "El soporte de OStatus no esta habilitado, el contacto no puede ser agregado.";
 $a->strings["The network type couldn't be detected. Contact can't be added."] = "No se pudo detectar el tipo de red. Contacto no puede ser agregado.";
 $a->strings["Contact added"] = "Contacto añadido";
+$a->strings["This is Friendica, version"] = "Esto es Friendica, versión";
+$a->strings["running at web location"] = "ejecutándose en la dirección web";
+$a->strings["Please visit <a href=\"http://friendica.com\">Friendica.com</a> to learn more about the Friendica project."] = "Por favor, visita <a href=\"http://friendica.com\">Friendica.com</a> para saber más sobre el proyecto Friendica.";
+$a->strings["Bug reports and issues: please visit"] = "Reporte de fallos y problemas: por favor visita";
+$a->strings["the bugtracker at github"] = "aviso de fallas (bugs) en github";
+$a->strings["Suggestions, praise, donations, etc. - please email \"Info\" at Friendica - dot com"] = "Sugerencias, elogios, donaciones, etc. por favor manda un correo a Info arroba Friendica punto com";
+$a->strings["Installed plugins/addons/apps:"] = "Módulos/extensiones/aplicaciones instalados:";
+$a->strings["No installed plugins/addons/apps"] = "Módulos/extensiones/aplicaciones no instalados";
+$a->strings["Friend suggestion sent."] = "Solicitud de amistad enviada.";
+$a->strings["Suggest Friends"] = "Sugerencias de amistad";
+$a->strings["Suggest a friend for %s"] = "Recomienda un amigo a %s";
+$a->strings["Group created."] = "Grupo creado.";
+$a->strings["Could not create group."] = "Imposible crear el grupo.";
+$a->strings["Group not found."] = "Grupo no encontrado.";
+$a->strings["Group name changed."] = "El nombre del grupo ha cambiado.";
+$a->strings["Save Group"] = "Guardar grupo";
+$a->strings["Create a group of contacts/friends."] = "Crea un grupo de contactos/amigos.";
+$a->strings["Group removed."] = "Grupo eliminado.";
+$a->strings["Unable to remove group."] = "No se puede eliminar el grupo.";
+$a->strings["Group Editor"] = "Editor de grupos";
+$a->strings["Members"] = "Miembros";
+$a->strings["Click on a contact to add or remove."] = "Pulsa en un contacto para añadirlo o eliminarlo.";
+$a->strings["No profile"] = "Nigún perfil";
+$a->strings["Help:"] = "Ayuda:";
+$a->strings["Welcome to %s"] = "Bienvenido a %s";
 $a->strings["Friendica Communications Server - Setup"] = "Servidor de comunicación Friendica - Configuración";
 $a->strings["Could not connect to database."] = "No es posible la conexión con la base de datos.";
 $a->strings["Could not create table."] = "No se puede crear la tabla.";
@@ -1904,6 +1365,7 @@ $a->strings["The database you specify below should already exist. If it does not
 $a->strings["Database Server Name"] = "Nombre del servidor de la base de datos";
 $a->strings["Database Login Name"] = "Usuario de la base de datos";
 $a->strings["Database Login Password"] = "Contraseña de la base de datos";
+$a->strings["For security reasons the password must not be empty"] = "Por razones de seguridad la contraseña no debe estar vacía";
 $a->strings["Database Name"] = "Nombre de la base de datos";
 $a->strings["Site administrator email address"] = "Dirección de correo del administrador de la web";
 $a->strings["Your account email address must match this in order to use the web admin panel."] = "La dirección de correo de tu cuenta debe coincidir con esta para poder usar el panel de administración de la web.";
@@ -1964,6 +1426,27 @@ $a->strings["ImageMagick supports GIF"] = "ImageMagick supporta GIF";
 $a->strings["The database configuration file \".htconfig.php\" could not be written. Please use the enclosed text to create a configuration file in your web server root."] = "El archivo de configuración de base de datos \".htconfig.php\" no se pudo escribir. Por favor, utiliza el texto adjunto para crear un archivo de configuración en la raíz de tu servidor web.";
 $a->strings["<h1>What next</h1>"] = "<h1>¿Ahora qué?</h1>";
 $a->strings["IMPORTANT: You will need to [manually] setup a scheduled task for the poller."] = "IMPORTANTE: Tendrás que configurar [manualmente] una tarea programada para el sondeo";
+$a->strings["Total invitation limit exceeded."] = "Límite total de invitaciones excedido.";
+$a->strings["%s : Not a valid email address."] = "%s : No es una dirección de correo válida.";
+$a->strings["Please join us on Friendica"] = "Únete a nosotros en Friendica";
+$a->strings["Invitation limit exceeded. Please contact your site administrator."] = "Límite de invitaciones sobrepasado. Contacta con el administrador del sitio.";
+$a->strings["%s : Message delivery failed."] = "%s : Ha fallado la entrega del mensaje.";
+$a->strings["%d message sent."] = array(
+       0 => "%d mensaje enviado.",
+       1 => "%d mensajes enviados.",
+);
+$a->strings["You have no more invitations available"] = "No tienes más invitaciones disponibles";
+$a->strings["Visit %s for a list of public sites that you can join. Friendica members on other sites can all connect with each other, as well as with members of many other social networks."] = "Visita %s para ver una lista de servidores públicos donde puedes darte de alta. Los miembros de otros servidores de Friendica pueden conectarse entre ellos, así como con miembros de otras redes sociales diferentes.";
+$a->strings["To accept this invitation, please visit and register at %s or any other public Friendica website."] = "Para aceptar la invitación visita y regístrate en %s o en cualquier otro servidor público de Friendica.";
+$a->strings["Friendica sites all inter-connect to create a huge privacy-enhanced social web that is owned and controlled by its members. They can also connect with many traditional social networks. See %s for a list of alternate Friendica sites you can join."] = "Los servidores de Friendica están interconectados para crear una enorme red social centrada en la privacidad y controlada por sus miembros. También se puede conectar con muchas redes sociales tradicionales. Mira en %s para poder ver un listado de servidores alternativos de Friendica donde puedes darte de alta.";
+$a->strings["Our apologies. This system is not currently configured to connect with other public sites or invite members."] = "Discúlpanos. Este sistema no está configurado actualmente para conectar con otros servidores públicos o invitar nuevos miembros.";
+$a->strings["Send invitations"] = "Enviar invitaciones";
+$a->strings["Enter email addresses, one per line:"] = "Introduce las direcciones de correo, una por línea:";
+$a->strings["Your message:"] = "Tu mensaje:";
+$a->strings["You are cordially invited to join me and other close friends on Friendica - and help us to create a better social web."] = "Estás cordialmente invitado a unirte a mi y a otros amigos en Friendica, creemos juntos una red social mejor.";
+$a->strings["You will need to supply this invitation code: \$invite_code"] = "Tienes que proporcionar el siguiente código: \$invite_code";
+$a->strings["Once you have registered, please connect with me via my profile page at:"] = "Una vez registrado, por favor contacta conmigo a través de mi página de perfil en:";
+$a->strings["For more information about the Friendica project and why we feel it is important, please visit http://friendica.com"] = "Para más información sobre el Proyecto Friendica y sobre por qué pensamos que es algo importante, visita http://friendica.com";
 $a->strings["Unable to locate original post."] = "No se puede encontrar la publicación original.";
 $a->strings["Empty post discarded."] = "Publicación vacía descartada.";
 $a->strings["System error. Post not saved."] = "Error del sistema. Mensaje no guardado.";
@@ -1971,6 +1454,66 @@ $a->strings["This message was sent to you by %s, a member of the Friendica socia
 $a->strings["You may visit them online at %s"] = "Los puedes visitar en línea en %s";
 $a->strings["Please contact the sender by replying to this post if you do not wish to receive these messages."] = "Por favor contacta con el remitente respondiendo a este mensaje si no deseas recibir estos mensajes.";
 $a->strings["%s posted an update."] = "%s ha publicado una actualización.";
+$a->strings["Time Conversion"] = "Conversión horária";
+$a->strings["Friendica provides this service for sharing events with other networks and friends in unknown timezones."] = "Friendica ofrece este servicio para compartir eventos con otros servidores de la red friendica y amigos en zonas de horarios desconocidos.";
+$a->strings["UTC time: %s"] = "Tiempo UTC: %s";
+$a->strings["Current timezone: %s"] = "Zona horaria actual: %s";
+$a->strings["Converted localtime: %s"] = "Zona horaria local convertida: %s";
+$a->strings["Please select your timezone:"] = "Por favor, selecciona tu zona horaria:";
+$a->strings["Remote privacy information not available."] = "Privacidad de la información remota no disponible.";
+$a->strings["Visible to:"] = "Visible para:";
+$a->strings["No valid account found."] = "No se ha encontrado ninguna cuenta válida";
+$a->strings["Password reset request issued. Check your email."] = "Solicitud de restablecimiento de contraseña enviada. Revisa tu correo.";
+$a->strings["\n\t\tDear %1\$s,\n\t\t\tA request was recently received at \"%2\$s\" to reset your account\n\t\tpassword. In order to confirm this request, please select the verification link\n\t\tbelow or paste it into your web browser address bar.\n\n\t\tIf you did NOT request this change, please DO NOT follow the link\n\t\tprovided and ignore and/or delete this email.\n\n\t\tYour password will not be changed unless we can verify that you\n\t\tissued this request."] = "\n\t\tEstimado %1\$s,\n\t\t\tUna consulta llego recientemente a \"%2\$s\" para renovar su\n\t\tcontraseña. Para confirmar esta solicitud por favor seleccione el enlace de verificación mas \n\t\tabajo o copie a pegue el mismo en la barra de dirección de su navegador.\n\n\t\tSi NO ha solicitado este cambio por favor NO SIGA este enlace\n\t\tproporcionado y ignore o borre este mail.\n\n\t\tSu contraseña no sera cambiada hasta que podamos verificar que usted haza\n\t\tsolicitado este cambio..";
+$a->strings["\n\t\tFollow this link to verify your identity:\n\n\t\t%1\$s\n\n\t\tYou will then receive a follow-up message containing the new password.\n\t\tYou may change that password from your account settings page after logging in.\n\n\t\tThe login details are as follows:\n\n\t\tSite Location:\t%2\$s\n\t\tLogin Name:\t%3\$s"] = "\n\t\tSiga este enlace para verificar su identidad:\n\n\t\t%1\$s\n\n\t\tA continuación recibirá un mensaje consecutivo conteniendo la nueva contraseña.\n\t\tPodrá cambiar la contraseña después de haber accedido a la cuenta.\n\n\t\tLos detalles del acceso son las siguientes:\n\n\t\tDirección del sitio:\t%2\$s\n\t\tNombre de la cuenta:\t%3\$s";
+$a->strings["Password reset requested at %s"] = "Contraseña restablecida enviada a %s";
+$a->strings["Request could not be verified. (You may have previously submitted it.) Password reset failed."] = "La solicitud no puede ser verificada (deberías haberla proporcionado antes). Falló el restablecimiento de la contraseña.";
+$a->strings["Your password has been reset as requested."] = "Tu contraseña ha sido restablecida como solicitaste.";
+$a->strings["Your new password is"] = "Tu nueva contraseña es";
+$a->strings["Save or copy your new password - and then"] = "Guarda o copia tu nueva contraseña y luego";
+$a->strings["click here to login"] = "pulsa aquí para acceder";
+$a->strings["Your password may be changed from the <em>Settings</em> page after successful login."] = "Puedes cambiar tu contraseña desde la página de <em>Configuración</em> después de acceder con éxito.";
+$a->strings["\n\t\t\t\tDear %1\$s,\n\t\t\t\t\tYour password has been changed as requested. Please retain this\n\t\t\t\tinformation for your records (or change your password immediately to\n\t\t\t\tsomething that you will remember).\n\t\t\t"] = "\n\t\t\t\tEstimado %1\$s,\n\t\t\t\t\tSu contraseña ha cambiado como solicitado. Por favor guarde esta\n\t\t\t\tinformación para sus documentación (o cambie su contraseña inmediatamente a\n\t\t\t\talgo que pueda recordar).\n\t\t";
+$a->strings["\n\t\t\t\tYour login details are as follows:\n\n\t\t\t\tSite Location:\t%1\$s\n\t\t\t\tLogin Name:\t%2\$s\n\t\t\t\tPassword:\t%3\$s\n\n\t\t\t\tYou may change that password from your account settings page after logging in.\n\t\t\t"] = "\n\t\t\t\tSus datos de acceso son las siguientes:\n\n\t\t\t\tDirección del sitio:\t%1\$s\n\t\t\t\tNombre de cuenta:\t%2\$s\n\t\t\t\tContraseña:\t%3\$s\n\n\t\t\t\tPodrá cambiar esta contraseña después de ingresar al sitio en su pagina de configuración.\n\t\t\t";
+$a->strings["Your password has been changed at %s"] = "Tu contraseña se ha cambiado por %s";
+$a->strings["Forgot your Password?"] = "¿Olvidaste tu contraseña?";
+$a->strings["Enter your email address and submit to have your password reset. Then check your email for further instructions."] = "Introduce tu correo para restablecer tu contraseña. Luego comprueba tu correo para las instrucciones adicionales.";
+$a->strings["Reset"] = "Restablecer";
+$a->strings["System down for maintenance"] = "Servicio suspendido por mantenimiento";
+$a->strings["Manage Identities and/or Pages"] = "Administrar identidades y/o páginas";
+$a->strings["Toggle between different identities or community/group pages which share your account details or which you have been granted \"manage\" permissions"] = "Cambia entre diferentes identidades o páginas de Comunidad/Grupos que comparten los detalles de tu cuenta o sobre los que tienes permisos para administrar";
+$a->strings["Select an identity to manage: "] = "Selecciona una identidad a gestionar:";
+$a->strings["No keywords to match. Please add keywords to your default profile."] = "No hay palabras clave que coincidan. Por favor, agrega algunas palabras claves en tu perfil predeterminado.";
+$a->strings["is interested in:"] = "estás interesado en:";
+$a->strings["Profile Match"] = "Coincidencias de Perfil";
+$a->strings["No recipient selected."] = "Ningún destinatario seleccionado";
+$a->strings["Unable to locate contact information."] = "No se puede encontrar información del contacto.";
+$a->strings["Message could not be sent."] = "El mensaje no ha podido ser enviado.";
+$a->strings["Message collection failure."] = "Fallo en la recolección de mensajes.";
+$a->strings["Message sent."] = "Mensaje enviado.";
+$a->strings["Do you really want to delete this message?"] = "¿Estás seguro de que quieres borrar este mensaje?";
+$a->strings["Message deleted."] = "Mensaje eliminado.";
+$a->strings["Conversation removed."] = "Conversación eliminada.";
+$a->strings["Send Private Message"] = "Enviar mensaje privado";
+$a->strings["To:"] = "Para:";
+$a->strings["Subject:"] = "Asunto:";
+$a->strings["No messages."] = "No hay mensajes.";
+$a->strings["Message not available."] = "Mensaje no disponibile.";
+$a->strings["Delete message"] = "Borrar mensaje";
+$a->strings["Delete conversation"] = "Eliminar conversación";
+$a->strings["No secure communications available. You <strong>may</strong> be able to respond from the sender's profile page."] = "No hay comunicaciones seguras disponibles. <strong>Podrías</strong> responder desde la página de perfil del remitente. ";
+$a->strings["Send Reply"] = "Enviar respuesta";
+$a->strings["Unknown sender - %s"] = "Remitente desconocido - %s";
+$a->strings["You and %s"] = "Tú y %s";
+$a->strings["%s and You"] = "%s y Tú";
+$a->strings["D, d M Y - g:i A"] = "D, d M Y - g:i A";
+$a->strings["%d message"] = array(
+       0 => "%d mensaje",
+       1 => "%d mensajes",
+);
+$a->strings["Mood"] = "Ánimo";
+$a->strings["Set your current mood and tell your friends"] = "Coloca tu ánimo actual y cuéntaselo a tus amigos";
+$a->strings["Remove term"] = "Eliminar término";
 $a->strings["Warning: This group contains %s member from a network that doesn't allow non public messages."] = array(
        0 => "Aviso: Este grupo contiene %s miembro de una red que no permite mensajes públicos.",
        1 => "Aviso: Este grupo contiene %s miembros de una red que no permite mensajes públicos.",
@@ -1989,19 +1532,475 @@ $a->strings["Shared Links"] = "Enlaces compartidos";
 $a->strings["Interesting Links"] = "Enlaces interesantes";
 $a->strings["Starred"] = "Favoritos";
 $a->strings["Favourite Posts"] = "Publicaciones favoritas";
+$a->strings["Welcome to Friendica"] = "Bienvenido a Friendica ";
+$a->strings["New Member Checklist"] = "Listado de nuevos miembros";
+$a->strings["We would like to offer some tips and links to help make your experience enjoyable. Click any item to visit the relevant page. A link to this page will be visible from your home page for two weeks after your initial registration and then will quietly disappear."] = "Nos gustaría ofrecerte algunos consejos y enlaces para ayudar a hacer tu experiencia más amena. Pulsa en cualquier elemento para visitar la página correspondiente. Un enlace a esta página será visible desde tu página de inicio durante las dos semanas siguientes a tu inscripción y luego desaparecerá.";
+$a->strings["Getting Started"] = "Empezando";
+$a->strings["Friendica Walk-Through"] = "Visita guiada a Friendica";
+$a->strings["On your <em>Quick Start</em> page - find a brief introduction to your profile and network tabs, make some new connections, and find some groups to join."] = "En tu página de <em>Inicio Rápido</em> - busca una introducción breve para tus pestañas de perfil y red, haz algunas conexiones nuevas, y busca algunos grupos a los que unirte.";
+$a->strings["Go to Your Settings"] = "Ir a tus ajustes";
+$a->strings["On your <em>Settings</em> page -  change your initial password. Also make a note of your Identity Address. This looks just like an email address - and will be useful in making friends on the free social web."] = "En la página de <em>Configuración</em> puedes cambiar tu contraseña inicial. También aparece tu ID (Identity Address). Es parecida a una dirección de correo y te servirá para conectar con gente de redes sociales libres.";
+$a->strings["Review the other settings, particularly the privacy settings. An unpublished directory listing is like having an unlisted phone number. In general, you should probably publish your listing - unless all of your friends and potential friends know exactly how to find you."] = "Revisa las otras configuraciones, especialmente la configuración de privacidad. Un listado de directorio sin publicar es como tener un número de teléfono sin publicar. Normalmente querrás publicar tu listado, a menos que tus amigos y amigos potenciales sepan cómo ponerse en contacto contigo.";
+$a->strings["Upload Profile Photo"] = "Subir foto del Perfil";
+$a->strings["Upload a profile photo if you have not done so already. Studies have shown that people with real photos of themselves are ten times more likely to make friends than people who do not."] = "Sube una foto para tu perfil si no lo has hecho aún. Los estudios han demostrado que la gente que usa fotos suyas reales tienen diez veces más éxito a la hora de entablar amistad que las que no.";
+$a->strings["Edit Your Profile"] = "Editar tu perfil";
+$a->strings["Edit your <strong>default</strong> profile to your liking. Review the settings for hiding your list of friends and hiding the profile from unknown visitors."] = "Edita tu perfil <strong>predeterminado</strong> como quieras. Revisa la configuración para ocultar tu lista de amigos o tu perfil a los visitantes desconocidos.";
+$a->strings["Profile Keywords"] = "Palabras clave del perfil";
+$a->strings["Set some public keywords for your default profile which describe your interests. We may be able to find other people with similar interests and suggest friendships."] = "Define en tu perfil público algunas palabras que describan tus intereses. Así podremos buscar otras personas con los mismos gustos y sugerirte posibles amigos.";
+$a->strings["Connecting"] = "Conectando";
+$a->strings["Importing Emails"] = "Importando correos electrónicos";
+$a->strings["Enter your email access information on your Connector Settings page if you wish to import and interact with friends or mailing lists from your email INBOX"] = "Introduce la información para acceder a tu correo en la página de Configuración del conector si quieres importar e interactuar con amigos o listas de correos del buzón de entrada de tu correo electrónico.";
+$a->strings["Go to Your Contacts Page"] = "Ir a tu página de contactos";
+$a->strings["Your Contacts page is your gateway to managing friendships and connecting with friends on other networks. Typically you enter their address or site URL in the <em>Add New Contact</em> dialog."] = "Tu página de Contactos es el portal desde donde podrás manejar tus amistades y conectarte con amigos de otras redes. Normalmente introduces su dirección o la dirección de su sitio web en el recuadro \"Añadir contacto nuevo\".";
+$a->strings["Go to Your Site's Directory"] = "Ir al directorio de tu sitio";
+$a->strings["The Directory page lets you find other people in this network or other federated sites. Look for a <em>Connect</em> or <em>Follow</em> link on their profile page. Provide your own Identity Address if requested."] = "El Directorio te permite encontrar otras personas en esta red o en cualquier otro sitio federado. Busca algún enlace de <em>Conectar</em> o <em>Seguir</em> en su perfil. Proporciona tu direción personal si es necesario.";
+$a->strings["Finding New People"] = "Encontrando nueva gente";
+$a->strings["On the side panel of the Contacts page are several tools to find new friends. We can match people by interest, look up people by name or interest, and provide suggestions based on network relationships. On a brand new site, friend suggestions will usually begin to be populated within 24 hours."] = "En el panel lateral de la página de Contactos existen varias herramientas para encontrar nuevos amigos. Podemos filtrar personas por sus intereses, buscar personas por nombre o por sus intereses, y ofrecerte sugerencias basadas en sus relaciones de la red. En un sitio nuevo, las sugerencias de amigos por lo general comienzan pasadas las 24 horas.";
+$a->strings["Group Your Contacts"] = "Agrupa tus contactos";
+$a->strings["Once you have made some friends, organize them into private conversation groups from the sidebar of your Contacts page and then you can interact with each group privately on your Network page."] = "Una vez que tengas algunos amigos, puedes organizarlos en grupos privados de conversación mediante el memnú en tu página de Contactos y luego puedes interactuar con cada grupo por separado desde tu página de Red.";
+$a->strings["Why Aren't My Posts Public?"] = "¿Por qué mis publicaciones no son públicas?";
+$a->strings["Friendica respects your privacy. By default, your posts will only show up to people you've added as friends. For more information, see the help section from the link above."] = "Friendica respeta tu privacidad. Por defecto, tus publicaciones solo se mostrarán a personas que hayas añadido como amistades. Para más información, mira la sección de ayuda en el enlace de más arriba.";
+$a->strings["Getting Help"] = "Consiguiendo ayuda";
+$a->strings["Go to the Help Section"] = "Ir a la sección de ayuda";
+$a->strings["Our <strong>help</strong> pages may be consulted for detail on other program features and resources."] = "Puedes consultar nuestra página de <strong>Ayuda</strong> para más información y recursos de ayuda.";
+$a->strings["Contacts who are not members of a group"] = "Contactos sin grupo";
+$a->strings["Invalid request identifier."] = "Solicitud de identificación no válida.";
+$a->strings["Discard"] = "Descartar";
+$a->strings["Network Notifications"] = "Notificaciones de Red";
+$a->strings["System Notifications"] = "Notificaciones del sistema";
+$a->strings["Personal Notifications"] = "Notificaciones personales";
+$a->strings["Home Notifications"] = "Notificaciones de Inicio";
+$a->strings["Show Ignored Requests"] = "Mostrar peticiones ignoradas";
+$a->strings["Hide Ignored Requests"] = "Ocultar peticiones ignoradas";
+$a->strings["Notification type: "] = "Tipo de notificación: ";
+$a->strings["suggested by %s"] = "sugerido por %s";
+$a->strings["Post a new friend activity"] = "Publica tu nueva amistad";
+$a->strings["if applicable"] = "Si corresponde";
+$a->strings["Claims to be known to you: "] = "Dice conocerte: ";
+$a->strings["yes"] = "sí";
+$a->strings["no"] = "no";
+$a->strings["Shall your connection be bidirectional or not?"] = "¿Su conexión debe ser bidireccional o no?";
+$a->strings["Accepting %s as a friend allows %s to subscribe to your posts, and you will also receive updates from them in your news feed."] = "Aceptar a %s como amigo le permite a %s suscribirse a sus publicaciones, y usted también recibirá actualizaciones de ellos en sus noticias.";
+$a->strings["Accepting %s as a subscriber allows them to subscribe to your posts, but you will not receive updates from them in your news feed."] = "Aceptar a %s como suscriptor les permite suscribirse a sus publicaciones, pero usted no recibirá actualizaciones de ellos en sus noticias.";
+$a->strings["Accepting %s as a sharer allows them to subscribe to your posts, but you will not receive updates from them in your news feed."] = "Aceptar a %s como participante les permite suscribirse a sus publicaciones, pero usted no recibirá actualizaciones de ellos en sus noticias.";
+$a->strings["Friend"] = "Amigo";
+$a->strings["Sharer"] = "Lector";
+$a->strings["Subscriber"] = "Suscriptor";
+$a->strings["No introductions."] = "Sin presentaciones.";
+$a->strings["Show unread"] = "Mostrar no leído";
+$a->strings["Show all"] = "Mostrar todo";
+$a->strings["No more %s notifications."] = "No más notificaciones de %s.";
+$a->strings["No more system notifications."] = "No hay más notificaciones del sistema.";
+$a->strings["Post successful."] = "¡Publicado!";
+$a->strings["OpenID protocol error. No ID returned."] = "Error de protocolo OpenID. ID no devuelta.";
+$a->strings["Account not found and OpenID registration is not permitted on this site."] = "Cuenta no encontrada y el registro OpenID no está permitido en ese sitio.";
+$a->strings["Subscribing to OStatus contacts"] = "Subscribir a los contactos de OStatus";
+$a->strings["No contact provided."] = "Sin suministro de datos de contacto.";
+$a->strings["Couldn't fetch information for contact."] = "No se ha podido conseguir la información del contacto.";
+$a->strings["Couldn't fetch friends for contact."] = "No se ha podido conseguir datos de amigos para contactar.";
+$a->strings["Done"] = "hecho!";
+$a->strings["success"] = "exito!";
+$a->strings["failed"] = "fallido!";
+$a->strings["Keep this window open until done."] = "Mantén esta ventana abierta hasta que el proceso ha terminado.";
+$a->strings["Not Extended"] = "No extendido";
+$a->strings["Recent Photos"] = "Fotos recientes";
+$a->strings["Upload New Photos"] = "Subir nuevas fotos";
+$a->strings["everybody"] = "todos";
+$a->strings["Contact information unavailable"] = "Información del contacto no disponible";
+$a->strings["Album not found."] = "Álbum no encontrado.";
+$a->strings["Delete Album"] = "Eliminar álbum";
+$a->strings["Do you really want to delete this photo album and all its photos?"] = "¿Estás seguro de quieres borrar este álbum y todas sus fotos?";
+$a->strings["Delete Photo"] = "Eliminar foto";
+$a->strings["Do you really want to delete this photo?"] = "¿Estás seguro de que quieres borrar esta foto?";
+$a->strings["%1\$s was tagged in %2\$s by %3\$s"] = "%1\$s fue etiquetado en %2\$s por %3\$s";
+$a->strings["a photo"] = "una foto";
+$a->strings["Image exceeds size limit of %s"] = "La imagen excede el limite de %s";
+$a->strings["Image file is empty."] = "El archivo de imagen está vacío.";
+$a->strings["Unable to process image."] = "Imposible procesar la imagen.";
+$a->strings["Image upload failed."] = "Error al subir la imagen.";
+$a->strings["No photos selected"] = "Ninguna foto seleccionada";
+$a->strings["Access to this item is restricted."] = "El acceso a este elemento está restringido.";
+$a->strings["You have used %1$.2f Mbytes of %2$.2f Mbytes photo storage."] = "Has usado %1$.2f MB de %2$.2f MB de tu álbum de fotos.";
+$a->strings["Upload Photos"] = "Subir fotos";
+$a->strings["New album name: "] = "Nombre del nuevo álbum: ";
+$a->strings["or existing album name: "] = "o nombre de un álbum existente: ";
+$a->strings["Do not show a status post for this upload"] = "No actualizar tu estado con este envío";
+$a->strings["Show to Groups"] = "Mostrar a los Grupos";
+$a->strings["Show to Contacts"] = "Mostrar a los Contactos";
+$a->strings["Private Photo"] = "Foto Privada";
+$a->strings["Public Photo"] = "Foto Pública";
+$a->strings["Edit Album"] = "Modificar álbum";
+$a->strings["Show Newest First"] = "Mostrar más nuevos primero";
+$a->strings["Show Oldest First"] = "Mostrar más antiguos primero";
+$a->strings["View Photo"] = "Ver foto";
+$a->strings["Permission denied. Access to this item may be restricted."] = "Permiso denegado. El acceso a este elemento puede estar restringido.";
+$a->strings["Photo not available"] = "Foto no disponible";
+$a->strings["View photo"] = "Ver foto";
+$a->strings["Edit photo"] = "Modificar foto";
+$a->strings["Use as profile photo"] = "Usar como foto del perfil";
+$a->strings["View Full Size"] = "Ver a tamaño completo";
+$a->strings["Tags: "] = "Etiquetas: ";
+$a->strings["[Remove any tag]"] = "[Borrar todas las etiquetas]";
+$a->strings["New album name"] = "Nuevo nombre del álbum";
+$a->strings["Caption"] = "Título";
+$a->strings["Add a Tag"] = "Añadir una etiqueta";
+$a->strings["Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping"] = "Ejemplo: @juan, @Barbara_Ruiz, @julia@example.com, #California, #camping";
+$a->strings["Do not rotate"] = "No rotar";
+$a->strings["Rotate CW (right)"] = "Girar a la derecha";
+$a->strings["Rotate CCW (left)"] = "Girar a la izquierda";
+$a->strings["Private photo"] = "Foto privada";
+$a->strings["Public photo"] = "Foto pública";
+$a->strings["Map"] = "Mapa";
+$a->strings["View Album"] = "Ver Álbum";
 $a->strings["{0} wants to be your friend"] = "{0} quiere ser tu amigo";
 $a->strings["{0} sent you a message"] = "{0} te ha enviado un mensaje";
 $a->strings["{0} requested registration"] = "{0} solicitudes de registro";
+$a->strings["Poke/Prod"] = "Toque/Empujón";
+$a->strings["poke, prod or do other things to somebody"] = "da un toque, empujón o similar a alguien";
+$a->strings["Recipient"] = "Receptor";
+$a->strings["Choose what you wish to do to recipient"] = "Elige qué desea hacer con el receptor";
+$a->strings["Make this post private"] = "Hacer esta publicación privada";
+$a->strings["Tips for New Members"] = "Consejos para nuevos miembros";
+$a->strings["Image uploaded but image cropping failed."] = "Imagen recibida, pero ha fallado al recortarla.";
+$a->strings["Image size reduction [%s] failed."] = "Ha fallado la reducción de las dimensiones de la imagen [%s].";
+$a->strings["Shift-reload the page or clear browser cache if the new photo does not display immediately."] = "Recarga la página o limpia la caché del navegador si la foto nueva no aparece inmediatamente.";
+$a->strings["Unable to process image"] = "Imposible procesar la imagen";
+$a->strings["Upload File:"] = "Subir archivo:";
+$a->strings["Select a profile:"] = "Elige un perfil:";
+$a->strings["Upload"] = "Subir";
+$a->strings["or"] = "o";
+$a->strings["skip this step"] = "saltar este paso";
+$a->strings["select a photo from your photo albums"] = "elige una foto de tus álbumes";
+$a->strings["Crop Image"] = "Recortar imagen";
+$a->strings["Please adjust the image cropping for optimum viewing."] = "Por favor, ajusta el recorte de la imagen para optimizarla.";
+$a->strings["Done Editing"] = "Editado";
+$a->strings["Image uploaded successfully."] = "Imagen subida con éxito.";
+$a->strings["Profile deleted."] = "Perfil eliminado.";
+$a->strings["Profile-"] = "Perfil-";
+$a->strings["New profile created."] = "Nuevo perfil creado.";
+$a->strings["Profile unavailable to clone."] = "Imposible duplicar el perfil.";
+$a->strings["Profile Name is required."] = "Se necesita un nombre de perfil.";
+$a->strings["Marital Status"] = "Estado civil";
+$a->strings["Romantic Partner"] = "Pareja sentimental";
+$a->strings["Work/Employment"] = "Trabajo/estudios";
+$a->strings["Religion"] = "Religión";
+$a->strings["Political Views"] = "Preferencias políticas";
+$a->strings["Gender"] = "Género";
+$a->strings["Sexual Preference"] = "Orientación sexual";
+$a->strings["XMPP"] = "XMPP";
+$a->strings["Homepage"] = "Página de inicio";
+$a->strings["Interests"] = "Intereses";
+$a->strings["Address"] = "Dirección";
+$a->strings["Location"] = "Ubicación";
+$a->strings["Profile updated."] = "Perfil actualizado.";
+$a->strings[" and "] = " y ";
+$a->strings["public profile"] = "perfil público";
+$a->strings["%1\$s changed %2\$s to &ldquo;%3\$s&rdquo;"] = "%1\$s cambió su %2\$s a &ldquo;%3\$s&rdquo;";
+$a->strings[" - Visit %1\$s's %2\$s"] = " - Visita %1\$s's %2\$s";
+$a->strings["%1\$s has an updated %2\$s, changing %3\$s."] = "%1\$s tiene una actualización %2\$s, cambiando %3\$s.";
+$a->strings["Hide contacts and friends:"] = "Ocultar contactos y amigos";
+$a->strings["Hide your contact/friend list from viewers of this profile?"] = "¿Ocultar tu lista de contactos/amigos en este perfil?";
+$a->strings["Show more profile fields:"] = "Mostrar mas campos del perfil:";
+$a->strings["Profile Actions"] = "Acciones de perfil";
+$a->strings["Edit Profile Details"] = "Editar detalles de tu perfil";
+$a->strings["Change Profile Photo"] = "Cambiar imagen del Perfil";
+$a->strings["View this profile"] = "Ver este perfil";
+$a->strings["Create a new profile using these settings"] = "¿Crear un nuevo perfil con esta configuración?";
+$a->strings["Clone this profile"] = "Clonar este perfil";
+$a->strings["Delete this profile"] = "Eliminar este perfil";
+$a->strings["Basic information"] = "Información básica";
+$a->strings["Profile picture"] = "Imagen del perfil";
+$a->strings["Preferences"] = "Preferencias";
+$a->strings["Status information"] = "Información del estatus";
+$a->strings["Additional information"] = "Información addicional";
+$a->strings["Relation"] = "Relación";
+$a->strings["Your Gender:"] = "Género:";
+$a->strings["<span class=\"heart\">&hearts;</span> Marital Status:"] = "<span class=\"heart\"&hearts;</span> Estado civil:";
+$a->strings["Example: fishing photography software"] = "Ejemplo: pesca fotografía software";
+$a->strings["Profile Name:"] = "Nombres del perfil:";
+$a->strings["This is your <strong>public</strong> profile.<br />It <strong>may</strong> be visible to anybody using the internet."] = "Éste es tu perfil <strong>público</strong>.<br /><strong>Puede</strong> ser visto por cualquier usuario de internet.";
+$a->strings["Your Full Name:"] = "Tu nombre completo:";
+$a->strings["Title/Description:"] = "Título/Descrición:";
+$a->strings["Street Address:"] = "Dirección";
+$a->strings["Locality/City:"] = "Localidad/Ciudad:";
+$a->strings["Region/State:"] = "Región/Estado:";
+$a->strings["Postal/Zip Code:"] = "Código postal:";
+$a->strings["Country:"] = "País";
+$a->strings["Who: (if applicable)"] = "¿Quién? (si es aplicable)";
+$a->strings["Examples: cathy123, Cathy Williams, cathy@example.com"] = "Ejemplos: cathy123, Cathy Williams, cathy@example.com";
+$a->strings["Since [date]:"] = "Desde [fecha]:";
+$a->strings["Tell us about yourself..."] = "Háblanos sobre ti...";
+$a->strings["XMPP (Jabber) address:"] = "Dirección XMPP (Jabber):";
+$a->strings["The XMPP address will be propagated to your contacts so that they can follow you."] = "La dirección XMPP será propagada entre sus contactos para que puedan seguirle.";
+$a->strings["Homepage URL:"] = "Dirección de tu página:";
+$a->strings["Religious Views:"] = "Creencias religiosas:";
+$a->strings["Public Keywords:"] = "Palabras clave públicas:";
+$a->strings["(Used for suggesting potential friends, can be seen by others)"] = "(Utilizadas para sugerir amigos potenciales, otros pueden verlo)";
+$a->strings["Private Keywords:"] = "Palabras clave privadas:";
+$a->strings["(Used for searching profiles, never shown to others)"] = "(Utilizadas para buscar perfiles, nunca se muestra a otros)";
+$a->strings["Musical interests"] = "Gustos musicales";
+$a->strings["Books, literature"] = "Libros, literatura";
+$a->strings["Television"] = "Televisión";
+$a->strings["Film/dance/culture/entertainment"] = "Películas/baile/cultura/entretenimiento";
+$a->strings["Hobbies/Interests"] = "Aficiones/Intereses";
+$a->strings["Love/romance"] = "Amor/Romance";
+$a->strings["Work/employment"] = "Trabajo/ocupación";
+$a->strings["School/education"] = "Escuela/estudios";
+$a->strings["Contact information and Social Networks"] = "Informacioń de contacto y Redes sociales";
+$a->strings["Edit/Manage Profiles"] = "Editar/Administrar perfiles";
+$a->strings["Invalid profile identifier."] = "Identificador de perfil no válido.";
+$a->strings["Profile Visibility Editor"] = "Editor de visibilidad del perfil";
+$a->strings["Visible To"] = "Visible para";
+$a->strings["All Contacts (with secure profile access)"] = "Todos los contactos (con perfil de acceso seguro)";
+$a->strings["Registration successful. Please check your email for further instructions."] = "Te has registrado con éxito. Por favor, consulta tu correo para más información.";
+$a->strings["Failed to send email message. Here your accout details:<br> login: %s<br> password: %s<br><br>You can change your password after login."] = "Error al intentar de enviar mensaje de correo. Aquí los detalles de su cuenta: <br> login: %s<br> contraseña: %s<br><br>Puede cambiar su contraseña después de ingresar al sitio.";
+$a->strings["Registration successful."] = "Registro exitoso.";
+$a->strings["Your registration can not be processed."] = "Tu registro no se puede procesar.";
+$a->strings["Your registration is pending approval by the site owner."] = "Tu registro está pendiente de aprobación por el propietario del sitio.";
+$a->strings["This site has exceeded the number of allowed daily account registrations. Please try again tomorrow."] = "Este sitio ha excedido el número de registros diarios permitidos. Inténtalo de nuevo mañana por favor.";
+$a->strings["You may (optionally) fill in this form via OpenID by supplying your OpenID and clicking 'Register'."] = "Puedes (opcionalmente) rellenar este formulario a través de OpenID escribiendo tu OpenID y pulsando en \"Registrar\".";
+$a->strings["If you are not familiar with OpenID, please leave that field blank and fill in the rest of the items."] = "Si no estás familiarizado con OpenID, por favor deja ese campo en blanco y rellena el resto de los elementos.";
+$a->strings["Your OpenID (optional): "] = "Tu OpenID (opcional):";
+$a->strings["Include your profile in member directory?"] = "¿Incluir tu perfil en el directorio de miembros?";
+$a->strings["Note for the admin"] = "Nota para el administrador";
+$a->strings["Leave a message for the admin, why you want to join this node"] = "Deje un mensaje para el administrador sobre por qué quiere unirse a este nodo";
+$a->strings["Membership on this site is by invitation only."] = "Sitio solo accesible mediante invitación.";
+$a->strings["Your invitation ID: "] = "ID de tu invitación: ";
+$a->strings["Your Full Name (e.g. Joe Smith, real or real-looking): "] = "Nombre completo (ej. Joe Smith, real o real aparente):";
+$a->strings["Your Email Address: "] = "Tu dirección de correo: ";
+$a->strings["New Password:"] = "Contraseña nueva:";
+$a->strings["Leave empty for an auto generated password."] = "Dejar vacío para autogenerar una contraseña";
+$a->strings["Confirm:"] = "Confirmar:";
+$a->strings["Choose a profile nickname. This must begin with a text character. Your profile address on this site will then be '<strong>nickname@\$sitename</strong>'."] = "Elije un apodo. Debe comenzar con una letra. Tu dirección de perfil en este sitio va a ser \"<strong>apodo@\$nombredelsitio</strong>\".";
+$a->strings["Choose a nickname: "] = "Escoge un apodo: ";
+$a->strings["Import"] = "Importar";
+$a->strings["Import your profile to this friendica instance"] = "Importar tu perfil a esta instancia de friendica";
+$a->strings["Account approved."] = "Cuenta aprobada.";
+$a->strings["Registration revoked for %s"] = "Registro anulado para %s";
+$a->strings["Please login."] = "Por favor accede.";
+$a->strings["Remove My Account"] = "Eliminar mi cuenta";
+$a->strings["This will completely remove your account. Once this has been done it is not recoverable."] = "Esto eliminará por completo tu cuenta. Una vez hecho no se puede deshacer.";
+$a->strings["Please enter your password for verification:"] = "Por favor, introduce tu contraseña para la verificación:";
+$a->strings["Resubscribing to OStatus contacts"] = "Resubscribir a contactos de OStatus";
+$a->strings["Error"] = "error";
+$a->strings["Only logged in users are permitted to perform a search."] = "Solo usuarios activos tienen permiso para ejecutar búsquedas.";
+$a->strings["Too Many Requests"] = "Demasiadas consultas";
+$a->strings["Only one search per minute is permitted for not logged in users."] = "Se permite solo una búsqueda por minuto para usuarios no identificados.";
+$a->strings["Items tagged with: %s"] = "Objetos taggeado con: %s";
+$a->strings["Display"] = "Interfaz del usuario";
+$a->strings["Social Networks"] = "Redes sociales";
+$a->strings["Connected apps"] = "Aplicaciones conectadas";
+$a->strings["Export personal data"] = "Exportación de datos personales";
+$a->strings["Remove account"] = "Eliminar cuenta";
+$a->strings["Missing some important data!"] = "¡Faltan algunos datos importantes!";
+$a->strings["Failed to connect with email account using the settings provided."] = "Error al conectar con la cuenta de correo mediante la configuración suministrada.";
+$a->strings["Email settings updated."] = "Configuración de correo actualizada.";
+$a->strings["Features updated"] = "Actualizaciones";
+$a->strings["Relocate message has been send to your contacts"] = "Mensaje de reubicación ha sido enviado a sus contactos.";
+$a->strings["Empty passwords are not allowed. Password unchanged."] = "No se permiten contraseñas vacías. La contraseña no ha sido modificada.";
+$a->strings["Wrong password."] = "Contraseña incorrecta";
+$a->strings["Password changed."] = "Contraseña modificada.";
+$a->strings["Password update failed. Please try again."] = "La actualización de la contraseña ha fallado. Por favor, prueba otra vez.";
+$a->strings[" Please use a shorter name."] = " Usa un nombre más corto.";
+$a->strings[" Name too short."] = " Nombre demasiado corto.";
+$a->strings["Wrong Password"] = "Contraseña incorrecta";
+$a->strings[" Not valid email."] = " Correo no válido.";
+$a->strings[" Cannot change to that email."] = " No se puede usar ese correo.";
+$a->strings["Private forum has no privacy permissions. Using default privacy group."] = "El foro privado no tiene permisos de privacidad. Usando el grupo de privacidad por defecto.";
+$a->strings["Private forum has no privacy permissions and no default privacy group."] = "El foro privado no tiene permisos de privacidad ni grupo por defecto de privacidad.";
+$a->strings["Settings updated."] = "Configuración actualizada.";
+$a->strings["Add application"] = "Agregar aplicación";
+$a->strings["Consumer Key"] = "Clave del consumidor";
+$a->strings["Consumer Secret"] = "Secreto del consumidor";
+$a->strings["Redirect"] = "Redirigir";
+$a->strings["Icon url"] = "Dirección del ícono";
+$a->strings["You can't edit this application."] = "No puedes editar esta aplicación.";
+$a->strings["Connected Apps"] = "Aplicaciones conectadas";
+$a->strings["Client key starts with"] = "Clave de cliente comienza por";
+$a->strings["No name"] = "Sin nombre";
+$a->strings["Remove authorization"] = "Suprimir la autorización";
+$a->strings["No Plugin settings configured"] = "No se ha configurado ningún módulo";
+$a->strings["Plugin Settings"] = "Configuración de los módulos";
+$a->strings["Additional Features"] = "Características adicionales";
+$a->strings["General Social Media Settings"] = "Configuración general de social media ";
+$a->strings["Disable intelligent shortening"] = "Deshabilitar recorte inteligente de URL";
+$a->strings["Normally the system tries to find the best link to add to shortened posts. If this option is enabled then every shortened post will always point to the original friendica post."] = "Normalemente el sistema intenta de encontrara el mejor enlace para agregar a envíos recortados (twitter, OStatus). Si esta opción se encuentra habilitado, todo envío recortado apuntara siempre al tema original en friendica.";
+$a->strings["Automatically follow any GNU Social (OStatus) followers/mentioners"] = "Automáticamente seguir cualquier GNUsocial (OStatus) seguidores o menciones ";
+$a->strings["If you receive a message from an unknown OStatus user, this option decides what to do. If it is checked, a new contact will be created for every unknown user."] = "Cuando se recibe un mensaje de un perfil desconocido de OStatus, esta opción define que hacer.\nSi es habilitado, un nuevo contacto sera creado para cada usuario.";
+$a->strings["Default group for OStatus contacts"] = "Grupo por defecto para contactos OStatus";
+$a->strings["Your legacy GNU Social account"] = "Tu cuenta GNU social conectada";
+$a->strings["If you enter your old GNU Social/Statusnet account name here (in the format user@domain.tld), your contacts will be added automatically. The field will be emptied when done."] = "Si agrega su viejo nombre de perfil  GNUsocial/Statusnet aqui (en el formato de usuario@dominio.tld), sus contactos serán añadidos automáticamente.\nEl campo sera vaciado cuando termine el proceso. ";
+$a->strings["Repair OStatus subscriptions"] = "Reparar subscripciones de OStatus";
+$a->strings["Built-in support for %s connectivity is %s"] = "El soporte integrado de conexión con %s está %s";
+$a->strings["enabled"] = "habilitado";
+$a->strings["disabled"] = "deshabilitado";
+$a->strings["GNU Social (OStatus)"] = "GNUsocial (OStatus)";
+$a->strings["Email access is disabled on this site."] = "El acceso por correo está deshabilitado en esta web.";
+$a->strings["Email/Mailbox Setup"] = "Configuración del correo/buzón";
+$a->strings["If you wish to communicate with email contacts using this service (optional), please specify how to connect to your mailbox."] = "Si quieres comunicarte con tus contactos de correo usando este servicio (opcional), por favor, especifica cómo conectar con tu buzón.";
+$a->strings["Last successful email check:"] = "Última comprobación del correo con éxito:";
+$a->strings["IMAP server name:"] = "Nombre del servidor IMAP:";
+$a->strings["IMAP port:"] = "Puerto IMAP:";
+$a->strings["Security:"] = "Seguridad:";
+$a->strings["None"] = "Ninguna";
+$a->strings["Email login name:"] = "Nombre de usuario:";
+$a->strings["Email password:"] = "Contraseña:";
+$a->strings["Reply-to address:"] = "Dirección de respuesta:";
+$a->strings["Send public posts to all email contacts:"] = "Enviar publicaciones públicas a todos los contactos de correo:";
+$a->strings["Action after import:"] = "Acción después de importar:";
+$a->strings["Move to folder"] = "Mover a un directorio";
+$a->strings["Move to folder:"] = "Mover al directorio:";
+$a->strings["Display Settings"] = "Configuración Tema/Visualización";
+$a->strings["Display Theme:"] = "Utilizar tema:";
+$a->strings["Mobile Theme:"] = "Tema móvil:";
+$a->strings["Suppress warning of insecure networks"] = "Suprimir el aviso de redes inseguras";
+$a->strings["Should the system suppress the warning that the current group contains members of networks that can't receive non public postings."] = "Debería el sistema suprimir el aviso de que el grupo actual contiene miembros de redes que no pueden recibir publicaciones públicas.";
+$a->strings["Update browser every xx seconds"] = "Actualizar navegador cada xx segundos";
+$a->strings["Minimum of 10 seconds. Enter -1 to disable it."] = "Minimo 10 segundos. Ingrese -1 para deshabilitar.";
+$a->strings["Number of items to display per page:"] = "Número de elementos a mostrar por página:";
+$a->strings["Maximum of 100 items"] = "Máximo 100 elementos";
+$a->strings["Number of items to display per page when viewed from mobile device:"] = "Cantidad de objetos a visualizar cuando se usa un movil";
+$a->strings["Don't show emoticons"] = "No mostrar emoticones";
+$a->strings["Calendar"] = "Calendario";
+$a->strings["Beginning of week:"] = "Principio de la semana:";
+$a->strings["Don't show notices"] = "No mostrara avisos";
+$a->strings["Infinite scroll"] = "pagina infinita (sroll)";
+$a->strings["Automatic updates only at the top of the network page"] = "Actualizaciones automaticas solo estando al principio de la pagina";
+$a->strings["Bandwith Saver Mode"] = "Modo de guardado de ancho de banda";
+$a->strings["When enabled, embedded content is not displayed on automatic updates, they only show on page reload."] = "Cuando está habilitado, el contenido incrustado no se muestra en las actualizaciones automáticas, sólo en las páginas recargadas.";
+$a->strings["General Theme Settings"] = "Ajustes generales de tema";
+$a->strings["Custom Theme Settings"] = "Ajustes personalizados de tema";
+$a->strings["Content Settings"] = "Ajustes de contenido";
+$a->strings["Theme settings"] = "Configuración del Tema";
+$a->strings["Account Types"] = "Tipos de cuenta";
+$a->strings["Personal Page Subtypes"] = "Subtipos de página personal";
+$a->strings["Community Forum Subtypes"] = "Subtipos de foro de comunidad";
+$a->strings["Personal Page"] = "Página personal";
+$a->strings["This account is a regular personal profile"] = "Esta cuenta es un perfil personal corriente";
+$a->strings["Organisation Page"] = "Página de organización";
+$a->strings["This account is a profile for an organisation"] = "Esta cuenta es un perfil de una organización";
+$a->strings["News Page"] = "Página de noticias";
+$a->strings["This account is a news account/reflector"] = "Esta cuenta es una cuenta de noticias/reflectora";
+$a->strings["Community Forum"] = "Foro de la comunidad";
+$a->strings["This account is a community forum where people can discuss with each other"] = "Esta cuenta es un foro de comunidad donde la gente puede debatir con otros";
+$a->strings["Normal Account Page"] = "Página de cuenta normal";
+$a->strings["This account is a normal personal profile"] = "Esta cuenta es el perfil personal normal";
+$a->strings["Soapbox Page"] = "Página de tribuna";
+$a->strings["Automatically approve all connection/friend requests as read-only fans"] = "Acepta automáticamente todas las peticiones de conexión/amistad como seguidores de solo-lectura";
+$a->strings["Public Forum"] = "Foro público";
+$a->strings["Automatically approve all contact requests"] = "Aprovar autimáticamente todas las solicitudes de contacto";
+$a->strings["Automatic Friend Page"] = "Página de Amistad autómatica";
+$a->strings["Automatically approve all connection/friend requests as friends"] = "Aceptar automáticamente todas las solicitudes de conexión/amistad como amigos";
+$a->strings["Private Forum [Experimental]"] = "Foro privado [Experimental]";
+$a->strings["Private forum - approved members only"] = "Foro privado - solo miembros";
+$a->strings["OpenID:"] = "OpenID:";
+$a->strings["(Optional) Allow this OpenID to login to this account."] = "(Opcional) Permitir a este OpenID acceder a esta cuenta.";
+$a->strings["Publish your default profile in your local site directory?"] = "¿Quieres publicar tu perfil predeterminado en el directorio local del sitio?";
+$a->strings["Publish your default profile in the global social directory?"] = "¿Quieres publicar tu perfil predeterminado en el directorio social de forma global?";
+$a->strings["Hide your contact/friend list from viewers of your default profile?"] = "¿Quieres ocultar tu lista de contactos/amigos en la vista de tu perfil predeterminado?";
+$a->strings["If enabled, posting public messages to Diaspora and other networks isn't possible."] = "Si habilitado, enviar temas públicos a  a Diaspora* y otras redes no es posible. ";
+$a->strings["Allow friends to post to your profile page?"] = "¿Permites que tus amigos publiquen en tu página de perfil?";
+$a->strings["Allow friends to tag your posts?"] = "¿Permites a los amigos etiquetar tus publicaciones?";
+$a->strings["Allow us to suggest you as a potential friend to new members?"] = "¿Nos permite recomendarte como amigo potencial a los nuevos miembros?";
+$a->strings["Permit unknown people to send you private mail?"] = "¿Permites que desconocidos te manden correos privados?";
+$a->strings["Profile is <strong>not published</strong>."] = "El perfil <strong>no está publicado</strong>.";
+$a->strings["Your Identity Address is <strong>'%s'</strong> or '%s'."] = "Su dirección de identidad es <strong>'%s'</strong> o '%s'.";
+$a->strings["Automatically expire posts after this many days:"] = "Las publicaciones expirarán automáticamente después de estos días:";
+$a->strings["If empty, posts will not expire. Expired posts will be deleted"] = "Si lo dejas vacío no expirarán nunca. Las publicaciones que hayan expirado se borrarán";
+$a->strings["Advanced expiration settings"] = "Configuración avanzada de expiración";
+$a->strings["Advanced Expiration"] = "Expiración avanzada";
+$a->strings["Expire posts:"] = "¿Expiran las publicaciones?";
+$a->strings["Expire personal notes:"] = "¿Expiran las notas personales?";
+$a->strings["Expire starred posts:"] = "¿Expiran los favoritos?";
+$a->strings["Expire photos:"] = "¿Expiran las fotografías?";
+$a->strings["Only expire posts by others:"] = "Solo expiran los mensajes de los demás:";
+$a->strings["Account Settings"] = "Configuración de la cuenta";
+$a->strings["Password Settings"] = "Configuración de la contraseña";
+$a->strings["Leave password fields blank unless changing"] = "Deja la contraseña en blanco si no quieres cambiarla";
+$a->strings["Current Password:"] = "Contraseña actual:";
+$a->strings["Your current password to confirm the changes"] = "Su contraseña actual para confirmar los cambios.";
+$a->strings["Password:"] = "Contraseña:";
+$a->strings["Basic Settings"] = "Configuración básica";
+$a->strings["Email Address:"] = "Dirección de correo:";
+$a->strings["Your Timezone:"] = "Zona horaria:";
+$a->strings["Your Language:"] = "Tu idioma:";
+$a->strings["Set the language we use to show you friendica interface and to send you emails"] = "Selecciona el idioma que se usara para la interfaz del usuario y para el envío de correo.";
+$a->strings["Default Post Location:"] = "Localización predeterminada:";
+$a->strings["Use Browser Location:"] = "Usar localización del navegador:";
+$a->strings["Security and Privacy Settings"] = "Configuración de seguridad y privacidad";
+$a->strings["Maximum Friend Requests/Day:"] = "Máximo número de peticiones de amistad por día:";
+$a->strings["(to prevent spam abuse)"] = "(para prevenir el abuso de spam)";
+$a->strings["Default Post Permissions"] = "Permisos por defecto para las publicaciones";
+$a->strings["(click to open/close)"] = "(pulsa para abrir/cerrar)";
+$a->strings["Default Private Post"] = "Publicación Privada por defecto";
+$a->strings["Default Public Post"] = "Publicación Pública por defecto";
+$a->strings["Default Permissions for New Posts"] = "Permisos por defecto para nuevas publicaciones";
+$a->strings["Maximum private messages per day from unknown people:"] = "Número máximo de mensajes diarios para desconocidos:";
+$a->strings["Notification Settings"] = "Configuración de notificaciones";
+$a->strings["By default post a status message when:"] = "Publicar en tu estado cuando:";
+$a->strings["accepting a friend request"] = "aceptes una solicitud de amistad";
+$a->strings["joining a forum/community"] = "te unas a un foro/comunidad";
+$a->strings["making an <em>interesting</em> profile change"] = "hagas un cambio <em>interesante</em> en tu perfil";
+$a->strings["Send a notification email when:"] = "Enviar notificación por correo cuando:";
+$a->strings["You receive an introduction"] = "Recibas una presentación";
+$a->strings["Your introductions are confirmed"] = "Tu presentación sea confirmada";
+$a->strings["Someone writes on your profile wall"] = "Alguien escriba en el muro de mi perfil";
+$a->strings["Someone writes a followup comment"] = "Algien escriba en un comentario que sigo";
+$a->strings["You receive a private message"] = "Recibas un mensaje privado";
+$a->strings["You receive a friend suggestion"] = "Recibas una sugerencia de amistad";
+$a->strings["You are tagged in a post"] = "Seas etiquetado en una publicación";
+$a->strings["You are poked/prodded/etc. in a post"] = "Te han tocado/empujado/etc. en una publicación";
+$a->strings["Activate desktop notifications"] = "Activar notificaciones en pantalla.";
+$a->strings["Show desktop popup on new notifications"] = "Mostrar notificaciones emergentes en caso de nuevos eventos.";
+$a->strings["Text-only notification emails"] = "Notificaciones e-mail de solo texto";
+$a->strings["Send text only notification emails, without the html part"] = "Enviar las notificaciones por correo con formato de solo texto sin html.";
+$a->strings["Advanced Account/Page Type Settings"] = "Configuración avanzada de tipo de Cuenta/Página";
+$a->strings["Change the behaviour of this account for special situations"] = "Cambiar el comportamiento de esta cuenta para situaciones especiales";
+$a->strings["Relocate"] = "Relocalizar";
+$a->strings["If you have moved this profile from another server, and some of your contacts don't receive your updates, try pushing this button."] = "Si ha migrado este perfil desde otro servidor aquí y algunos contactos no reciben sus publicaciones intente  recomunicar su ubicación a traves este botón. (Como para decir el botón de los botones)";
+$a->strings["Resend relocate message to contacts"] = "Reenviar mensaje de relocalización a los contactos";
+$a->strings["%1\$s is following %2\$s's %3\$s"] = "%1\$s está siguiendo las %3\$s de %2\$s";
+$a->strings["Do you really want to delete this suggestion?"] = "¿Estás seguro de que quieres borrar esta sugerencia?";
+$a->strings["No suggestions available. If this is a new site, please try again in 24 hours."] = "No hay sugerencias disponibles. Si el sitio web es nuevo inténtalo de nuevo dentro de 24 horas.";
+$a->strings["Ignore/Hide"] = "Ignorar/Ocultar";
+$a->strings["Tag removed"] = "Etiqueta eliminada";
+$a->strings["Remove Item Tag"] = "Eliminar etiqueta";
+$a->strings["Select a tag to remove: "] = "Selecciona una etiqueta para eliminar: ";
+$a->strings["Export account"] = "Exportar cuenta";
+$a->strings["Export your account info and contacts. Use this to make a backup of your account and/or to move it to another server."] = "Exporta la información de tu cuenta y tus contactos. Úsalo para guardar una copia de seguridad de tu cuenta y/o moverla a otro servidor.";
+$a->strings["Export all"] = "Exportar todo";
+$a->strings["Export your accout info, contacts and all your items as json. Could be a very big file, and could take a lot of time. Use this to make a full backup of your account (photos are not exported)"] = "Exporta la información de tu cuenta, contactos y lo demás en JSON. Puede ser un archivo bastante grande, por lo que llevará tiempo. Úsalo para hacer una copia de seguridad completa de tu cuenta (las fotos no se exportarán)";
+$a->strings["Move account"] = "Mover cuenta";
+$a->strings["You can import an account from another Friendica server."] = "Puedes importar una cuenta desde otro servidor de Friendica.";
+$a->strings["You need to export your account from the old server and upload it here. We will recreate your old account here with all your contacts. We will try also to inform your friends that you moved here."] = "Necesitas exportar tu cuenta del antiguo servidor y subirla aquí. Volveremos a crear tu antigua cuenta con todos tus contactos aquí. También intentaremos de informar a tus amigos de que te has mudado.";
+$a->strings["This feature is experimental. We can't import contacts from the OStatus network (GNU Social/Statusnet) or from Diaspora"] = "Esta característica es experimental. No podemos importar contactos desde la red OStatus (statusnet/identi.ca) o desde Diaspora*";
+$a->strings["Account file"] = "Archivo de la cuenta";
+$a->strings["To export your account, go to \"Settings->Export your personal data\" and select \"Export account\""] = "Para exportar el perfil vaya a \"Configuracion -> Exportar sus datos personales\" y seleccione \"Exportar cuenta\"";
+$a->strings["[Embedded content - reload page to view]"] = "[Contenido incrustado - recarga la página para verlo]";
+$a->strings["Do you really want to delete this video?"] = "Realmente quieres eliminar este vídeo?";
+$a->strings["Delete Video"] = "Borrar vídeo";
+$a->strings["No videos selected"] = "Ningún vídeo seleccionado";
+$a->strings["Recent Videos"] = "Vídeos recientes";
+$a->strings["Upload New Videos"] = "Subir nuevos vídeos";
 $a->strings["No contacts."] = "Ningún contacto.";
+$a->strings["Access denied."] = "Acceso denegado.";
+$a->strings["Invalid request."] = "Consulta invalida";
+$a->strings["Sorry, maybe your upload is bigger than the PHP configuration allows"] = "Disculpa, posiblemente el archivo subido es mas grande que la PHP configuración permite.";
+$a->strings["Or - did you try to upload an empty file?"] = "Si no - intento de subir un archivo vacío?";
+$a->strings["File exceeds size limit of %s"] = "El archivo excede el limite de tamaño de %s";
+$a->strings["File upload failed."] = "Ha fallado la subida del archivo.";
+$a->strings["Number of daily wall messages for %s exceeded. Message failed."] = "Excedido el número máximo de mensajes para %s. El mensaje no se ha enviado.";
+$a->strings["Unable to check your home location."] = "Imposible comprobar tu servidor de inicio.";
+$a->strings["No recipient."] = "Sin receptor.";
+$a->strings["If you wish for %s to respond, please check that the privacy settings on your site allow private mail from unknown senders."] = "Si quieres que %s te responda, asegúrate de que la configuración de privacidad permite enviar correo privado a desconocidos.";
 $a->strings["via"] = "vía";
-$a->strings["Repeat the image"] = "Repetir la imagen";
-$a->strings["Will repeat your image to fill the background."] = "Repetirá su imagen para llenar el fondo";
-$a->strings["Stretch"] = "Estirar";
-$a->strings["Will stretch to width/height of the image."] = "Estirará la anchura/altura de la imagen.";
-$a->strings["Resize fill and-clip"] = "Reajustar llenado y clip";
-$a->strings["Resize to fill and retain aspect ratio."] = "Reajustar para llenar y conservar proporción";
-$a->strings["Resize best fit"] = "Reajustar al mejor tamaño";
-$a->strings["Resize to best fit and retain aspect ratio."] = "Reajustar al mejor tamaño y conservar proporción";
+$a->strings["greenzero"] = "greenzero";
+$a->strings["purplezero"] = "purplezero";
+$a->strings["easterbunny"] = "easterbunny";
+$a->strings["darkzero"] = "darkzero";
+$a->strings["comix"] = "comix";
+$a->strings["slackr"] = "slackr";
+$a->strings["Variations"] = "Variaciones";
 $a->strings["Default"] = "Por defecto";
 $a->strings["Note: "] = "Nota:";
 $a->strings["Check image permissions if all users are allowed to visit the image"] = "Compruebe los permisos de imagen si se les permite a todos los usuarios visitar la imagen";
@@ -2012,6 +2011,14 @@ $a->strings["Link color"] = "Color de enlace";
 $a->strings["Set the background color"] = "Seleccionar el color de fondo";
 $a->strings["Content background transparency"] = "Transparencia de contenido de fondo";
 $a->strings["Set the background image"] = "Seleccionar la imagen de fondo";
+$a->strings["Repeat the image"] = "Repetir la imagen";
+$a->strings["Will repeat your image to fill the background."] = "Repetirá su imagen para llenar el fondo";
+$a->strings["Stretch"] = "Estirar";
+$a->strings["Will stretch to width/height of the image."] = "Estirará la anchura/altura de la imagen.";
+$a->strings["Resize fill and-clip"] = "Reajustar llenado y clip";
+$a->strings["Resize to fill and retain aspect ratio."] = "Reajustar para llenar y conservar proporción";
+$a->strings["Resize best fit"] = "Reajustar al mejor tamaño";
+$a->strings["Resize to best fit and retain aspect ratio."] = "Reajustar al mejor tamaño y conservar proporción";
 $a->strings["Guest"] = "Invitado";
 $a->strings["Visitor"] = "Visitante";
 $a->strings["Alignment"] = "Alineación";
@@ -2020,33 +2027,13 @@ $a->strings["Center"] = "Centrado";
 $a->strings["Color scheme"] = "Esquema de color";
 $a->strings["Posts font size"] = "Tamaño de letra del titulo de las publicaciones";
 $a->strings["Textareas font size"] = "Tamaño de letra del área de texto";
-$a->strings["Community Profiles"] = "Perfiles de la Comunidad";
-$a->strings["Last users"] = "Últimos usuarios";
-$a->strings["Find Friends"] = "Buscar amigos";
-$a->strings["Local Directory"] = "Directorio local";
-$a->strings["Quick Start"] = "Inicio rápido";
-$a->strings["Connect Services"] = "Servicios conectados";
 $a->strings["Comma separated list of helper forums"] = "Lista separada por comas de foros de ayuda.";
 $a->strings["Set style"] = "Definir estilo";
 $a->strings["Community Pages"] = "Páginas de Comunidad";
+$a->strings["Community Profiles"] = "Perfiles de la Comunidad";
 $a->strings["Help or @NewHere ?"] = "¿Ayuda o @NuevoAquí?";
-$a->strings["greenzero"] = "greenzero";
-$a->strings["purplezero"] = "purplezero";
-$a->strings["easterbunny"] = "easterbunny";
-$a->strings["darkzero"] = "darkzero";
-$a->strings["comix"] = "comix";
-$a->strings["slackr"] = "slackr";
-$a->strings["Variations"] = "Variaciones";
-$a->strings["Delete this item?"] = "¿Eliminar este elemento?";
-$a->strings["show fewer"] = "ver menos";
-$a->strings["Update %s failed. See error logs."] = "Falló la actualización de %s. Mira los registros de errores.";
-$a->strings["Create a New Account"] = "Crear una nueva cuenta";
-$a->strings["Password: "] = "Contraseña: ";
-$a->strings["Remember me"] = "Recordarme";
-$a->strings["Or login using OpenID: "] = "O inicia sesión usando OpenID: ";
-$a->strings["Forgot your password?"] = "¿Olvidaste la contraseña?";
-$a->strings["Website Terms of Service"] = "Términos de uso del sitio";
-$a->strings["terms of service"] = "Términos de uso";
-$a->strings["Website Privacy Policy"] = "Política de privacidad del sitio";
-$a->strings["privacy policy"] = "Política de privacidad";
-$a->strings["toggle mobile"] = "Cambiar a versión móvil";
+$a->strings["Connect Services"] = "Servicios conectados";
+$a->strings["Find Friends"] = "Buscar amigos";
+$a->strings["Last users"] = "Últimos usuarios";
+$a->strings["Local Directory"] = "Directorio local";
+$a->strings["Quick Start"] = "Inicio rápido";
index fdba195f1770fe29a4a0aa41e31e58947f5331cf..86efb26a22da73f4cef1adb0ca6828b383f31996 100644 (file)
@@ -1,6 +1,6 @@
 <script>
        $(function(){
-               
+
                $("#cnftheme").click(function(){
                        $.colorbox({
                                width: 800,
                                                        data[$(this).attr('name')] = $(this).children(":selected").val();
                                                });
                                                console.log(":)", url, data);
-                                       
+
                                                $.post(url, data, function(data) {
                                                        if(timer) clearTimeout(timer);
                                                        NavUpdate();
                                                        $.colorbox.close();
                                                })
-                                       
+
                                                return false;
                                        });
-                               
+
                                }
                        });
                        return false;
@@ -40,7 +40,7 @@
 </script>
 <div id='adminpage'>
        <h1>{{$title}} - {{$page}}</h1>
-       
+
        <form action="{{$baseurl}}/admin/site" method="post">
     <input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
 
@@ -59,7 +59,7 @@
        {{include file="field_checkbox.tpl" field=$hide_help}}
        {{include file="field_select.tpl" field=$singleuser}}
        <div class="submit"><input type="submit" name="page_site" value="{{$submit|escape:'html'}}" /></div>
-       
+
        <h3>{{$registration}}</h3>
        {{include file="field_input.tpl" field=$register_text}}
        {{include file="field_select.tpl" field=$register_policy}}
@@ -74,7 +74,7 @@
        {{include file="field_input.tpl" field=$maximagelength}}
        {{include file="field_input.tpl" field=$jpegimagequality}}
        <div class="submit"><input type="submit" name="page_site" value="{{$submit|escape:'html'}}" /></div>
-       
+
        <h3>{{$corporate}}</h3>
        {{include file="field_input.tpl" field=$allowed_sites}}
        {{include file="field_input.tpl" field=$allowed_email}}
        {{include file="field_checkbox.tpl" field=$thread_allow}}
        {{include file="field_checkbox.tpl" field=$newuser_private}}
        {{include file="field_checkbox.tpl" field=$enotify_no_content}}
-       {{include file="field_checkbox.tpl" field=$private_addons}}     
+       {{include file="field_checkbox.tpl" field=$private_addons}}
        {{include file="field_checkbox.tpl" field=$disable_embedded}}
        {{include file="field_checkbox.tpl" field=$allow_users_remote_self}}
        <div class="submit"><input type="submit" name="page_site" value="{{$submit|escape:'html'}}" /></div>
-       
+
        <h3>{{$advanced}}</h3>
        {{include file="field_select.tpl" field=$rino}}
-       {{include file="field_checkbox.tpl" field=$no_utf}}
        {{include file="field_checkbox.tpl" field=$verifyssl}}
        {{include file="field_input.tpl" field=$proxy}}
        {{include file="field_input.tpl" field=$proxyuser}}
        {{include file="field_input.tpl" field=$basepath}}
        {{include file="field_checkbox.tpl" field=$suppress_tags}}
        {{include file="field_checkbox.tpl" field=$nodeinfo}}
-       {{include file="field_input.tpl" field=$embedly}}
        <div class="submit"><input type="submit" name="page_site" value="{{$submit|escape:'html'}}" /></div>
 
        <h3>{{$portable_contacts}}</h3>
        <div class="submit"><input type="submit" name="page_site" value="{{$submit|escape:'html'}}" /></div>
 
        </form>
-       
+
        {{* separate form for relocate... *}}
        <form action="{{$baseurl}}/admin/site" method="post">
        <input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
        <input type="hidden" name="page_site" value="{{$submit|escape:'html'}}">
        <div class="submit"><input type="submit" name="relocate" value="{{$submit|escape:'html'}}" /></div>
        </form>
-       
+
 </div>
index 78a2e47df2e89243ede77e7483cf52806503c8c9..f8a6bc1c90f4cdc500cbc8ddc856bb9c9e2904e1 100644 (file)
@@ -80,9 +80,8 @@ $a->config['system']['maximagesize'] = 800000;
 $a->config['system']['huburl'] = '[internal]';
 
 // Server-to-server private message encryption (RINO) is allowed by default.
-// Encryption will only be provided if this setting is set to a non zero
-// value and the PHP mcrypt extension is installed on both systems
-// set to 0 to disable, 2 to enable, 1 is deprecated but wont need mcrypt
+// Encryption will only be provided if this setting is set to a non zero value
+// set to 0 to disable, 2 to enable, 1 is deprecated
 
 $a->config['system']['rino_encrypt'] = {{$rino}};
 
index 47973ed448bd0156787d87a468af1ccf72d14140..e0a0b09b76c7bb276b4eed19f95c0469970f3248 100644 (file)
@@ -1272,6 +1272,18 @@ section #jotOpen {
     color: #fff;
 }
 
+/* Filebrowser */
+.fbrowser .profile-rotator-wrapper {
+    min-height: 200px;
+}
+.fbrowser .fa-spin {
+   position: absolute;
+   left: 45%;
+   top: 40%;
+   font-size: 48px;
+   margin:0px auto;
+}
+
 /*
 /* Stream
 */
index 6856d12ba28737202e34f115621190fe8fc6f1cf..a66309865dc10e6a243bc2af97f33424e748bf3f 100644 (file)
@@ -88,23 +88,35 @@ var FileBrowser = {
 \r
                console.log("FileBrowser:", nickname, type,FileBrowser.event, FileBrowser.id );\r
 \r
+               // We need to add the AjaxUpload to the button\r
+               FileBrowser.uploadButtons();\r
+\r
                $(".error a.close").on("click", function(e) {\r
                        e.preventDefault();\r
                        $(".error").addClass("hidden");\r
                });\r
 \r
-               $(".folders a, .path a").on("click", function(e) {\r
+               // Click on album link\r
+               $(".fbrowser").on("click", ".folders a, .path a", function(e) {\r
                        e.preventDefault();\r
                        var url = baseurl + "/fbrowser/" + FileBrowser.type + "/" + this.dataset.folder + "?mode=none";\r
+                       $(".fbrowser-content").hide();\r
+                       $(".fbrowser .profile-rotator-wrapper").show();\r
 \r
                        // load new content to fbrowser window\r
-                       $(".fbrowser").load(url,function() {\r
-                               $(function() {FileBrowser.init(nickname, type, hash);});\r
+                       $(".fbrowser").load(url, function(responseText, textStatus){\r
+                               $(".profile-rotator-wrapper").hide();\r
+                               if (textStatus === 'success') {\r
+                                       $(".fbrowser_content").show();\r
+                                       // We need to add the AjaxUpload to the button\r
+                                       FileBrowser.uploadButtons();\r
+                               }\r
                        });\r
+                       \r
                });\r
 \r
                //embed on click\r
-               $(".photo-album-photo-link").on('click', function(e) {\r
+               $(".fbrowser").on('click', ".photo-album-photo-link", function(e) {\r
                        e.preventDefault();\r
 \r
                        var embed = "";\r
@@ -142,39 +154,52 @@ var FileBrowser = {
                        // update autosize for this textarea\r
                        autosize.update($(".text-autosize"));\r
                });\r
+       },\r
 \r
-               if ($("#upload-image").length)\r
+       uploadButtons: function() {\r
+               if ($("#upload-image").length) {\r
                        var image_uploader = new window.AjaxUpload(\r
                                'upload-image',\r
-                               { action: 'wall_upload/'+FileBrowser.nickname+'?response=json',\r
+                               {       action: 'wall_upload/'+FileBrowser.nickname+'?response=json',\r
                                        name: 'userfile',\r
                                        responseType: 'json',\r
-                                       onSubmit: function(file,ext) { $('#profile-rotator').show(); $(".error").addClass('hidden'); },\r
+                                       onSubmit: function(file,ext) {\r
+                                               $(".fbrowser-content").hide();\r
+                                               $(".fbrowser .profile-rotator-wrapper").show();\r
+                                               $(".error").addClass('hidden');\r
+                                       },\r
                                        onComplete: function(file,response) {\r
                                                if (response['error']!= undefined) {\r
                                                        $(".error span").html(response['error']);\r
                                                        $(".error").removeClass('hidden');\r
-                                                       $('#profile-rotator').hide();\r
+                                                       $(".fbrowser .profile-rotator-wrapper").hide();\r
                                                        return;\r
                                                }\r
+\r
+                                               $(".profile-rotator-wrapper").hide();\r
+                                               $(".fbrowser_content").show();\r
+\r
 //                                             location = baseurl + "/fbrowser/image/?mode=none"+location['hash'];\r
 //                                             location.reload(true);\r
 \r
                                                var url = baseurl + "/fbrowser/" + FileBrowser.type + "?mode=none"\r
                                                // load new content to fbrowser window\r
-                                               $(".fbrowser").load(url,function() {\r
-                                                       $(function() {FileBrowser.init(nickname, type, hash);});\r
-                                               });\r
+                                               $(".fbrowser").load(url);\r
                                        }\r
                                }\r
                        );\r
+               }\r
 \r
-               if ($("#upload-file").length)\r
+               if ($("#upload-file").length) {\r
                        var file_uploader = new window.AjaxUpload(\r
                                'upload-file',\r
-                               { action: 'wall_attach/'+FileBrowser.nickname+'?response=json',\r
+                               {       action: 'wall_attach/'+FileBrowser.nickname+'?response=json',\r
                                        name: 'userfile',\r
-                                       onSubmit: function(file,ext) { $('#profile-rotator').show(); $(".error").addClass('hidden'); },\r
+                                       onSubmit: function(file,ext) {\r
+                                               $(".fbrowser-content").hide();\r
+                                               $(".fbrowser .profile-rotator-wrapper").show();\r
+                                               $(".error").addClass('hidden');\r
+                                       },\r
                                        onComplete: function(file,response) {\r
                                                if (response['error']!= undefined) {\r
                                                        $(".error span").html(response['error']);\r
@@ -182,17 +207,19 @@ var FileBrowser = {
                                                        $('#profile-rotator').hide();\r
                                                        return;\r
                                                }\r
+\r
+                                               $(".profile-rotator-wrapper").hide();\r
+                                               $(".fbrowser_content").show();\r
+\r
 //                                             location = baseurl + "/fbrowser/file/?mode=none"+location['hash'];\r
 //                                             location.reload(true);\r
 \r
                                                var url = baseurl + "/fbrowser/" + FileBrowser.type + "?mode=none"\r
                                                // load new content to fbrowser window\r
-                                               $(".fbrowser").load(url,function() {\r
-                                                       $(function() {FileBrowser.init(nickname, type, hash);});\r
-                                               });\r
+                                               $(".fbrowser").load(url);\r
                                        }\r
                                }\r
-               );\r
-       },\r
+                       );\r
+               }\r
+       }\r
 };\r
-\r
index f657ff5f2314afd450d68718d3f82a9dd539d8b3..b77f621617c3adfff0dcc6386dc6c664ee11a90b 100644 (file)
@@ -8,9 +8,11 @@ $(document).ready(function(){
                $(this).removeData('bs.modal');
                $("#modal-title").empty();
                $('#modal-body').empty();
-               // remove the file browser from jot (else we would have problems
-               // with ajaxupload
+               // Remove the file browser from jot (else we would have problems
+               // with AjaxUpload
                $(".fbrowser").remove();
+               // Remove the AjaxUpload element
+               $("[name=userfile]").parent().remove();
        });
 
        // Clear bs modal on close
index 56118cc90e0401c0b283ed6a25ce9c6f69a3e187..87ccf3dc1a85114da47094bf9c7066cced5f36e7 100644 (file)
@@ -4,20 +4,17 @@
  * @brief The default site template
  */
 ?>
-
 <!DOCTYPE html >
-
-<?php 
+<?php
        require_once('view/theme/frio/php/frio_boot.php');
 
 //     $minimal = is_modal();
 
 ?>
-
 <html>
 <head>
        <title><?php if(x($page,'title')) echo $page['title'] ?></title>
-       <meta request="<?php echo htmlspecialchars($_REQUEST['pagename']) ?> ">
+       <meta request="<?php echo htmlspecialchars($_REQUEST['pagename']) ?>">
        <script>var baseurl="<?php echo App::get_baseurl() ?>";</script>
        <script>var frio="<?php echo "view/theme/frio"; ?>";</script>
        <?php $baseurl = App::get_baseurl(); ?>
@@ -31,8 +28,6 @@
                        if(x($page,'htmlhead')) echo $page['htmlhead'];
                }
        ?>
-       
-
 </head>
 <?php
 if(($_SERVER['REQUEST_URI'] != "/register") && ($_SERVER['REQUEST_URI'] != "/lostpass") && ($_SERVER['REQUEST_URI'] != "/login"))
@@ -90,7 +85,6 @@ else
                                        ";
                                }
 ?>
-               
                        </div><!--row-->
                </div><!-- container -->
 
index 491fa9d5b0df87c69b97170b39532db65259ccdc..9e3d2ca638ab0595d1580a8f3481e3888c30d7fb 100644 (file)
@@ -4,21 +4,17 @@
  * @brief The default site template
  */
 ?>
-
 <!DOCTYPE html >
-
 <html>
 <head>
        <title><?php if(x($page,'title')) echo $page['title'] ?></title>
        <meta name="viewport" content="initial-scale=1.0">
-       <meta request="<?php echo htmlspecialchars($_REQUEST['pagename']) ?> ">
+       <meta request="<?php echo htmlspecialchars($_REQUEST['pagename']) ?>">
        <script>var baseurl="<?php echo App::get_baseurl() ?>";</script>
        <script>var frio="<?php echo "view/theme/frio"; ?>";</script>
        <?php $baseurl = App::get_baseurl(); ?>
        <?php $frio = "view/theme/frio"; ?>
        <?php if(x($page,'htmlhead')) echo $page['htmlhead']; ?>
-       
-
 </head>
 <body id=\"top\">";
 <?php if($_SERVER['REQUEST_URI'] == "/"){header('Location: /login');} ?>
@@ -54,7 +50,6 @@
                                        </div>
                                                ";
 ?>
-               
                        </div><!--row-->
                </div><!-- container -->
 
@@ -80,7 +75,7 @@
                        })
                })
        }
-       
+
        $('textarea').enterKey(function() {$(this).closest('form').submit(); }, 'ctrl')
        $('input').enterKey(function() {$(this).closest('form').submit(); }, 'ctrl')
 </script>
@@ -126,7 +121,5 @@ $("nav").bind('nav-update', function(e,data)
                </div>
        </div>
 </div>
-
-
 </footer>
 </body>
index 55cecabb8fac1fb0b30bf0fcc2727f8c4f0926b1..1a1bd9a6759aedb6a016937f6d08b18981cdac5c 100644 (file)
@@ -8,43 +8,42 @@
 {{*<script type="text/javascript" src="view/theme/frio/js/filebrowser.js"></script>*}}
 
 <div class="fbrowser {{$type}}">
-       <input id="fb-nickname" type="hidden" name="type" value="{{$nickname}}" />
-       <input id="fb-type" type="hidden" name="type" value="{{$type}}" />
+       <div class="fbrowser-content">
+               <input id="fb-nickname" type="hidden" name="type" value="{{$nickname}}" />
+               <input id="fb-type" type="hidden" name="type" value="{{$type}}" />
 
-       <div class="error hidden">
-               <span></span> <a href="#" class='close'>X</a>
-       </div>
+               <div class="error hidden">
+                       <span></span> <a href="#" class='close'>X</a>
+               </div>
 
-       <div class="path">
-               {{foreach $path as $p}}<a href="#" data-folder="{{$p.0}}">{{$p.1}}</a>{{/foreach}}
-       </div>
+               <div class="path">
+                       {{foreach $path as $p}}<a href="#" data-folder="{{$p.0}}">{{$p.1}}</a>{{/foreach}}
+               </div>
 
-       {{if $folders }}
-       <div class="folders">
-               <ul>
-                       {{foreach $folders as $f}}<li><a href="#" data-folder="{{$f.0}}">{{$f.1}}</a></li>{{/foreach}}
-               </ul>
-       </div>
-       {{/if}}
+               {{if $folders }}
+               <div class="folders">
+                       <ul>
+                               {{foreach $folders as $f}}<li><a href="#" data-folder="{{$f.0}}">{{$f.1}}</a></li>{{/foreach}}
+                       </ul>
+               </div>
+               {{/if}}
+
+               <div class="list">
+                       {{foreach $files as $f}}
+                       <div class="photo-album-image-wrapper">
+                               <a href="#" class="photo-album-photo-link" data-link="{{$f.0}}" data-filename="{{$f.1}}" data-img="{{$f.2}}">
+                                       <img src="{{$f.2}}">
+                                       <p>{{$f.1}}</p>
+                               </a>
+                       </div>
+                       {{/foreach}}
+               </div>
 
-       <div class="list">
-               {{foreach $files as $f}}
-               <div class="photo-album-image-wrapper">
-                       <a href="#" class="photo-album-photo-link" data-link="{{$f.0}}" data-filename="{{$f.1}}" data-img="{{$f.2}}">
-                               <img src="{{$f.2}}">
-                               <p>{{$f.1}}</p>
-                       </a>
+               <div class="upload">
+                       <button id="upload-{{$type}}"><img id="profile-rotator" src="images/rotator.gif" alt="{{$wait}}" title="{{$wait|escape:'html'}}" style="display: none;" /> {{"Upload"|t}}</button>
                </div>
-               {{/foreach}}
        </div>
-
-       <div class="upload">
-               <button id="upload-{{$type}}"><img id="profile-rotator" src="images/rotator.gif" alt="{{$wait}}" title="{{$wait|escape:'html'}}" style="display: none;" /> {{"Upload"|t}}</button>
+       <div class="profile-rotator-wrapper" style="display: none;">
+               <i class="fa fa-circle-o-notch fa-spin"></i>
        </div>
 </div>
-
-<script>
-    $(document).ready(function(){
-
-       });
-</script>
\ No newline at end of file
index 08b068c4023a529251fc9bdfe7265b4ba788345d..fb3694f59944e2d7788027f3e2f3c4b75d54aafb 100644 (file)
@@ -52,7 +52,6 @@
        <div class="submit"><input type="submit" name="page_site" value="{{$submit}}" /></div>
        
        <h3>{{$advanced}}</h3>
-       {{include file="field_checkbox.tpl" field=$no_utf}}
        {{include file="field_checkbox.tpl" field=$verifyssl}}
        {{include file="field_input.tpl" field=$proxy}}
        {{include file="field_input.tpl" field=$proxyuser}}
index e9f472a2416735e4b62142b2cbc8e8c47182e032..535242a3ecba1d35faee5b90dea9af71afcbf387 100644 (file)
@@ -52,7 +52,6 @@
        <div class="submit"><input type="submit" name="page_site" value="{{$submit}}" /></div>
        
        <h3>{{$advanced}}</h3>
-       {{include file="field_checkbox.tpl" field=$no_utf}}
        {{include file="field_checkbox.tpl" field=$verifyssl}}
        {{include file="field_input.tpl" field=$proxy}}
        {{include file="field_input.tpl" field=$proxyuser}}