-- ------------------------------------------
--- Friendica 2019.09-rc (Dalmatian Bellflower)
--- DB_UPDATE_VERSION 1322
+-- Friendica 2019.12-dev (Dalmatian Bellflower)
+-- DB_UPDATE_VERSION 1324
-- ------------------------------------------
`uid` mediumint unsigned NOT NULL DEFAULT 0 COMMENT 'User id',
`hidden` boolean NOT NULL DEFAULT '0' COMMENT 'Marker to hide an item from the user',
`ignored` boolean COMMENT 'Ignore this thread if set',
- PRIMARY KEY(`uid`,`iid`)
+ `pinned` boolean COMMENT 'The item is pinned on the profile page',
+ PRIMARY KEY(`uid`,`iid`),
+ INDEX `uid_pinned` (`uid`,`pinned`)
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='User specific item data';
--
--- /dev/null
+# Export / Import of followed Contacts
+
+* [Home](help)
+
+In addition to [move your account](help/Move-Account) you can export and import the list of accounts you follow.
+The exported list is stored as CSV file that is compatible to the format used by other platforms as e.g. Mastodon or Pleroma.
+
+## Export of followed Contacts
+
+To export the list of accounts that you follow, go to the [Settings Export personal date](settings/userexport) and click the [Export Contacts to CSV](settings/userexport/contact).
+
+## Import of followed Contacts
+
+To import contacts from a CSV file, go to the [Settings page](settings).
+At the bottom of the *account settings* page you'll find the *import contacts* section.
+Upload the CSV file there.
+
+### Supported File Format
+
+The CSV file *must* contain at least one column.
+In the first column the table should contain either the handle or URL of an followed account.
+(one account per row.)
+Other columns in the CSV file will be ignored.
* [Chats](help/Chats)
* Further information
* [Move your account](help/Move-Account)
+ * [Export / Import of followed Contacts](help/Export-Import-Contacts)
* [Delete your account](help/Remove-Account)
* [Frequently asked questions (FAQ)](help/FAQ)
--- /dev/null
+# Export / Import von gefolgten Kontakte
+
+* [Home](help)
+
+Zusätzlich zum [Umziehen des Accounts](help/Move-Account) kannst du die Liste der von dir gefolgten Kontakte exportieren und importieren.
+Die exportierte Liste wird als CSV Datei in einem zu anderen Plattformen, z.B. Mastodon oder Pleroma, kompatiblen Format gespeichert.
+
+## Export der gefolgten Kontakte
+
+Um die Liste der Kontakte *denen du folgst* zu exportieren, geht die [Einstellungen Persönliche Daten exportieren](settings/userexport) und klicke den [Exportiere Kontakte als CSV](settings/userexport/contact) an.
+
+## Import der gefolgten Kontakte
+
+Um die Kontakt CSV Datei zu importieren, gehe in die [Einstellungen](settings).
+Am Ende der Einstellungen zum Nutzerkonto findest du den Abschnitt "Kontakte Importieren".
+Hier kannst du die CSV Datei auswählen und hoch laden.
+
+### Unterstütztes Datei Format
+
+Die CSV Datei *muss* mindestens eine Spalte beinhalten.
+In der ersten Spalte der Tabelle sollte *sollte* entweder das Handle oder die URL des gefolgten Kontakts.
+(Ein Kontakt pro Zeile.)
+Alle anderen Spalten der CSV Datei werden beim Importieren ignoriert.
* [Chats](help/Chats)
* Weiterführende Informationen
* [Account umziehen](help/Move-Account)
+ * [Export / Import gefolgter Kontakte](help/Export-Import-Contacts)
* [Account löschen](help/Remove-Account)
* [Bugs und Probleme](help/Bugs-and-Issues)
* [Häufig gestellte Fragen (FAQ)](help/FAQ)
use Friendica\Protocol\Activity;
use Friendica\Protocol\Diaspora;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Images;
use Friendica\Util\Network;
use Friendica\Util\Proxy as ProxyUtils;
use Friendica\Util\Strings;
api_user()
);
if (DBA::isResult($r)) {
- $phototypes = Image::supportedTypes();
+ $phototypes = Images::supportedTypes();
$ext = $phototypes[$r[0]['type']];
$description = $r[0]['desc'] ?? '';
$_REQUEST['body'] .= "\n\n" . '[url=' . System::baseUrl() . '/photos/' . $r[0]['nickname'] . '/image/' . $r[0]['resource-id'] . ']';
$attachments = [];
foreach ($images[1] as $image) {
- $imagedata = Image::getInfoFromURL($image);
+ $imagedata = Images::getInfoFromURLCached($image);
if ($imagedata) {
$attachments[] = ["url" => $image, "mimetype" => $imagedata["mime"], "size" => $imagedata["size"]];
$start = iconv_strpos($text, $url, $offset, "UTF-8");
if (!($start === false)) {
- $image = Image::getInfoFromURL($url);
+ $image = Images::getInfoFromURLCached($url);
if ($image) {
// If image cache is activated, then use the following sizes:
// thumb (150), small (340), medium (600) and large (1024)
$media_url = ProxyUtils::proxifyUrl($url);
$sizes = [];
- $scale = Image::getScalingDimensions($image[0], $image[1], 150);
+ $scale = Images::getScalingDimensions($image[0], $image[1], 150);
$sizes["thumb"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"];
if (($image[0] > 150) || ($image[1] > 150)) {
- $scale = Image::getScalingDimensions($image[0], $image[1], 340);
+ $scale = Images::getScalingDimensions($image[0], $image[1], 340);
$sizes["small"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"];
}
- $scale = Image::getScalingDimensions($image[0], $image[1], 600);
+ $scale = Images::getScalingDimensions($image[0], $image[1], 600);
$sizes["medium"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"];
if (($image[0] > 600) || ($image[1] > 600)) {
- $scale = Image::getScalingDimensions($image[0], $image[1], 1024);
+ $scale = Images::getScalingDimensions($image[0], $image[1], 1024);
$sizes["large"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"];
}
} else {
}
if ($filetype == "") {
- $filetype=Image::guessType($filename);
+ $filetype = Images::guessType($filename);
}
$imagedata = @getimagesize($src);
if ($imagedata) {
$height = $Image->getHeight();
// create a new resource-id if not already provided
- $hash = ($photo_id == null) ? Photo::newResource() : $photo_id;
+ $resource_id = ($photo_id == null) ? Photo::newResource() : $photo_id;
if ($mediatype == "photo") {
// upload normal image (scales 0, 1, 2)
Logger::log("photo upload: starting new photo upload", Logger::DEBUG);
- $r = Photo::store($Image, local_user(), $visitor, $hash, $filename, $album, 0, 0, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
+ $r = Photo::store($Image, local_user(), $visitor, $resource_id, $filename, $album, 0, 0, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
if (!$r) {
Logger::log("photo upload: image upload with scale 0 (original size) failed");
}
if ($width > 640 || $height > 640) {
$Image->scaleDown(640);
- $r = Photo::store($Image, local_user(), $visitor, $hash, $filename, $album, 1, 0, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
+ $r = Photo::store($Image, local_user(), $visitor, $resource_id, $filename, $album, 1, 0, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
if (!$r) {
Logger::log("photo upload: image upload with scale 1 (640x640) failed");
}
if ($width > 320 || $height > 320) {
$Image->scaleDown(320);
- $r = Photo::store($Image, local_user(), $visitor, $hash, $filename, $album, 2, 0, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
+ $r = Photo::store($Image, local_user(), $visitor, $resource_id, $filename, $album, 2, 0, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
if (!$r) {
Logger::log("photo upload: image upload with scale 2 (320x320) failed");
}
if ($width > 300 || $height > 300) {
$Image->scaleDown(300);
- $r = Photo::store($Image, local_user(), $visitor, $hash, $filename, $album, 4, $profile, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
+ $r = Photo::store($Image, local_user(), $visitor, $resource_id, $filename, $album, 4, $profile, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
if (!$r) {
Logger::log("photo upload: profile image upload with scale 4 (300x300) failed");
}
if ($width > 80 || $height > 80) {
$Image->scaleDown(80);
- $r = Photo::store($Image, local_user(), $visitor, $hash, $filename, $album, 5, $profile, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
+ $r = Photo::store($Image, local_user(), $visitor, $resource_id, $filename, $album, 5, $profile, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
if (!$r) {
Logger::log("photo upload: profile image upload with scale 5 (80x80) failed");
}
if ($width > 48 || $height > 48) {
$Image->scaleDown(48);
- $r = Photo::store($Image, local_user(), $visitor, $hash, $filename, $album, 6, $profile, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
+ $r = Photo::store($Image, local_user(), $visitor, $resource_id, $filename, $album, 6, $profile, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $desc);
if (!$r) {
Logger::log("photo upload: profile image upload with scale 6 (48x48) failed");
}
if (isset($r) && $r) {
// create entry in 'item'-table on new uploads to enable users to comment/like/dislike the photo
if ($photo_id == null && $mediatype == "photo") {
- post_photo_item($hash, $allow_cid, $deny_cid, $allow_gid, $deny_gid, $filetype, $visibility);
+ post_photo_item($resource_id, $allow_cid, $deny_cid, $allow_gid, $deny_gid, $filetype, $visibility);
}
// on success return image data in json/xml format (like /api/friendica/photo does when no scale is given)
- return prepare_photo_data($type, false, $hash);
+ return prepare_photo_data($type, false, $resource_id);
} else {
throw new InternalServerErrorException("image upload failed");
}
/**
* Fetch all comments from a query. Additionally set the newest resharer as thread owner.
*
- * @param $thread_items Database statement with thread posts
+ * @param array $thread_items Database statement with thread posts
+ * @param boolean $pinned Is the item pinned?
+ *
* @return array items with parents and comments
*/
-function conversation_fetch_comments($thread_items) {
+function conversation_fetch_comments($thread_items, $pinned) {
$comments = [];
$parentlines = [];
$lineno = 0;
$parentlines[] = $lineno;
}
+ if ($row['gravity'] == GRAVITY_PARENT) {
+ $row['pinned'] = $pinned;
+ }
+
$comments[] = $row;
$lineno++;
}
$thread_items = Item::selectForUser(local_user(), array_merge(Item::DISPLAY_FIELDLIST, ['contact-uid', 'gravity']), $condition, $params);
- $comments = conversation_fetch_comments($thread_items);
+ $comments = conversation_fetch_comments($thread_items, $parent['pinned'] ?? false);
if (count($comments) != 0) {
$items = array_merge($items, $comments);
}
}
- if (stristr($order, 'received')) {
+ if (stristr($order, 'pinned_received')) {
+ usort($parents, 'sort_thr_pinned_received');
+ } elseif (stristr($order, 'received')) {
usort($parents, 'sort_thr_received');
} elseif (stristr($order, 'commented')) {
usort($parents, 'sort_thr_commented');
return $parents;
}
+/**
+ * @brief usort() callback to sort item arrays by pinned and the received key
+ *
+ * @param array $a
+ * @param array $b
+ * @return int
+ */
+function sort_thr_pinned_received(array $a, array $b)
+{
+ if ($b['pinned'] && !$a['pinned']) {
+ return 1;
+ } elseif (!$b['pinned'] && $a['pinned']) {
+ return -1;
+ }
+
+ return strcmp($b['received'], $a['received']);
+}
+
/**
* @brief usort() callback to sort item arrays by the received key
*
use Friendica\Core\Renderer;
use Friendica\Core\System;
use Friendica\Database\DBA;
-use Friendica\Object\Image;
+use Friendica\Util\Images;
use Friendica\Util\Strings;
/**
function _map_files1($rr)
{
$a = \get_app();
- $types = Image::supportedTypes();
+ $types = Images::supportedTypes();
$ext = $types[$rr['type']];
$filename_e = $rr['filename'];
+++ /dev/null
-<?php
-
-/**
- * Name: Frio Hovercard
- * Description: Hovercard addon for the frio theme
- * Version: 0.1
- * Author: Rabuzarus <https://github.com/rabuzarus>
- * License: GNU AFFERO GENERAL PUBLIC LICENSE (Version 3)
- */
-
-use Friendica\App;
-use Friendica\Core\Config;
-use Friendica\Core\Renderer;
-use Friendica\Core\System;
-use Friendica\Database\DBA;
-use Friendica\Model\Contact;
-use Friendica\Model\GContact;
-use Friendica\Util\Proxy as ProxyUtils;
-use Friendica\Util\Strings;
-
-function hovercard_init(App $a)
-{
- // Just for testing purposes
- $_GET['mode'] = 'minimal';
-}
-
-function hovercard_content()
-{
- $profileurl = $_REQUEST['profileurl'] ?? '';
- $datatype = ($_REQUEST['datatype'] ?? '') ?: 'json';
-
- // Get out if the system doesn't have public access allowed
- if (intval(Config::get('system', 'block_public'))) {
- throw new \Friendica\Network\HTTPException\ForbiddenException();
- }
-
- // Return the raw content of the template. We use this to make templates usable for js functions.
- // Look at hovercard.js (function getHoverCardTemplate()).
- // This part should be moved in its own module. Maybe we could make more templates accessible.
- // (We need to discuss possible security leaks before doing this)
- if ($datatype == 'tpl') {
- $templatecontent = get_template_content('hovercard.tpl');
- echo $templatecontent;
- exit();
- }
-
- // If a contact is connected the url is internally changed to 'redir/CID'. We need the pure url to search for
- // the contact. So we strip out the contact id from the internal url and look in the contact table for
- // the real url (nurl)
- if (strpos($profileurl, 'redir/') === 0) {
- $cid = intval(substr($profileurl, 6));
- $remote_contact = DBA::selectFirst('contact', ['nurl'], ['id' => $cid]);
- $profileurl = $remote_contact['nurl'] ?? '';
- }
-
- $contact = [];
- // if it's the url containing https it should be converted to http
- $nurl = Strings::normaliseLink(GContact::cleanContactUrl($profileurl));
- if (!$nurl) {
- return;
- }
-
- // Search for contact data
- // Look if the local user has got the contact
- if (local_user()) {
- $contact = Contact::getDetailsByURL($nurl, local_user());
- }
-
- // If not then check the global user
- if (!count($contact)) {
- $contact = Contact::getDetailsByURL($nurl);
- }
-
- // Feeds url could have been destroyed through "cleanContactUrl", so we now use the original url
- if (!count($contact) && local_user()) {
- $nurl = Strings::normaliseLink($profileurl);
- $contact = Contact::getDetailsByURL($nurl, local_user());
- }
-
- if (!count($contact)) {
- $nurl = Strings::normaliseLink($profileurl);
- $contact = Contact::getDetailsByURL($nurl);
- }
-
- if (!count($contact)) {
- return;
- }
-
- // Get the photo_menu - the menu if possible contact actions
- if (local_user()) {
- $actions = Contact::photoMenu($contact);
- } else {
- $actions = [];
- }
-
- // Move the contact data to the profile array so we can deliver it to
- $profile = [
- 'name' => $contact['name'],
- 'nick' => $contact['nick'],
- 'addr' => ($contact['addr'] ?? '') ?: $contact['url'],
- 'thumb' => ProxyUtils::proxifyUrl($contact['thumb'], false, ProxyUtils::SIZE_THUMB),
- 'url' => Contact::magicLink($contact['url']),
- 'nurl' => $contact['nurl'], // We additionally store the nurl as identifier
- 'location' => $contact['location'],
- 'gender' => $contact['gender'],
- 'about' => $contact['about'],
- 'network_link' => Strings::formatNetworkName($contact['network'], $contact['url']),
- 'tags' => $contact['keywords'],
- 'bd' => $contact['birthday'] <= DBA::NULL_DATE ? '' : $contact['birthday'],
- 'account_type' => Contact::getAccountType($contact),
- 'actions' => $actions,
- ];
- if ($datatype == 'html') {
- $tpl = Renderer::getMarkupTemplate('hovercard.tpl');
- $o = Renderer::replaceMacros($tpl, [
- '$profile' => $profile,
- ]);
-
- return $o;
- } else {
- System::jsonExit($profile);
- }
-}
-
-/**
- * @brief Get the raw content of a template file
- *
- * @param string $template The name of the template
- * @param string $root Directory of the template
- *
- * @return string|bool Output the raw content if existent, otherwise false
- * @throws Exception
- */
-function get_template_content($template, $root = '')
-{
- // We load the whole template system to get the filename.
- // Maybe we can do it a little bit smarter if I get time.
- $templateEngine = Renderer::getTemplateEngine();
- $template = $templateEngine->getTemplateFile($template, $root);
-
- $filename = $template->filename;
-
- // Get the content of the template file
- if (file_exists($filename)) {
- $content = file_get_contents($filename);
-
- return $content;
- }
-
- return false;
-}
if ($remember_tab) {
// redirect if current selected tab is '/network' and
- // last selected tab is _not_ '/network?order=comment'.
+ // last selected tab is _not_ '/network?order=activity'.
// and this isn't a date query
$tab_baseurls = [
'', //bookmarked
];
$tab_args = [
- 'order=comment', //all
- 'order=post', //postord
- 'conv=1', //conv
- '', //new
- 'star=1', //starred
- 'bmark=1', //bookmarked
+ 'order=activity', //all
+ 'order=post', //postord
+ 'conv=1', //conv
+ '', //new
+ 'star=1', //starred
+ 'bmark=1', //bookmarked
];
$k = array_search('active', $last_sel_tabs);
* Return selected tab from query
*
* urls -> returns
- * '/network' => $no_active = 'active'
- * '/network?order=comment' => $comment_active = 'active'
- * '/network?order=post' => $postord_active = 'active'
+ * '/network' => $no_active = 'active'
+ * '/network?order=activity' => $activity_active = 'active'
+ * '/network?order=post' => $postord_active = 'active'
* '/network?conv=1', => $conv_active = 'active'
- * '/network/new', => $new_active = 'active'
+ * '/network/new', => $new_active = 'active'
* '/network?star=1', => $starred_active = 'active'
- * '/network?bmark=1', => $bookmarked_active = 'active'
+ * '/network?bmark=1', => $bookmarked_active = 'active'
*
* @param App $a
- * @return array ($no_active, $comment_active, $postord_active, $conv_active, $new_active, $starred_active, $bookmarked_active);
+ * @return array ($no_active, $activity_active, $postord_active, $conv_active, $new_active, $starred_active, $bookmarked_active);
*/
function network_query_get_sel_tab(App $a)
{
if ($no_active == 'active' && !empty($_GET['order'])) {
switch($_GET['order']) {
- case 'post' : $postord_active = 'active'; $no_active=''; break;
- case 'comment' : $all_active = 'active'; $no_active=''; break;
+ case 'post' : $postord_active = 'active'; $no_active=''; break;
+ case 'activity' : $all_active = 'active'; $no_active=''; break;
}
}
$star = intval($_GET['star'] ?? 0);
$bmark = intval($_GET['bmark'] ?? 0);
$conv = intval($_GET['conv'] ?? 0);
- $order = Strings::escapeTags(($_GET['order'] ?? '') ?: 'comment');
+ $order = Strings::escapeTags(($_GET['order'] ?? '') ?: 'activity');
$nets = $_GET['nets'] ?? '';
$allowedCids = [];
// item filter tabs
/// @TODO fix this logic, reduce duplication
/// $a->page['content'] .= '<div class="tabs-wrapper">';
- list($no_active, $all_active, $postord_active, $conv_active, $new_active, $starred_active, $bookmarked_active) = network_query_get_sel_tab($a);
+ list($no_active, $all_active, $post_active, $conv_active, $new_active, $starred_active, $bookmarked_active) = network_query_get_sel_tab($a);
- // if no tabs are selected, defaults to comments
+ // if no tabs are selected, defaults to activitys
if ($no_active == 'active') {
$all_active = 'active';
}
// tabs
$tabs = [
[
- 'label' => L10n::t('Commented Order'),
- 'url' => str_replace('/new', '', $cmd) . '?order=comment' . (!empty($_GET['cid']) ? '&cid=' . $_GET['cid'] : ''),
+ 'label' => L10n::t('Latest Activity'),
+ 'url' => str_replace('/new', '', $cmd) . '?order=activity' . (!empty($_GET['cid']) ? '&cid=' . $_GET['cid'] : ''),
'sel' => $all_active,
- 'title' => L10n::t('Sort by Comment Date'),
- 'id' => 'commented-order-tab',
+ 'title' => L10n::t('Sort by latest activity'),
+ 'id' => 'activity-order-tab',
'accesskey' => 'e',
],
[
- 'label' => L10n::t('Posted Order'),
+ 'label' => L10n::t('Latest Posts'),
'url' => str_replace('/new', '', $cmd) . '?order=post' . (!empty($_GET['cid']) ? '&cid=' . $_GET['cid'] : ''),
- 'sel' => $postord_active,
- 'title' => L10n::t('Sort by Post Date'),
- 'id' => 'posted-order-tab',
+ 'sel' => $post_active,
+ 'title' => L10n::t('Sort by post received date'),
+ 'id' => 'post-order-tab',
'accesskey' => 't',
],
];
// save selected tab, but only if not in file mode
if (empty($_GET['file'])) {
PConfig::set(local_user(), 'network.view', 'tab.selected', [
- $all_active, $postord_active, $conv_active, $new_active, $starred_active, $bookmarked_active
+ $all_active, $post_active, $conv_active, $new_active, $starred_active, $bookmarked_active
]);
}
use Friendica\Util\ACLFormatter;
use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Images;
use Friendica\Util\Map;
use Friendica\Util\Security;
use Friendica\Util\Strings;
Logger::log('mod_photos: REQUEST ' . print_r($_REQUEST, true), Logger::DATA);
Logger::log('mod_photos: FILES ' . print_r($_FILES, true), Logger::DATA);
- $phototypes = Image::supportedTypes();
+ $phototypes = Images::supportedTypes();
$can_post = false;
$visitor = 0;
}
if ($type == "") {
- $type = Image::guessType($filename);
+ $type = Images::guessType($filename);
}
Logger::log('photos: upload: received file: ' . $filename . ' as ' . $src . ' ('. $type . ') ' . $filesize . ' bytes', Logger::DEBUG);
$smallest = 0;
- $photo_hash = Photo::newResource();
+ $resource_id = Photo::newResource();
- $r = Photo::store($image, $page_owner_uid, $visitor, $photo_hash, $filename, $album, 0 , 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
+ $r = Photo::store($image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 0 , 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
if (!$r) {
Logger::log('mod/photos.php: photos_post(): image store failed', Logger::DEBUG);
if ($width > 640 || $height > 640) {
$image->scaleDown(640);
- Photo::store($image, $page_owner_uid, $visitor, $photo_hash, $filename, $album, 1, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
+ Photo::store($image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 1, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
$smallest = 1;
}
if ($width > 320 || $height > 320) {
$image->scaleDown(320);
- Photo::store($image, $page_owner_uid, $visitor, $photo_hash, $filename, $album, 2, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
+ Photo::store($image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 2, 0, $str_contact_allow, $str_group_allow, $str_contact_deny, $str_group_deny);
$smallest = 2;
}
$arr['parent-uri'] = $uri;
$arr['type'] = 'photo';
$arr['wall'] = 1;
- $arr['resource-id'] = $photo_hash;
+ $arr['resource-id'] = $resource_id;
$arr['contact-id'] = $owner_record['id'];
$arr['owner-name'] = $owner_record['name'];
$arr['owner-link'] = $owner_record['url'];
$arr['visible'] = $visible;
$arr['origin'] = 1;
- $arr['body'] = '[url=' . System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $photo_hash . ']'
- . '[img]' . System::baseUrl() . "/photo/{$photo_hash}-{$smallest}.".$image->getExt() . '[/img]'
+ $arr['body'] = '[url=' . System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $resource_id . ']'
+ . '[img]' . System::baseUrl() . "/photo/{$resource_id}-{$smallest}.".$image->getExt() . '[/img]'
. '[/url]';
$item_id = Item::insert($arr);
return;
}
- $phototypes = Image::supportedTypes();
+ $phototypes = Images::supportedTypes();
$_SESSION['photo_return'] = $a->cmd;
$tabs[] = [
'label' => L10n::t('Export personal data'),
- 'url' => 'uexport',
- 'selected' => (($a->argc == 1) && ($a->argv[0] === 'uexport')?'active':''),
+ 'url' => 'settings/userexport',
+ 'selected' => (($a->argc > 1) && ($a->argv[1] === 'userexport')?'active':''),
'accesskey' => 'e',
];
BaseModule::checkFormSecurityTokenRedirectOnError('/settings', 'settings');
+ // Import Contacts from CSV file
+ if (!empty($_POST['importcontact-submit'])) {
+ if (isset($_FILES['importcontact-filename'])) {
+ // was there an error
+ if ($_FILES['importcontact-filename']['error'] > 0) {
+ Logger::notice('Contact CSV file upload error');
+ info(L10n::t('Contact CSV file upload error'));
+ } else {
+ $csvArray = array_map('str_getcsv', file($_FILES['importcontact-filename']['tmp_name']));
+ // import contacts
+ foreach ($csvArray as $csvRow) {
+ // The 1st row may, or may not contain the headers of the table
+ // We expect the 1st field of the row to contain either the URL
+ // or the handle of the account, therefore we check for either
+ // "http" or "@" to be present in the string.
+ // All other fields from the row will be ignored
+ if ((strpos($csvRow[0],'@') !== false) || (strpos($csvRow[0],'http') !== false)) {
+ $arr = Contact::createFromProbe($_SESSION['uid'], $csvRow[0], '', false);
+ }
+ }
+ info(L10n::t('Importing Contacts done'));
+ // delete temp file
+ unlink($filename);
+ }
+ }
+ }
+
if (!empty($_POST['resend_relocate'])) {
Worker::add(PRIORITY_HIGH, 'Notifier', Delivery::RELOCATION, local_user());
info(L10n::t("Relocate message has been send to your contacts"));
$fields = ['username' => $username, 'email' => $email, 'timezone' => $timezone,
'allow_cid' => $str_contact_allow, 'allow_gid' => $str_group_allow, 'deny_cid' => $str_contact_deny, 'deny_gid' => $str_group_deny,
- 'notify-flags' => $notify, 'page-flags' => $notify, 'account-type' => $account_type, 'default-location' => $defloc,
+ 'notify-flags' => $notify, 'page-flags' => $page_flags, 'account-type' => $account_type, 'default-location' => $defloc,
'allow_location' => $allow_location, 'maxreq' => $maxreq, 'expire' => $expire, 'def_gid' => $def_gid, 'blockwall' => $blockwall,
- 'hidewall' => $hide_wall, 'blocktags' => $blocktags, 'unkmail' => $unkmail, 'cntunkmail' => $cntunkmail, 'language' => $language];
+ 'hidewall' => $hidewall, 'blocktags' => $blocktags, 'unkmail' => $unkmail, 'cntunkmail' => $cntunkmail, 'language' => $language];
if ($delete_openid) {
$fields['openid'] = '';
'$h_descadvn' => L10n::t('Change the behaviour of this account for special situations'),
'$pagetype' => $pagetype,
+ '$importcontact' => L10n::t('Import Contacts'),
+ '$importcontact_text' => L10n::t('Upload a CSV file that contains the handle of your followed accounts in the first column you exported from the old account.'),
+ '$importcontact_button' => L10n::t('Upload File'),
+ '$importcontact_maxsize' => Config::get('system', 'max_csv_file_size', 30720),
'$relocate' => L10n::t('Relocate'),
'$relocate_text' => L10n::t("If you have moved this profile from another server, and some of your contacts don't receive your updates, try pushing this button."),
'$relocate_button' => L10n::t("Resend relocate message to contacts"),
+++ /dev/null
-<?php
-/**
- * @file mod/uexport.php
- */
-
-use Friendica\App;
-use Friendica\Core\Hook;
-use Friendica\Core\L10n;
-use Friendica\Core\Renderer;
-use Friendica\Core\System;
-use Friendica\Database\DBA;
-use Friendica\Database\DBStructure;
-
-function uexport_init(App $a) {
- /// @todo Don't forget to move this global field as static field in src/Modules
- global $dbStructure;
-
- if (!local_user()) {
- exit();
- }
-
- require_once("mod/settings.php");
- settings_init($a);
-
- $dbStructure = DBStructure::definition($a->getBasePath());
-}
-
-function uexport_content(App $a) {
-
- if ($a->argc > 1) {
- header("Content-type: application/json");
- header('Content-Disposition: attachment; filename="' . $a->user['nickname'] . '.' . $a->argv[1] . '"');
- switch ($a->argv[1]) {
- case "backup":
- uexport_all($a);
- exit();
- break;
- case "account":
- uexport_account($a);
- exit();
- break;
- default:
- exit();
- }
- }
-
- /**
- * options shown on "Export personal data" page
- * list of array( 'link url', 'link text', 'help text' )
- */
- $options = [
- ['uexport/account', L10n::t('Export account'), L10n::t('Export your account info and contacts. Use this to make a backup of your account and/or to move it to another server.')],
- ['uexport/backup', L10n::t('Export all'), L10n::t("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 \x28photos are not exported\x29")],
- ];
- Hook::callAll('uexport_options', $options);
-
- $tpl = Renderer::getMarkupTemplate("uexport.tpl");
- return Renderer::replaceMacros($tpl, [
- '$title' => L10n::t('Export personal data'),
- '$options' => $options
- ]);
-}
-
-function _uexport_multirow($query) {
- global $dbStructure;
-
- preg_match("/\s+from\s+`?([a-z\d_]+)`?/i", $query, $match);
- $table = $match[1];
-
- $result = [];
- $r = q($query);
- if (DBA::isResult($r)) {
- foreach ($r as $rr) {
- $p = [];
- foreach ($rr as $k => $v) {
- switch ($dbStructure[$table]['fields'][$k]['type']) {
- case 'datetime':
- $p[$k] = $v ?? DBA::NULL_DATETIME;
- break;
- default:
- $p[$k] = $v;
- break;
- }
- }
- $result[] = $p;
- }
- }
- return $result;
-}
-
-function _uexport_row($query) {
- global $dbStructure;
-
- preg_match("/\s+from\s+`?([a-z\d_]+)`?/i", $query, $match);
- $table = $match[1];
-
- $result = [];
- $r = q($query);
- if (DBA::isResult($r)) {
-
- foreach ($r as $rr) {
- foreach ($rr as $k => $v) {
- switch ($dbStructure[$table]['fields'][$k]['type']) {
- case 'datetime':
- $result[$k] = $v ?? DBA::NULL_DATETIME;
- break;
- default:
- $result[$k] = $v;
- break;
- }
- }
- }
- }
- return $result;
-}
-
-function uexport_account($a) {
-
- $user = _uexport_row(
- sprintf("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval(local_user()))
- );
-
- $contact = _uexport_multirow(
- sprintf("SELECT * FROM `contact` WHERE `uid` = %d ", intval(local_user()))
- );
-
-
- $profile = _uexport_multirow(
- sprintf("SELECT * FROM `profile` WHERE `uid` = %d ", intval(local_user()))
- );
-
- $photo = _uexport_multirow(
- sprintf("SELECT * FROM `photo` WHERE uid = %d AND profile = 1", intval(local_user()))
- );
- foreach ($photo as &$p) {
- $p['data'] = bin2hex($p['data']);
- }
-
- $pconfig = _uexport_multirow(
- sprintf("SELECT * FROM `pconfig` WHERE uid = %d", intval(local_user()))
- );
-
- $group = _uexport_multirow(
- sprintf("SELECT * FROM `group` WHERE uid = %d", intval(local_user()))
- );
-
- $group_member = _uexport_multirow(
- sprintf("SELECT `group_member`.`gid`, `group_member`.`contact-id` FROM `group_member` INNER JOIN `group` ON `group`.`id` = `group_member`.`gid` WHERE `group`.`uid` = %d", intval(local_user()))
- );
-
- $output = [
- 'version' => FRIENDICA_VERSION,
- 'schema' => DB_UPDATE_VERSION,
- 'baseurl' => System::baseUrl(),
- 'user' => $user,
- 'contact' => $contact,
- 'profile' => $profile,
- 'photo' => $photo,
- 'pconfig' => $pconfig,
- 'group' => $group,
- 'group_member' => $group_member,
- ];
-
- echo json_encode($output, JSON_PARTIAL_OUTPUT_ON_ERROR);
-}
-
-/**
- * echoes account data and items as separated json, one per line
- *
- * @param App $a
- * @throws Exception
- */
-function uexport_all(App $a) {
-
- uexport_account($a);
- echo "\n";
-
- $total = 0;
- $r = q("SELECT count(*) as `total` FROM `item` WHERE `uid` = %d ",
- intval(local_user())
- );
- if (DBA::isResult($r)) {
- $total = $r[0]['total'];
- }
- // chunk the output to avoid exhausting memory
-
- for ($x = 0; $x < $total; $x += 500) {
- $r = q("SELECT * FROM `item` WHERE `uid` = %d LIMIT %d, %d",
- intval(local_user()),
- intval($x),
- intval(500)
- );
-
- $output = ['item' => $r];
- echo json_encode($output, JSON_PARTIAL_OUTPUT_ON_ERROR). "\n";
- }
-}
echo "<section>";
if ($_GET["force"] == 1) {
- $text = Contact::content(true);
+ $text = Contact::content([], true);
} else {
$text = '';
}
* on the client side and then swap the image back.
*/
- $text = Profile::content($profile_uid);
+ $text = Profile::content([], $profile_uid);
if (PConfig::get(local_user(), "system", "bandwidth_saver")) {
$replace = "<br />".L10n::t("[Embedded content - reload page to view]")."<br />";
*/
use Friendica\App;
+use Friendica\Core\Config;
use Friendica\Core\L10n;
use Friendica\Core\Logger;
-use Friendica\Core\System;
use Friendica\Core\Session;
-use Friendica\Core\Config;
+use Friendica\Core\System;
use Friendica\Database\DBA;
-use Friendica\Model\Contact;
use Friendica\Model\Photo;
use Friendica\Model\User;
use Friendica\Object\Image;
+use Friendica\Util\Images;
use Friendica\Util\Strings;
function wall_upload_post(App $a, $desktopmode = true)
}
if ($filetype == "") {
- $filetype = Image::guessType($filename);
+ $filetype = Images::guessType($filename);
}
// If there is a temp name, then do a manual check
$width = $Image->getWidth();
$height = $Image->getHeight();
- $hash = Photo::newResource();
+ $resource_id = Photo::newResource();
$smallest = 0;
$defperm = '<' . $default_cid . '>';
- $r = Photo::store($Image, $page_owner_uid, $visitor, $hash, $filename, $album, 0, 0, $defperm);
+ $r = Photo::store($Image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 0, 0, $defperm);
if (!$r) {
$msg = L10n::t('Image upload failed.');
if ($width > 640 || $height > 640) {
$Image->scaleDown(640);
- $r = Photo::store($Image, $page_owner_uid, $visitor, $hash, $filename, $album, 1, 0, $defperm);
+ $r = Photo::store($Image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 1, 0, $defperm);
if ($r) {
$smallest = 1;
}
if ($width > 320 || $height > 320) {
$Image->scaleDown(320);
- $r = Photo::store($Image, $page_owner_uid, $visitor, $hash, $filename, $album, 2, 0, $defperm);
+ $r = Photo::store($Image, $page_owner_uid, $visitor, $resource_id, $filename, $album, 2, 0, $defperm);
if ($r && ($smallest == 0)) {
$smallest = 2;
}
$r = q("SELECT `id`, `datasize`, `width`, `height`, `type` FROM `photo`
WHERE `resource-id` = '%s'
ORDER BY `width` DESC LIMIT 1",
- $hash
+ $resource_id
);
if (!$r) {
if ($r_json) {
$picture["width"] = $r[0]["width"];
$picture["height"] = $r[0]["height"];
$picture["type"] = $r[0]["type"];
- $picture["albumpage"] = System::baseUrl() . '/photos/' . $page_owner_nick . '/image/' . $hash;
- $picture["picture"] = System::baseUrl() . "/photo/{$hash}-0." . $Image->getExt();
- $picture["preview"] = System::baseUrl() . "/photo/{$hash}-{$smallest}." . $Image->getExt();
+ $picture["albumpage"] = System::baseUrl() . '/photos/' . $page_owner_nick . '/image/' . $resource_id;
+ $picture["picture"] = System::baseUrl() . "/photo/{$resource_id}-0." . $Image->getExt();
+ $picture["preview"] = System::baseUrl() . "/photo/{$resource_id}-{$smallest}." . $Image->getExt();
if ($r_json) {
echo json_encode(['picture' => $picture]);
exit();
}
- echo "\n\n" . '[url=' . System::baseUrl() . '/photos/' . $page_owner_nick . '/image/' . $hash . '][img]' . System::baseUrl() . "/photo/{$hash}-{$smallest}.".$Image->getExt()."[/img][/url]\n\n";
+ echo "\n\n" . '[url=' . System::baseUrl() . '/photos/' . $page_owner_nick . '/image/' . $resource_id . '][img]' . System::baseUrl() . "/photo/{$resource_id}-{$smallest}.".$Image->getExt()."[/img][/url]\n\n";
exit();
// NOTREACHED
}
$queryString = '';
if (!empty($server['QUERY_STRING']) && strpos($server['QUERY_STRING'], 'pagename=') === 0) {
- $queryString = substr($server['QUERY_STRING'], 9);
+ $queryString = urldecode(substr($server['QUERY_STRING'], 9));
} elseif (!empty($server['QUERY_STRING']) && strpos($server['QUERY_STRING'], 'q=') === 0) {
- $queryString = substr($server['QUERY_STRING'], 2);
+ $queryString = urldecode(substr($server['QUERY_STRING'], 2));
}
// eventually strip ZRL
*/
private $module_class;
+ /**
+ * @var array The module parameters
+ */
+ private $module_parameters;
+
/**
* @var bool true, if the module is a backend module
*/
return $this->module_class;
}
+ /**
+ * @return array The module parameters extracted from the route
+ */
+ public function getParameters()
+ {
+ return $this->module_parameters;
+ }
+
/**
* @return bool True, if the current module is a backend module
* @see Module::BACKEND_MODULES for a list
return $this->isBackend;
}
- public function __construct(string $module = self::DEFAULT, string $moduleClass = self::DEFAULT_CLASS, bool $isBackend = false, bool $printNotAllowedAddon = false)
+ public function __construct(string $module = self::DEFAULT, string $moduleClass = self::DEFAULT_CLASS, array $moduleParameters = [], bool $isBackend = false, bool $printNotAllowedAddon = false)
{
$this->module = $module;
$this->module_class = $moduleClass;
+ $this->module_parameters = $moduleParameters;
$this->isBackend = $isBackend;
$this->printNotAllowedAddon = $printNotAllowedAddon;
}
$isBackend = in_array($module, Module::BACKEND_MODULES);;
- return new Module($module, $this->module_class, $isBackend, $this->printNotAllowedAddon);
+ return new Module($module, $this->module_class, [], $isBackend, $this->printNotAllowedAddon);
}
/**
$printNotAllowedAddon = false;
$module_class = null;
+ $module_parameters = [];
/**
* ROUTING
*
**/
try {
$module_class = $router->getModuleClass($args->getCommand());
+ $module_parameters = $router->getModuleParameters();
} catch (MethodNotAllowedException $e) {
$module_class = MethodNotAllowed::class;
} catch (NotFoundException $e) {
$module_class = $module_class ?: PageNotFound::class;
}
- return new Module($this->module, $module_class, $this->isBackend, $printNotAllowedAddon);
+ return new Module($this->module, $module_class, $module_parameters, $this->isBackend, $printNotAllowedAddon);
}
/**
Core\Hook::callAll($this->module . '_mod_init', $placeholder);
- call_user_func([$this->module_class, 'init']);
+ call_user_func([$this->module_class, 'init'], $this->module_parameters);
// "rawContent" is especially meant for technical endpoints.
// This endpoint doesn't need any theme initialization or other comparable stuff.
- call_user_func([$this->module_class, 'rawContent']);
+ call_user_func([$this->module_class, 'rawContent'], $this->module_parameters);
if ($server['REQUEST_METHOD'] === 'POST') {
Core\Hook::callAll($this->module . '_mod_post', $post);
- call_user_func([$this->module_class, 'post']);
+ call_user_func([$this->module_class, 'post'], $this->module_parameters);
}
Core\Hook::callAll($this->module . '_mod_afterpost', $placeholder);
- call_user_func([$this->module_class, 'afterpost']);
+ call_user_func([$this->module_class, 'afterpost'], $this->module_parameters);
}
}
$arr = ['content' => $content];
Hook::callAll($moduleClass . '_mod_content', $arr);
$content = $arr['content'];
- $arr = ['content' => call_user_func([$moduleClass, 'content'])];
+ $arr = ['content' => call_user_func([$moduleClass, 'content'], $module->getParameters())];
Hook::callAll($moduleClass . '_mod_aftercontent', $arr);
$content .= $arr['content'];
} catch (HTTPException $e) {
*/
private $httpMethod;
+ /**
+ * @var array Module parameters
+ */
+ private $parameters = [];
+
/**
* @param array $server The $_SERVER variable
* @param RouteCollector|null $routeCollector Optional the loaded Route collector
*
* @throws HTTPException\InternalServerErrorException In case of invalid configs
*/
- public function addRoutes(array $routes)
+ public function loadRoutes(array $routes)
{
$routeCollector = (isset($this->routeCollector) ?
$this->routeCollector :
new RouteCollector(new Std(), new GroupCountBased()));
+ $this->addRoutes($routeCollector, $routes);
+
+ $this->routeCollector = $routeCollector;
+
+ return $this;
+ }
+
+ private function addRoutes(RouteCollector $routeCollector, array $routes)
+ {
foreach ($routes as $route => $config) {
if ($this->isGroup($config)) {
$this->addGroup($route, $config, $routeCollector);
throw new HTTPException\InternalServerErrorException("Wrong route config for route '" . print_r($route, true) . "'");
}
}
-
- $this->routeCollector = $routeCollector;
-
- return $this;
}
/**
private function addGroup(string $groupRoute, array $routes, RouteCollector $routeCollector)
{
$routeCollector->addGroup($groupRoute, function (RouteCollector $routeCollector) use ($routes) {
- foreach ($routes as $route => $config) {
- if ($this->isGroup($config)) {
- $this->addGroup($route, $config, $routeCollector);
- } elseif ($this->isRoute($config)) {
- $routeCollector->addRoute($config[1], $route, $config[0]);
- }else {
- throw new HTTPException\InternalServerErrorException("Wrong route config for route '" . print_r($route, true) . "'");
- }
- }
+ $this->addRoutes($routeCollector, $routes);
});
}
$cmd = '/' . ltrim($cmd, '/');
- $dispatcher = new \FastRoute\Dispatcher\GroupCountBased($this->routeCollector->getData());
+ $dispatcher = new Dispatcher\GroupCountBased($this->routeCollector->getData());
$moduleClass = null;
+ $this->parameters = [];
$routeInfo = $dispatcher->dispatch($this->httpMethod, $cmd);
if ($routeInfo[0] === Dispatcher::FOUND) {
$moduleClass = $routeInfo[1];
+ $this->parameters = $routeInfo[2];
} elseif ($routeInfo[0] === Dispatcher::METHOD_NOT_ALLOWED) {
throw new HTTPException\MethodNotAllowedException(L10n::t('Method not allowed for this module. Allowed method(s): %s', implode(', ', $routeInfo[1])));
} else {
return $moduleClass;
}
+
+ /**
+ * Returns the module parameters.
+ *
+ * @return array parameters
+ */
+ public function getModuleParameters()
+ {
+ return $this->parameters;
+ }
}
* Extend this method if you need to do any shared processing before both
* content() or post()
*/
- public static function init()
+ public static function init(array $parameters = [])
{
}
* Extend this method if the module is supposed to return communication data,
* e.g. from protocol implementations.
*/
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
// echo '';
// exit;
*
* @return string
*/
- public static function content()
+ public static function content(array $parameters = [])
{
$o = '';
* Extend this method if the module is supposed to process POST requests.
* Doesn't display any content
*/
- public static function post()
+ public static function post(array $parameters = [])
{
// $a = self::getApp();
// $a->internalRedirect('module');
*
* Unknown purpose
*/
- public static function afterpost()
+ public static function afterpost(array $parameters = [])
{
-
}
/*
$first = true;
foreach (FileTag::fileToArray($item['file'] ?? '', 'category') as $savedFolderName) {
+ if (!empty($item['author-link'])) {
+ $url = $item['author-link'] . "?category=" . rawurlencode($savedFolderName);
+ } else {
+ $url = '#';
+ }
$categories[] = [
'name' => $savedFolderName,
- 'url' => "#",
+ 'url' => $url,
'removeurl' => ((local_user() == $item['uid']) ? 'filerm/' . $item['id'] . '?f=&cat=' . rawurlencode($savedFolderName) : ""),
'first' => $first,
'last' => false
use Friendica\Network\Probe;
use Friendica\Object\Image;
use Friendica\Protocol\Activity;
+use Friendica\Util\Images;
use Friendica\Util\Map;
use Friendica\Util\Network;
use Friendica\Util\ParseUrl;
if (preg_match("/\[img\](.*?)\[\/img\]/ism", $attacheddata, $matches)) {
- $picturedata = Image::getInfoFromURL($matches[1]);
+ $picturedata = Images::getInfoFromURLCached($matches[1]);
if ($picturedata) {
if (($picturedata[0] >= 500) && ($picturedata[0] >= $picturedata[1])) {
$post['preview'] = $pictures[0][2];
$post['text'] = trim(str_replace($pictures[0][0], '', $body));
} else {
- $imgdata = Image::getInfoFromURL($pictures[0][1]);
+ $imgdata = Images::getInfoFromURLCached($pictures[0][1]);
if ($imgdata && substr($imgdata['mime'], 0, 6) == 'image/') {
$post['type'] = 'photo';
$post['image'] = $pictures[0][1];
}
// guess mimetype from headers or filename
- $type = Image::guessType($mtch[1], true);
+ $type = Images::guessType($mtch[1], true);
if ($i) {
$Image = new Image($i, $type);
foreach (FileTag::fileToArray($saved) as $savedFolderName) {
$terms[] = ['ref' => $savedFolderName, 'name' => $savedFolderName];
}
+
+ usort($terms, function ($a, $b) {
+ return strcmp($a['name'], $b['name']);
+ });
return self::filter(
'file',
use Friendica\Core\Config\Cache\ConfigCache;
use Friendica\Database\Database;
use Friendica\Database\DBStructure;
-use Friendica\Object\Image;
+use Friendica\Util\Images;
use Friendica\Util\Network;
use Friendica\Util\Strings;
if (class_exists('Imagick')) {
$imagick = true;
- $supported = Image::supportedTypes();
+ $supported = Images::supportedTypes();
if (array_key_exists('image/gif', $supported)) {
$gif = true;
}
require_once $file_path;
}
- public static function init()
+ public static function init(array $parameters = [])
{
- self::runModuleFunction('init');
+ self::runModuleFunction('init', $parameters);
}
- public static function content()
+ public static function content(array $parameters = [])
{
- return self::runModuleFunction('content');
+ return self::runModuleFunction('content', $parameters);
}
- public static function post()
+ public static function post(array $parameters = [])
{
- self::runModuleFunction('post');
+ self::runModuleFunction('post', $parameters);
}
- public static function afterpost()
+ public static function afterpost(array $parameters = [])
{
- self::runModuleFunction('afterpost');
+ self::runModuleFunction('afterpost', $parameters);
}
/**
* @return string
* @throws \Exception
*/
- private static function runModuleFunction($function_suffix)
+ private static function runModuleFunction($function_suffix, array $parameters = [])
{
$function_name = static::$moduleName . '_' . $function_suffix;
$a = self::getApp();
return $function_name($a);
} else {
- return parent::{$function_suffix}();
+ return parent::{$function_suffix}($parameters);
}
}
}
use Friendica\Protocol\OStatus;
use Friendica\Protocol\Salmon;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Images;
use Friendica\Util\Network;
use Friendica\Util\Strings;
}
// Creating the path to the avatar, beginning with the file suffix
- $types = Image::supportedTypes();
+ $types = Images::supportedTypes();
if (isset($types[$avatar['type']])) {
$file_suffix = $types[$avatar['type']];
}
$ssl_url = str_replace('http://', 'https://', $url);
+ $nurl = Strings::normaliseLink($url);
+
// Fetch contact data from the contact table for the given user
$s = DBA::p("SELECT `id`, `id` AS `cid`, 0 AS `gid`, 0 AS `zid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
- `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, `self`
- FROM `contact` WHERE `nurl` = ? AND `uid` = ?", Strings::normaliseLink($url), $uid);
+ `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, `self`, `rel`, `pending`
+ FROM `contact` WHERE `nurl` = ? AND `uid` = ?", $nurl, $uid);
$r = DBA::toArray($s);
// Fetch contact data from the contact table for the given user, checking with the alias
if (!DBA::isResult($r)) {
$s = DBA::p("SELECT `id`, `id` AS `cid`, 0 AS `gid`, 0 AS `zid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
- `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, `self`
- FROM `contact` WHERE `alias` IN (?, ?, ?) AND `uid` = ?", Strings::normaliseLink($url), $url, $ssl_url, $uid);
+ `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, `self`, `rel`, `pending`
+ FROM `contact` WHERE `alias` IN (?, ?, ?) AND `uid` = ?", $nurl, $url, $ssl_url, $uid);
$r = DBA::toArray($s);
}
// Fetch the data from the contact table with "uid=0" (which is filled automatically)
if (!DBA::isResult($r)) {
$s = DBA::p("SELECT `id`, 0 AS `cid`, `id` AS `zid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
- `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, 0 AS `self`
- FROM `contact` WHERE `nurl` = ? AND `uid` = 0", Strings::normaliseLink($url));
+ `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, 0 AS `self`, `rel`, `pending`
+ FROM `contact` WHERE `nurl` = ? AND `uid` = 0", $nurl);
$r = DBA::toArray($s);
}
// Fetch the data from the contact table with "uid=0" (which is filled automatically) - checked with the alias
if (!DBA::isResult($r)) {
$s = DBA::p("SELECT `id`, 0 AS `cid`, `id` AS `zid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
- `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, 0 AS `self`
- FROM `contact` WHERE `alias` IN (?, ?, ?) AND `uid` = 0", Strings::normaliseLink($url), $url, $ssl_url);
+ `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, 0 AS `self`, `rel`, `pending`
+ FROM `contact` WHERE `alias` IN (?, ?, ?) AND `uid` = 0", $nurl, $url, $ssl_url);
$r = DBA::toArray($s);
}
// Fetch the data from the gcontact table
if (!DBA::isResult($r)) {
$s = DBA::p("SELECT 0 AS `id`, 0 AS `cid`, `id` AS `gid`, 0 AS `zid`, 0 AS `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, '' AS `xmpp`,
- `keywords`, `gender`, `photo`, `photo` AS `thumb`, `photo` AS `micro`, 0 AS `forum`, 0 AS `prv`, `community`, `contact-type`, `birthday`, 0 AS `self`
- FROM `gcontact` WHERE `nurl` = ?", Strings::normaliseLink($url));
+ `keywords`, `gender`, `photo`, `photo` AS `thumb`, `photo` AS `micro`, 0 AS `forum`, 0 AS `prv`, `community`, `contact-type`, `birthday`, 0 AS `self`, 2 AS `rel`, 0 AS `pending`
+ FROM `gcontact` WHERE `nurl` = ?", $nurl);
$r = DBA::toArray($s);
}
// Fetch contact data from the contact table for the given user
$r = q("SELECT `id`, `id` AS `cid`, 0 AS `gid`, 0 AS `zid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
- `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, `self`
+ `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, `self`, `rel`, `pending`
FROM `contact` WHERE `addr` = '%s' AND `uid` = %d AND NOT `deleted`",
DBA::escape($addr),
intval($uid)
// Fetch the data from the contact table with "uid=0" (which is filled automatically)
if (!DBA::isResult($r)) {
$r = q("SELECT `id`, 0 AS `cid`, `id` AS `zid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`,
- `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, 0 AS `self`
+ `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, 0 AS `self`, `rel`, `pending`
FROM `contact` WHERE `addr` = '%s' AND `uid` = 0 AND NOT `deleted`",
DBA::escape($addr)
);
// Fetch the data from the gcontact table
if (!DBA::isResult($r)) {
$r = q("SELECT 0 AS `id`, 0 AS `cid`, `id` AS `gid`, 0 AS `zid`, 0 AS `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, '' AS `xmpp`,
- `keywords`, `gender`, `photo`, `photo` AS `thumb`, `photo` AS `micro`, `community` AS `forum`, 0 AS `prv`, `community`, `contact-type`, `birthday`, 0 AS `self`
+ `keywords`, `gender`, `photo`, `photo` AS `thumb`, `photo` AS `micro`, `community` AS `forum`, 0 AS `prv`, `community`, `contact-type`, `birthday`, 0 AS `self`, 2 AS `rel`, 0 AS `pending`
FROM `gcontact` WHERE `addr` = '%s'",
DBA::escape($addr)
);
$contact_drop_link = System::baseUrl() . '/contact/' . $contact['id'] . '/drop?confirm=1';
}
+ $follow_link = '';
+ $unfollow_link = '';
+ if (in_array($contact['network'], Protocol::NATIVE_SUPPORT)) {
+ if ($contact['uid'] && in_array($contact['rel'], [self::SHARING, self::FRIEND])) {
+ $unfollow_link = 'unfollow?url=' . urlencode($contact['url']);
+ } elseif(!$contact['pending']) {
+ $follow_link = 'follow?url=' . urlencode($contact['url']);
+ }
+ }
+
/**
* Menu array:
* "name" => [ "Label", "link", (bool)Should the link opened in a new tab? ]
*/
if (empty($contact['uid'])) {
- $connlnk = 'follow/?url=' . $contact['url'];
$menu = [
- 'profile' => [L10n::t('View Profile'), $profile_link, true],
- 'network' => [L10n::t('Network Posts'), $posts_link, false],
- 'edit' => [L10n::t('View Contact'), $contact_url, false],
- 'follow' => [L10n::t('Connect/Follow'), $connlnk, true],
+ 'profile' => [L10n::t('View Profile') , $profile_link , true],
+ 'network' => [L10n::t('Network Posts') , $posts_link , false],
+ 'edit' => [L10n::t('View Contact') , $contact_url , false],
+ 'follow' => [L10n::t('Connect/Follow'), $follow_link , true],
+ 'unfollow'=> [L10n::t('UnFollow') , $unfollow_link, true],
];
} else {
$menu = [
- 'status' => [L10n::t('View Status'), $status_link, true],
- 'profile' => [L10n::t('View Profile'), $profile_link, true],
- 'photos' => [L10n::t('View Photos'), $photos_link, true],
- 'network' => [L10n::t('Network Posts'), $posts_link, false],
- 'edit' => [L10n::t('View Contact'), $contact_url, false],
- 'drop' => [L10n::t('Drop Contact'), $contact_drop_link, false],
- 'pm' => [L10n::t('Send PM'), $pm_url, false],
- 'poke' => [L10n::t('Poke'), $poke_link, false],
+ 'status' => [L10n::t('View Status') , $status_link , true],
+ 'profile' => [L10n::t('View Profile') , $profile_link , true],
+ 'photos' => [L10n::t('View Photos') , $photos_link , true],
+ 'network' => [L10n::t('Network Posts') , $posts_link , false],
+ 'edit' => [L10n::t('View Contact') , $contact_url , false],
+ 'drop' => [L10n::t('Drop Contact') , $contact_drop_link, false],
+ 'pm' => [L10n::t('Send PM') , $pm_url , false],
+ 'poke' => [L10n::t('Poke') , $poke_link , false],
+ 'follow' => [L10n::t('Connect/Follow'), $follow_link , true],
+ 'unfollow'=> [L10n::t('UnFollow') , $unfollow_link , true],
];
if (!empty($contact['pending'])) {
$hidden = (($protocol === Protocol::MAIL) ? 1 : 0);
- $pending = in_array($protocol, [Protocol::ACTIVITYPUB]);
+ $pending = false;
+ if ($protocol == Protocol::ACTIVITYPUB) {
+ $apcontact = APContact::getByURL($url, false);
+ if (isset($apcontact['manually-approve'])) {
+ $pending = (bool)$apcontact['manually-approve'];
+ }
+ }
if (in_array($protocol, [Protocol::MAIL, Protocol::DIASPORA, Protocol::ACTIVITYPUB])) {
$writeable = 1;
'author-id', 'author-link', 'author-name', 'author-avatar', 'author-network',
'owner-id', 'owner-link', 'owner-name', 'owner-avatar', 'owner-network',
'contact-id', 'contact-uid', 'contact-link', 'contact-name', 'contact-avatar',
- 'writable', 'self', 'cid', 'alias',
+ 'writable', 'self', 'cid', 'alias', 'pinned',
'event-id', 'event-created', 'event-edited', 'event-start', 'event-finish',
'event-summary', 'event-desc', 'event-location', 'event-type',
'event-nofinish', 'event-adjust', 'event-ignore', 'event-id',
return self::$legacy_mode;
}
+ /**
+ * Set the pinned state of an item
+ *
+ * @param integer $iid Item ID
+ * @param integer $uid User ID
+ * @param boolean $pinned Pinned state
+ */
+ public static function setPinned(int $iid, int $uid, bool $pinned)
+ {
+ DBA::update('user-item', ['pinned' => $pinned], ['iid' => $iid, 'uid' => $uid], true);
+ }
+
+ /**
+ * Get the pinned state
+ *
+ * @param integer $iid Item ID
+ * @param integer $uid User ID
+ *
+ * @return boolean pinned state
+ */
+ public static function getPinned(int $iid, int $uid)
+ {
+ $useritem = DBA::selectFirst('user-item', ['pinned'], ['iid' => $iid, 'uid' => $uid]);
+ if (!DBA::isResult($useritem)) {
+ return false;
+ }
+ return (bool)$useritem['pinned'];
+ }
+
+ /**
+ * @brief Select pinned rows from the item table for a given user
+ *
+ * @param integer $uid User ID
+ * @param array $selected Array of selected fields, empty for all
+ * @param array $condition Array of fields for condition
+ * @param array $params Array of several parameters
+ *
+ * @return boolean|object
+ * @throws \Exception
+ */
+ public static function selectPinned(int $uid, array $selected = [], array $condition = [], $params = [])
+ {
+ $useritems = DBA::select('user-item', ['iid'], ['uid' => $uid, 'pinned' => true]);
+ if (!DBA::isResult($useritems)) {
+ return $useritems;
+ }
+
+ $pinned = [];
+ while ($useritem = self::fetch($useritems)) {
+ $pinned[] = $useritem['iid'];
+ }
+ DBA::close($useritems);
+
+ if (empty($pinned)) {
+ return [];
+ }
+
+ if (empty($condition) || !is_array($condition)) {
+ $condition = ['iid' => $pinned];
+ } else {
+ reset($condition);
+ $first_key = key($condition);
+ if (!is_int($first_key)) {
+ $condition['iid'] = $pinned;
+ } else {
+ $values_string = substr(str_repeat("?, ", count($pinned)), 0, -2);
+ $condition[0] = '(' . $condition[0] . ") AND `iid` IN (" . $values_string . ")";
+ $condition = array_merge($condition, $pinned);
+ }
+ }
+
+ return self::selectThreadForUser($uid, $selected, $condition, $params);
+ }
+
/**
* @brief returns an activity index from an activity string
*
'iaid' => 'internal-iaid'];
if ($usermode) {
- $fields['user-item'] = ['ignored' => 'internal-user-ignored'];
+ $fields['user-item'] = ['pinned', 'ignored' => 'internal-user-ignored'];
}
$fields['item-activity'] = ['activity', 'activity' => 'internal-activity'];
use Friendica\Database\DBStructure;
use Friendica\Model\Storage\IStorage;
use Friendica\Object\Image;
-use Friendica\Protocol\DFRN;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Images;
use Friendica\Util\Network;
use Friendica\Util\Security;
use Friendica\Util\Strings;
"photo", ["resource-id"], ["uid" => $uid, "contact-id" => $cid, "scale" => 4, "album" => "Contact Photos"]
);
if (!empty($photo['resource-id'])) {
- $hash = $photo["resource-id"];
+ $resource_id = $photo["resource-id"];
} else {
- $hash = self::newResource();
+ $resource_id = self::newResource();
}
$photo_failure = false;
}
if (empty($type)) {
- $type = Image::guessType($image_url, true);
+ $type = Images::guessType($image_url, true);
}
$Image = new Image($img_str, $type);
if ($Image->isValid()) {
$Image->scaleToSquare(300);
- $r = self::store($Image, $uid, $cid, $hash, $filename, "Contact Photos", 4);
+ $r = self::store($Image, $uid, $cid, $resource_id, $filename, "Contact Photos", 4);
if ($r === false) {
$photo_failure = true;
$Image->scaleDown(80);
- $r = self::store($Image, $uid, $cid, $hash, $filename, "Contact Photos", 5);
+ $r = self::store($Image, $uid, $cid, $resource_id, $filename, "Contact Photos", 5);
if ($r === false) {
$photo_failure = true;
$Image->scaleDown(48);
- $r = self::store($Image, $uid, $cid, $hash, $filename, "Contact Photos", 6);
+ $r = self::store($Image, $uid, $cid, $resource_id, $filename, "Contact Photos", 6);
if ($r === false) {
$photo_failure = true;
$suffix = "?ts=" . time();
- $image_url = System::baseUrl() . "/photo/" . $hash . "-4." . $Image->getExt() . $suffix;
- $thumb = System::baseUrl() . "/photo/" . $hash . "-5." . $Image->getExt() . $suffix;
- $micro = System::baseUrl() . "/photo/" . $hash . "-6." . $Image->getExt() . $suffix;
+ $image_url = System::baseUrl() . "/photo/" . $resource_id . "-4." . $Image->getExt() . $suffix;
+ $thumb = System::baseUrl() . "/photo/" . $resource_id . "-5." . $Image->getExt() . $suffix;
+ $micro = System::baseUrl() . "/photo/" . $resource_id . "-6." . $Image->getExt() . $suffix;
// Remove the cached photo
$a = \get_app();
$basepath = $a->getBasePath();
if (is_dir($basepath . "/photo")) {
- $filename = $basepath . "/photo/" . $hash . "-4." . $Image->getExt();
+ $filename = $basepath . "/photo/" . $resource_id . "-4." . $Image->getExt();
if (file_exists($filename)) {
unlink($filename);
}
- $filename = $basepath . "/photo/" . $hash . "-5." . $Image->getExt();
+ $filename = $basepath . "/photo/" . $resource_id . "-5." . $Image->getExt();
if (file_exists($filename)) {
unlink($filename);
}
- $filename = $basepath . "/photo/" . $hash . "-6." . $Image->getExt();
+ $filename = $basepath . "/photo/" . $resource_id . "-6." . $Image->getExt();
if (file_exists($filename)) {
unlink($filename);
}
public static function stripExtension($name)
{
$name = str_replace([".jpg", ".png", ".gif"], ["", "", ""], $name);
- foreach (Image::supportedTypes() as $m => $e) {
+ foreach (Images::supportedTypes() as $m => $e) {
$name = str_replace("." . $e, "", $name);
}
return $name;
use Friendica\Object\Image;
use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Images;
use Friendica\Util\Network;
use Friendica\Util\Strings;
use Friendica\Worker\Delivery;
$filename = basename($photo);
$img_str = Network::fetchUrl($photo, true);
// guess mimetype from headers or filename
- $type = Image::guessType($photo, true);
+ $type = Images::guessType($photo, true);
$Image = new Image($img_str, $type);
if ($Image->isValid()) {
$Image->scaleToSquare(300);
- $hash = Photo::newResource();
+ $resource_id = Photo::newResource();
- $r = Photo::store($Image, $uid, 0, $hash, $filename, L10n::t('Profile Photos'), 4);
+ $r = Photo::store($Image, $uid, 0, $resource_id, $filename, L10n::t('Profile Photos'), 4);
if ($r === false) {
$photo_failure = true;
$Image->scaleDown(80);
- $r = Photo::store($Image, $uid, 0, $hash, $filename, L10n::t('Profile Photos'), 5);
+ $r = Photo::store($Image, $uid, 0, $resource_id, $filename, L10n::t('Profile Photos'), 5);
if ($r === false) {
$photo_failure = true;
$Image->scaleDown(48);
- $r = Photo::store($Image, $uid, 0, $hash, $filename, L10n::t('Profile Photos'), 6);
+ $r = Photo::store($Image, $uid, 0, $resource_id, $filename, L10n::t('Profile Photos'), 6);
if ($r === false) {
$photo_failure = true;
}
if (!$photo_failure) {
- Photo::update(['profile' => 1], ['resource-id' => $hash]);
+ Photo::update(['profile' => 1], ['resource-id' => $resource_id]);
}
}
}
*/
class AccountManagementControlDocument extends BaseModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
$output = [
'version' => 1,
*/
class Acctlink extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
$addr = trim($_GET['addr'] ?? '');
class Details extends BaseAdminModule
{
- public static function post()
+ public static function post(array $parameters = [])
{
- parent::post();
+ parent::post($parameters);
$a = self::getApp();
$a->internalRedirect('admin/addons');
}
- public static function content()
+ public static function content(array $parameters = [])
{
- parent::content();
+ parent::content($parameters);
$a = self::getApp();
class Index extends BaseAdminModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
- parent::content();
+ parent::content($parameters);
$a = self::getApp();
class Contact extends BaseAdminModule
{
- public static function post()
+ public static function post(array $parameters = [])
{
- parent::post();
+ parent::post($parameters);
$contact_url = $_POST['contact_url'] ?? '';
$block_reason = $_POST['contact_block_reason'] ?? '';
self::getApp()->internalRedirect('admin/blocklist/contact');
}
- public static function content()
+ public static function content(array $parameters = [])
{
- parent::content();
+ parent::content($parameters);
$a = self::getApp();
class Server extends BaseAdminModule
{
- public static function post()
+ public static function post(array $parameters = [])
{
- parent::post();
+ parent::post($parameters);
if (empty($_POST['page_blocklist_save']) && empty($_POST['page_blocklist_edit'])) {
return;
self::getApp()->internalRedirect('admin/blocklist/server');
}
- public static function content()
+ public static function content(array $parameters = [])
{
- parent::content();
+ parent::content($parameters);
$a = self::getApp();
class DBSync extends BaseAdminModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
- parent::content();
+ parent::content($parameters);
$a = self::getApp();
class Features extends BaseAdminModule
{
- public static function post()
+ public static function post(array $parameters = [])
{
- parent::post();
+ parent::post($parameters);
parent::checkFormSecurityTokenRedirectOnError('/admin/features', 'admin_manage_features');
self::getApp()->internalRedirect('admin/features');
}
- public static function content()
+ public static function content(array $parameters = [])
{
- parent::content();
+ parent::content($parameters);
$arr = [];
$features = Feature::get(false);
class Federation extends BaseAdminModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
- parent::content();
+ parent::content($parameters);
// get counts on active friendica, diaspora, redmatrix, hubzilla, gnu
// social and statusnet nodes this node is knowing
class Delete extends BaseAdminModule
{
- public static function post()
+ public static function post(array $parameters = [])
{
- parent::post();
+ parent::post($parameters);
if (empty($_POST['page_deleteitem_submit'])) {
return;
self::getApp()->internalRedirect('admin/item/delete');
}
- public static function content()
+ public static function content(array $parameters = [])
{
- parent::content();
+ parent::content($parameters);
$t = Renderer::getMarkupTemplate('admin/item/delete.tpl');
class Source extends BaseAdminModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
- parent::content();
+ parent::content($parameters);
$a = self::getApp();
class Settings extends BaseAdminModule
{
- public static function post()
+ public static function post(array $parameters = [])
{
- parent::post();
+ parent::post($parameters);
if (!empty($_POST['page_logs'])) {
parent::checkFormSecurityTokenRedirectOnError('/admin/logs', 'admin_logs');
self::getApp()->internalRedirect('admin/logs');
}
- public static function content()
+ public static function content(array $parameters = [])
{
- parent::content();
+ parent::content($parameters);
$a = self::getApp();
class View extends BaseAdminModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
- parent::content();
+ parent::content($parameters);
$t = Renderer::getMarkupTemplate('admin/logs/view.tpl');
$f = Config::get('system', 'logfile');
class PhpInfo extends BaseAdminModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
- parent::rawContent();
+ parent::rawContent($parameters);
phpinfo();
exit();
*/
class Queue extends BaseAdminModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
- parent::content();
+ parent::content($parameters);
$a = self::getApp();
class Site extends BaseAdminModule
{
- public static function post()
+ public static function post(array $parameters = [])
{
- parent::post();
+ parent::post($parameters);
self::checkFormSecurityTokenRedirectOnError('/admin/site', 'admin_site');
$a->internalRedirect('admin/site' . $active_panel);
}
- public static function content()
+ public static function content(array $parameters = [])
{
- parent::content();
+ parent::content($parameters);
$a = self::getApp();
class Summary extends BaseAdminModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
- parent::content();
+ parent::content($parameters);
$a = self::getApp();
class Details extends BaseAdminModule
{
- public static function post()
+ public static function post(array $parameters = [])
{
- parent::post();
+ parent::post($parameters);
$a = self::getApp();
}
}
- public static function content()
+ public static function content(array $parameters = [])
{
- parent::content();
+ parent::content($parameters);
$a = self::getApp();
class Embed extends BaseAdminModule
{
- public static function init()
+ public static function init(array $parameters = [])
{
$a = self::getApp();
}
}
- public static function post()
+ public static function post(array $parameters = [])
{
- parent::post();
+ parent::post($parameters);
$a = self::getApp();
}
}
- public static function content()
+ public static function content(array $parameters = [])
{
- parent::content();
+ parent::content($parameters);
$a = self::getApp();
class Index extends BaseAdminModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
- parent::content();
+ parent::content($parameters);
$a = self::getApp();
class Tos extends BaseAdminModule
{
- public static function post()
+ public static function post(array $parameters = [])
{
- parent::post();
+ parent::post($parameters);
parent::checkFormSecurityTokenRedirectOnError('/admin/tos', 'admin_tos');
self::getApp()->internalRedirect('admin/tos');
}
- public static function content()
+ public static function content(array $parameters = [])
{
- parent::content();
+ parent::content($parameters);
$tos = new \Friendica\Module\Tos();
$t = Renderer::getMarkupTemplate('admin/tos.tpl');
class Users extends BaseAdminModule
{
- public static function post()
+ public static function post(array $parameters = [])
{
- parent::post();
+ parent::post($parameters);
$a = self::getApp();
$a->internalRedirect('admin/users');
}
- public static function content()
+ public static function content(array $parameters = [])
{
- parent::content();
+ parent::content($parameters);
$a = self::getApp();
*/
class AllFriends extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
$app = self::getApp();
*/
class Apps extends BaseModule
{
- public static function init()
+ public static function init(array $parameters = [])
{
$privateaddons = Config::get('config', 'private_addons');
if ($privateaddons === "1" && !local_user()) {
}
}
- public static function content()
+ public static function content(array $parameters = [])
{
$apps = Nav::getAppMenu();
/**
* @brief Return to user an attached file given the id
*/
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
$a = self::getApp();
if ($a->argc != 2) {
*/
abstract class BaseAdminModule extends BaseModule
{
- public static function post()
+ public static function post(array $parameters = [])
{
if (!is_site_admin()) {
return;
}
}
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
if (!is_site_admin()) {
return '';
return '';
}
- public static function content()
+ public static function content(array $parameters = [])
{
$a = self::getApp();
class BaseSettingsModule extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
$a = self::getApp();
$tabs[] = [
'label' => L10n::t('Export personal data'),
- 'url' => 'uexport',
- 'selected' => (($a->argc == 1) && ($a->argv[0] === 'uexport') ? 'active' : ''),
+ 'url' => 'settings/userexport',
+ 'selected' => (($a->argc > 1) && ($a->argv[1] === 'userexport') ? 'active' : ''),
'accesskey' => 'e',
];
*/
class Bookmarklet extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
$_GET['mode'] = 'minimal';
$a->internalRedirect('contact');
}
- public static function post()
+ public static function post(array $parameters = [])
{
$a = self::getApp();
Model\Contact::remove($orig_record['id']);
}
- public static function content($update = 0)
+ public static function content(array $parameters = [], $update = 0)
{
if (!local_user()) {
return Login::form($_SERVER['REQUEST_URI']);
--- /dev/null
+<?php
+
+namespace Friendica\Module\Contact;
+
+use Friendica\BaseModule;
+use Friendica\Core\Config;
+use Friendica\Core\Renderer;
+use Friendica\Core\Session;
+use Friendica\Database\DBA;
+use Friendica\Model\Contact;
+use Friendica\Model\GContact;
+use Friendica\Network\HTTPException;
+use Friendica\Util\Strings;
+use Friendica\Util\Proxy;
+
+/**
+ * Asynchronous HTML fragment provider for frio contact hovercards
+ */
+class Hovercard extends BaseModule
+{
+ public static function rawContent(array $parameters = [])
+ {
+ $contact_url = $_REQUEST['url'] ?? '';
+
+ // Get out if the system doesn't have public access allowed
+ if (Config::get('system', 'block_public') && !Session::isAuthenticated()) {
+ throw new HTTPException\ForbiddenException();
+ }
+
+ // If a contact is connected the url is internally changed to 'redir/CID'. We need the pure url to search for
+ // the contact. So we strip out the contact id from the internal url and look in the contact table for
+ // the real url (nurl)
+ if (strpos($contact_url, 'redir/') === 0) {
+ $cid = intval(substr($contact_url, 6));
+ $remote_contact = Contact::selectFirst(['nurl'], ['id' => $cid]);
+ $contact_url = $remote_contact['nurl'] ?? '';
+ }
+
+ $contact = [];
+
+ // if it's the url containing https it should be converted to http
+ $contact_nurl = Strings::normaliseLink(GContact::cleanContactUrl($contact_url));
+ if (!$contact_nurl) {
+ throw new HTTPException\BadRequestException();
+ }
+
+ // Search for contact data
+ // Look if the local user has got the contact
+ if (Session::isAuthenticated()) {
+ $contact = Contact::getDetailsByURL($contact_nurl, local_user());
+ }
+
+ // If not then check the global user
+ if (!count($contact)) {
+ $contact = Contact::getDetailsByURL($contact_nurl);
+ }
+
+ // Feeds url could have been destroyed through "cleanContactUrl", so we now use the original url
+ if (!count($contact) && Session::isAuthenticated()) {
+ $contact_nurl = Strings::normaliseLink($contact_url);
+ $contact = Contact::getDetailsByURL($contact_nurl, local_user());
+ }
+
+ if (!count($contact)) {
+ $contact_nurl = Strings::normaliseLink($contact_url);
+ $contact = Contact::getDetailsByURL($contact_nurl);
+ }
+
+ if (!count($contact)) {
+ throw new HTTPException\NotFoundException();
+ }
+
+ // Get the photo_menu - the menu if possible contact actions
+ if (Session::isAuthenticated()) {
+ $actions = Contact::photoMenu($contact);
+ } else {
+ $actions = [];
+ }
+
+ // Move the contact data to the profile array so we can deliver it to
+ $tpl = Renderer::getMarkupTemplate('hovercard.tpl');
+ $o = Renderer::replaceMacros($tpl, [
+ '$profile' => [
+ 'name' => $contact['name'],
+ 'nick' => $contact['nick'],
+ 'addr' => $contact['addr'] ?: $contact['url'],
+ 'thumb' => Proxy::proxifyUrl($contact['thumb'], false, Proxy::SIZE_THUMB),
+ 'url' => Contact::magicLink($contact['url']),
+ 'nurl' => $contact['nurl'],
+ 'location' => $contact['location'],
+ 'gender' => $contact['gender'],
+ 'about' => $contact['about'],
+ 'network_link' => Strings::formatNetworkName($contact['network'], $contact['url']),
+ 'tags' => $contact['keywords'],
+ 'bd' => $contact['birthday'] <= DBA::NULL_DATE ? '' : $contact['birthday'],
+ 'account_type' => Contact::getAccountType($contact),
+ 'actions' => $actions,
+ ],
+ ]);
+
+ echo $o;
+ exit();
+ }
+}
*/
class Credits extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
/* fill the page with credits */
$credits_string = file_get_contents('CREDITS.txt');
*/
class Babel extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
function visible_whitespace($s)
{
*/
class Feed extends BaseModule
{
- public static function init()
+ public static function init(array $parameters = [])
{
if (!local_user()) {
info(L10n::t('You must be logged in to use this module'));
}
}
- public static function content()
+ public static function content(array $parameters = [])
{
$result = [];
if (!empty($_REQUEST['url'])) {
*/
class ItemBody extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
if (!local_user()) {
throw new HTTPException\UnauthorizedException(L10n::t('Access denied.'));
class Localtime extends BaseModule
{
- public static function post()
+ public static function post(array $parameters = [])
{
$time = ($_REQUEST['time'] ?? '') ?: 'now';
}
}
- public static function content()
+ public static function content(array $parameters = [])
{
$app = self::getApp();
*/
class Probe extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
if (!local_user()) {
$e = new HTTPException\ForbiddenException(L10n::t('Only logged in users are permitted to perform a probing.'));
*/
class WebFinger extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
if (!local_user()) {
$e = new \Friendica\Network\HTTPException\ForbiddenException(L10n::t('Only logged in users are permitted to perform a probing.'));
*/
class Delegation extends BaseModule
{
- public static function post()
+ public static function post(array $parameters = [])
{
if (!local_user()) {
return;
// NOTREACHED
}
- public static function content()
+ public static function content(array $parameters = [])
{
if (!local_user()) {
throw new ForbiddenException(L10n::t('Permission denied.'));
*/
class Fetch extends BaseModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
$app = self::getApp();
/** @var LoggerInterface */
private static $logger;
- public static function init()
+ public static function init(array $parameters = [])
{
/** @var LoggerInterface $logger */
self::$logger = self::getClass(LoggerInterface::class);
}
- public static function post()
+ public static function post(array $parameters = [])
{
/** @var Configuration $config */
$config = self::getClass(Configuration::class);
*/
class Directory extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
$app = self::getApp();
$config = $app->getConfig();
*/
class Feed extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
$a = self::getApp();
*/
class RemoveTag extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
if (!local_user()) {
throw new HTTPException\ForbiddenException();
*/
class SaveTag extends BaseModule
{
- public static function init()
+ public static function init(array $parameters = [])
{
if (!local_user()) {
info(L10n::t('You must be logged in to use this module'));
}
}
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
$a = self::getApp();
$logger = $a->getLogger();
*/
class FollowConfirm extends BaseModule
{
- public static function post()
+ public static function post(array $parameters = [])
{
$a = self::getApp();
*/
class Followers extends BaseModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
$a = self::getApp();
*/
class Following extends BaseModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
$a = self::getApp();
*/
class Friendica extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
$app = self::getApp();
$config = $app->getConfig();
]);
}
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
$app = self::getApp();
class Group extends BaseModule
{
- public static function post()
+ public static function post(array $parameters = [])
{
$a = self::getApp();
}
}
- public static function content()
+ public static function content(array $parameters = [])
{
$change = false;
class MethodNotAllowed extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
throw new HTTPException\MethodNotAllowedException(L10n::t('Method Not Allowed.'));
}
class PageNotFound extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
throw new HTTPException\NotFoundException(L10n::t('Page not found.'));
}
class Hashtag extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
$result = [];
*/
class Help extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
Nav::setSelected('help');
*/
class Home extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
$app = self::getApp();
$config = $app->getConfig();
*/
class Inbox extends BaseModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
$a = self::getApp();
*/
private static $installer;
- public static function init()
+ public static function init(array $parameters = [])
{
$a = self::getApp();
self::$currentWizardStep = ($_POST['pass'] ?? '') ?: self::SYSTEM_CHECK;
}
- public static function post()
+ public static function post(array $parameters = [])
{
$a = self::getApp();
$configCache = $a->getConfigCache();
}
}
- public static function content()
+ public static function content(array $parameters = [])
{
$a = self::getApp();
$configCache = $a->getConfigCache();
*/
class Invite extends BaseModule
{
- public static function post()
+ public static function post(array $parameters = [])
{
if (!local_user()) {
throw new HTTPException\ForbiddenException(L10n::t('Permission denied.'));
notice(L10n::tt('%d message sent.', '%d messages sent.', $total) . EOL);
}
- public static function content()
+ public static function content(array $parameters = [])
{
if (!local_user()) {
throw new HTTPException\ForbiddenException(L10n::t('Permission denied.'));
class Compose extends BaseModule
{
- public static function post()
+ public static function post(array $parameters = [])
{
if (!empty($_REQUEST['body'])) {
$_REQUEST['return'] = 'network';
}
}
- public static function content()
+ public static function content(array $parameters = [])
{
if (!local_user()) {
return Login::form('compose', false);
*/
class Ignore extends BaseModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
/** @var L10n $l10n */
$l10n = self::getClass(L10n::class);
*/
class Like extends BaseModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
if (!Session::isAuthenticated()) {
throw new HTTPException\ForbiddenException();
*/
class Login extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
$a = self::getApp();
return self::form(Session::get('return_path'), intval(Config::get('config', 'register_policy')) !== \Friendica\Module\Register::CLOSED);
}
- public static function post()
+ public static function post(array $parameters = [])
{
$openid_identity = Session::get('openid_identity');
$openid_server = Session::get('openid_server');
/**
* @brief Process logout requests
*/
- public static function init()
+ public static function init(array $parameters = [])
{
$visitor_home = null;
if (remote_user()) {
*/
class Magic extends BaseModule
{
- public static function init()
+ public static function init(array $parameters = [])
{
$a = self::getApp();
$ret = ['success' => false, 'url' => '', 'message' => ''];
*/
class Maintenance extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
$config = self::getApp()->getConfig();
class Manifest extends BaseModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
$app = self::getApp();
$config = $app->getConfig();
*/
class NodeInfo extends BaseModule
{
- public static function init()
+ public static function init(array $parameters = [])
{
$config = self::getApp()->getConfig();
}
}
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
$app = self::getApp();
*/
class Notify extends BaseModule
{
- public static function init()
+ public static function init(array $parameters = [])
{
if (!local_user()) {
throw new HTTPException\UnauthorizedException(L10n::t('Permission denied.'));
}
}
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
$a = self::getApp();
* @return string|void
* @throws HTTPException\InternalServerErrorException
*/
- public static function content()
+ public static function content(array $parameters = [])
{
$a = self::getApp();
*/
class Objects extends BaseModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
$a = self::getApp();
*/
class Oembed extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
$a = self::getApp();
/**
* @throws \Exception
*/
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
header('Content-type: application/opensearchdescription+xml');
*/
class Outbox extends BaseModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
$a = self::getApp();
*/
class Owa extends BaseModule
{
- public static function init()
+ public static function init(array $parameters = [])
{
$ret = [ 'success' => false ];
* Fetch a photo or an avatar, in optional size, check for permissions and
* return the image
*/
- public static function init()
+ public static function init(array $parameters = [])
{
$a = self::getApp();
// @TODO: Replace with parameter from router
--- /dev/null
+<?php
+
+namespace Friendica\Module;
+
+use Friendica\BaseModule;
+use Friendica\Model\Item;
+
+/**
+ * Toggle pinned items
+ */
+class Pinned extends BaseModule
+{
+ public static function rawContent(array $parameters = [])
+ {
+ if (!local_user()) {
+ throw new \Friendica\Network\HTTPException\ForbiddenException();
+ }
+
+ if (empty($parameters['item'])) {
+ throw new \Friendica\Network\HTTPException\BadRequestException();
+ }
+
+ $itemId = intval($parameters['item']);
+
+ $pinned = !Item::getPinned($itemId, local_user());
+
+ Item::setPinned($itemId, local_user(), $pinned);
+
+ // See if we've been passed a return path to redirect to
+ $returnPath = $_REQUEST['return'] ?? '';
+ if (!empty($returnPath)) {
+ $rand = '_=' . time() . (strpos($returnPath, '?') ? '&' : '?') . 'rand';
+ self::getApp()->internalRedirect($returnPath . $rand);
+ }
+
+ // the json doesn't really matter, it will either be 0 or 1
+ echo json_encode((int)$pinned);
+ exit();
+ }
+}
public static $which = '';
public static $profile = 0;
- public static function init()
+ public static function init(array $parameters = [])
{
$a = self::getApp();
}
}
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
if (ActivityPub::isRequest()) {
$user = DBA::selectFirst('user', ['uid'], ['nickname' => self::$which]);
}
}
- public static function content($update = 0)
+ public static function content(array $parameters = [], $update = 0)
{
$a = self::getApp();
}
if (!$update) {
- $tab = Strings::escapeTags(trim($_GET['tab'] ?? ''));
+ $tab = Strings::escapeTags(trim($_GET['tab'] ?? ''));
$o .= ProfileModel::getTabs($a, $tab, $is_owner, $a->profile['nickname']);
$items = DBA::toArray($items_stmt);
- $o .= conversation($a, $items, $pager, 'profile', $update, false, 'received', $a->profile['profile_uid']);
+ if ($pager->getStart() == 0 && !empty($a->profile['profile_uid'])) {
+ $pinned_items = Item::selectPinned($a->profile['profile_uid'], ['uri', 'pinned'], ['true' . $sql_extra]);
+ $pinned = Item::inArray($pinned_items);
+ $items = array_merge($items, $pinned);
+ }
+
+ $o .= conversation($a, $items, $pager, 'profile', $update, false, 'pinned_received', $a->profile['profile_uid']);
if (!$update) {
$o .= $pager->renderMinimal(count($items));
class Contacts extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
if (Config::get('system', 'block_public') && !Session::isAuthenticated()) {
throw new \Friendica\Network\HTTPException\NotFoundException(L10n::t('User not found.'));
* Sets application instance and checks if /proxy/ path is writable.
*
*/
- public static function init()
+ public static function init(array $parameters = [])
{
// Set application instance here
$a = self::getApp();
*/
class PublicRSAKey extends BaseModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
$app = self::getApp();
*/
class RandomProfile extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
$a = self::getApp();
*/
class ReallySimpleDiscovery extends BaseModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
header('Content-Type: text/xml');
*
* @return string
*/
- public static function content()
+ public static function content(array $parameters = [])
{
// logged in users can register others (people/pages/groups)
// even with closed registrations, unless specifically prohibited by site policy.
* Extend this method if the module is supposed to process POST requests.
* Doesn't display any content
*/
- public static function post()
+ public static function post(array $parameters = [])
{
BaseModule::checkFormSecurityTokenRedirectOnError('/register', 'register');
$a->internalRedirect('register/');
}
+ // Is there text in the tar pit?
+ if (!empty($_POST['registertarpit'])) {
+ \notice(L10n::t('You have entered too much information.'));
+ $a->internalRedirect('register/');
+ }
Model\Register::createForApproval($user['uid'], Config::get('system', 'language'), $_POST['permonlybox']);
*/
class RobotsTxt extends BaseModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
$allDisalloweds = [
'/settings/',
const TYPE_PRIVATE_MESSAGE = 'm';
const TYPE_ANY_CONTACT = 'a';
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
if (!local_user()) {
throw new HTTPException\UnauthorizedException(L10n::t('You must be logged in to use this module.'));
*/
class Directory extends BaseSearchModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
if (!local_user()) {
notice(L10n::t('Permission denied.'));
class Index extends BaseSearchModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
$search = (!empty($_GET['q']) ? Strings::escapeTags(trim(rawurldecode($_GET['q']))) : '');
class Saved extends BaseModule
{
- public static function init()
+ public static function init(array $parameters = [])
{
/** @var Arguments $args */
$args = self::getClass(Arguments::class);
*/
class Delegation extends BaseSettingsModule
{
- public static function post()
+ public static function post(array $parameters = [])
{
if (!local_user() || !empty(self::getApp()->user['uid']) && self::getApp()->user['uid'] != local_user()) {
throw new HTTPException\ForbiddenException(L10n::t('Permission denied.'));
DBA::update('user', ['parent-uid' => $parent_uid], ['uid' => local_user()]);
}
- public static function content()
+ public static function content(array $parameters = [])
{
- parent::content();
+ parent::content($parameters);
if (!local_user()) {
throw new HTTPException\ForbiddenException(L10n::t('Permission denied.'));
{
private static $appSpecificPassword = null;
- public static function init()
+ public static function init(array $parameters = [])
{
if (!local_user()) {
return;
}
}
- public static function post()
+ public static function post(array $parameters = [])
{
if (!local_user()) {
return;
}
}
- public static function content()
+ public static function content(array $parameters = [])
{
if (!local_user()) {
return Login::form('settings/2fa/app_specific');
}
- parent::content();
+ parent::content($parameters);
$appSpecificPasswords = AppSpecificPassword::getListForUser(local_user());
class Index extends BaseSettingsModule
{
- public static function post()
+ public static function post(array $parameters = [])
{
if (!local_user()) {
return;
}
}
- public static function content()
+ public static function content(array $parameters = [])
{
if (!local_user()) {
return Login::form('settings/2fa');
}
- parent::content();
+ parent::content($parameters);
$has_secret = (bool) PConfig::get(local_user(), '2fa', 'secret');
$verified = PConfig::get(local_user(), '2fa', 'verified');
*/
class Recovery extends BaseSettingsModule
{
- public static function init()
+ public static function init(array $parameters = [])
{
if (!local_user()) {
return;
}
}
- public static function post()
+ public static function post(array $parameters = [])
{
if (!local_user()) {
return;
}
}
- public static function content()
+ public static function content(array $parameters = [])
{
if (!local_user()) {
return Login::form('settings/2fa/recovery');
}
- parent::content();
+ parent::content($parameters);
if (!RecoveryCode::countValidForUser(local_user())) {
RecoveryCode::generateForUser(local_user());
*/
class Verify extends BaseSettingsModule
{
- public static function init()
+ public static function init(array $parameters = [])
{
if (!local_user()) {
return;
}
}
- public static function post()
+ public static function post(array $parameters = [])
{
if (!local_user()) {
return;
}
}
- public static function content()
+ public static function content(array $parameters = [])
{
if (!local_user()) {
return Login::form('settings/2fa/verify');
}
- parent::content();
+ parent::content($parameters);
$company = 'Friendica';
$holder = Session::get('my_address');
--- /dev/null
+<?php
+/**
+ * @file src/Modules/Settings/UserExport.php
+ */
+
+namespace Friendica\Module\Settings;
+
+use Friendica\App;
+use Friendica\App\Arguments;
+use Friendica\BaseModule;
+use Friendica\Core\Hook;
+use Friendica\Core\L10n;
+use Friendica\Core\Renderer;
+use Friendica\Core\System;
+use Friendica\Database\DBA;
+use Friendica\Database\DBStructure;
+use Friendica\Module\BaseSettingsModule;
+
+/**
+ * Module to export user data
+ **/
+class UserExport extends BaseSettingsModule
+{
+ /**
+ * Handle the request to export data.
+ * At the moment one can export three different data set
+ * 1. The profile data that can be used by uimport to resettle
+ * to a different Friendica instance
+ * 2. The entire data-set, profile plus postings
+ * 3. A list of contacts as CSV file similar to the export of Mastodon
+ *
+ * If there is an action required through the URL / path, react
+ * accordingly and export the requested data.
+ **/
+ public static function content(array $parameters = [])
+ {
+ parent::content($parameters);
+
+ /**
+ * options shown on "Export personal data" page
+ * list of array( 'link url', 'link text', 'help text' )
+ */
+ $options = [
+ ['settings/userexport/account', L10n::t('Export account'), L10n::t('Export your account info and contacts. Use this to make a backup of your account and/or to move it to another server.')],
+ ['settings/userexport/backup', L10n::t('Export all'), L10n::t("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 \x28photos are not exported\x29")],
+ ['settings/userexport/contact', L10n::t('Export Contacts to CSV'), L10n::t("Export the list of the accounts you are following as CSV file. Compatible to e.g. Mastodon.")],
+ ];
+ Hook::callAll('uexport_options', $options);
+
+ $tpl = Renderer::getMarkupTemplate("settings/userexport.tpl");
+ return Renderer::replaceMacros($tpl, [
+ '$title' => L10n::t('Export personal data'),
+ '$options' => $options
+ ]);
+ }
+ /**
+ * raw content generated for the different choices made
+ * by the user. At the moment this returns a JSON file
+ * to the browser which then offers a save / open dialog
+ * to the user.
+ **/
+ public static function rawContent(array $parameters = [])
+ {
+ $args = self::getClass(Arguments::class);
+ if ($args->getArgc() == 3) {
+ // @TODO Replace with router-provided arguments
+ $action = $args->get(2);
+ $user = self::getApp()->user;
+ switch ($action) {
+ case "backup":
+ header("Content-type: application/json");
+ header('Content-Disposition: attachment; filename="' . $user['nickname'] . '.' . $action . '"');
+ self::exportAll(self::getApp());
+ exit();
+ break;
+ case "account":
+ header("Content-type: application/json");
+ header('Content-Disposition: attachment; filename="' . $user['nickname'] . '.' . $action . '"');
+ self::exportAccount(self::getApp());
+ exit();
+ break;
+ case "contact":
+ header("Content-type: application/csv");
+ header('Content-Disposition: attachment; filename="' . $user['nickname'] . '-contacts.csv'. '"');
+ self::exportContactsAsCSV();
+ exit();
+ break;
+ default:
+ exit();
+ }
+ }
+ }
+ private static function exportMultiRow(string $query)
+ {
+ $dbStructure = DBStructure::definition(self::getApp()->getBasePath(), false);
+
+ preg_match("/\s+from\s+`?([a-z\d_]+)`?/i", $query, $match);
+ $table = $match[1];
+
+ $result = [];
+ $rows = DBA::p($query);
+ while ($row = DBA::fetch($rows)) {
+ $p = [];
+ foreach ($row as $k => $v) {
+ switch ($dbStructure[$table]['fields'][$k]['type']) {
+ case 'datetime':
+ $p[$k] = $v ?? DBA::NULL_DATETIME;
+ break;
+ default:
+ $p[$k] = $v;
+ break;
+ }
+ }
+ $result[] = $p;
+ }
+ DBA::close($rows);
+ return $result;
+ }
+
+ private static function exportRow(string $query)
+ {
+ $dbStructure = DBStructure::definition(self::getApp()->getBasePath(), false);
+
+ preg_match("/\s+from\s+`?([a-z\d_]+)`?/i", $query, $match);
+ $table = $match[1];
+
+ $result = [];
+ $r = q($query);
+ if (DBA::isResult($r)) {
+
+ foreach ($r as $rr) {
+ foreach ($rr as $k => $v) {
+ switch ($dbStructure[$table]['fields'][$k]['type']) {
+ case 'datetime':
+ $result[$k] = $v ?? DBA::NULL_DATETIME;
+ break;
+ default:
+ $result[$k] = $v;
+ break;
+ }
+ }
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * Export a list of the contacts as CSV file as e.g. Mastodon and Pleroma are doing.
+ **/
+ private static function exportContactsAsCSV()
+ {
+ // write the table header (like Mastodon)
+ echo "Account address, Show boosts\n";
+ // get all the contacts
+ $contacts = DBA::select('contact', ['addr'], ['uid' => $_SESSION['uid'], 'self' => false, 'rel' => [1,3], 'deleted' => false]);
+ while ($contact = DBA::fetch($contacts)) {
+ echo $contact['addr'] . ", true\n";
+ }
+ DBA::close($contacts);
+ }
+ private static function exportAccount(App $a)
+ {
+ $user = self::exportRow(
+ sprintf("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval(local_user()))
+ );
+
+ $contact = self::exportMultiRow(
+ sprintf("SELECT * FROM `contact` WHERE `uid` = %d ", intval(local_user()))
+ );
+
+
+ $profile = self::exportMultiRow(
+ sprintf("SELECT * FROM `profile` WHERE `uid` = %d ", intval(local_user()))
+ );
+
+ $photo = self::exportMultiRow(
+ sprintf("SELECT * FROM `photo` WHERE uid = %d AND profile = 1", intval(local_user()))
+ );
+ foreach ($photo as &$p) {
+ $p['data'] = bin2hex($p['data']);
+ }
+
+ $pconfig = self::exportMultiRow(
+ sprintf("SELECT * FROM `pconfig` WHERE uid = %d", intval(local_user()))
+ );
+
+ $group = self::exportMultiRow(
+ sprintf("SELECT * FROM `group` WHERE uid = %d", intval(local_user()))
+ );
+
+ $group_member = self::exportMultiRow(
+ sprintf("SELECT `group_member`.`gid`, `group_member`.`contact-id` FROM `group_member` INNER JOIN `group` ON `group`.`id` = `group_member`.`gid` WHERE `group`.`uid` = %d", intval(local_user()))
+ );
+
+ $output = [
+ 'version' => FRIENDICA_VERSION,
+ 'schema' => DB_UPDATE_VERSION,
+ 'baseurl' => System::baseUrl(),
+ 'user' => $user,
+ 'contact' => $contact,
+ 'profile' => $profile,
+ 'photo' => $photo,
+ 'pconfig' => $pconfig,
+ 'group' => $group,
+ 'group_member' => $group_member,
+ ];
+
+ echo json_encode($output, JSON_PARTIAL_OUTPUT_ON_ERROR);
+ }
+
+ /**
+ * echoes account data and items as separated json, one per line
+ *
+ * @param App $a
+ * @throws Exception
+ */
+ private static function exportAll(App $a)
+ {
+ self::exportAccount($a);
+ echo "\n";
+
+ $total = DBA::count('item', ['uid' => local_user()]);
+ // chunk the output to avoid exhausting memory
+
+ for ($x = 0; $x < $total; $x += 500) {
+ $r = q("SELECT * FROM `item` WHERE `uid` = %d LIMIT %d, %d",
+ intval(local_user()),
+ intval($x),
+ intval(500)
+ );
+
+ $output = ['item' => $r];
+ echo json_encode($output, JSON_PARTIAL_OUTPUT_ON_ERROR). "\n";
+ }
+ }
+}
*/
class Smilies extends BaseModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
$app = self::getApp();
}
}
- public static function content()
+ public static function content(array $parameters = [])
{
$smilies = Content\Smilies::getList();
$count = count($smilies['texts'] ?? []);
*/
class Starred extends BaseModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
- $a = self::getApp();
- $starred = 0;
- $itemId = null;
-
if (!local_user()) {
- exit();
+ throw new \Friendica\Network\HTTPException\ForbiddenException();
}
- // @TODO: Replace with parameter from router
- if ($a->argc > 1) {
- $itemId = intval($a->argv[1]);
+ if (empty($parameters['item'])) {
+ throw new \Friendica\Network\HTTPException\BadRequestException();
}
- if (!$itemId) {
- exit();
- }
+ $itemId = intval($parameters['item']);
$item = Item::selectFirstForUser(local_user(), ['starred'], ['uid' => local_user(), 'id' => $itemId]);
if (empty($item)) {
- exit();
+ throw new \Friendica\Network\HTTPException\NotFoundException();
}
- if (!intval($item['starred'])) {
- $starred = 1;
- }
+ $starred = !(bool)$item['starred'];
Item::update(['starred' => $starred], ['id' => $itemId]);
// See if we've been passed a return path to redirect to
$returnPath = $_REQUEST['return'] ?? '';
- if ($returnPath) {
- $rand = '_=' . time();
- if (strpos($returnPath, '?')) {
- $rand = "&$rand";
- } else {
- $rand = "?$rand";
- }
-
- $a->internalRedirect($returnPath . $rand);
+ if (!empty($returnPath)) {
+ $rand = '_=' . time() . (strpos($returnPath, '?') ? '&' : '?') . 'rand';
+ self::getApp()->internalRedirect($returnPath . $rand);
}
// the json doesn't really matter, it will either be 0 or 1
- echo json_encode($starred);
+ echo json_encode((int)$starred);
exit();
}
}
class Statistics extends BaseModule
{
- public static function init()
+ public static function init(array $parameters = [])
{
$config = self::getApp()->getConfig();
}
}
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
$config = self::getApp()->getConfig();
$logger = self::getApp()->getLogger();
*/
class Theme extends BaseModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
header("Content-Type: text/css");
*/
class ThemeDetails extends BaseModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
if (!empty($_REQUEST['theme'])) {
$theme = $_REQUEST['theme'];
*/
class ToggleMobile extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
$a = self::getApp();
{
$this->privacy_operate = L10n::t('At the time of registration, and for providing communications between the user account and their contacts, the user has to provide a display name (pen name), an username (nickname) and a working email address. The names will be accessible on the profile page of the account by any visitor of the page, even if other profile details are not displayed. The email address will only be used to send the user notifications about interactions, but wont be visibly displayed. The listing of an account in the node\'s user directory or the global user directory is optional and can be controlled in the user settings, it is not necessary for communication.');
$this->privacy_distribute = L10n::t('This data is required for communication and is passed on to the nodes of the communication partners and is stored there. Users can enter additional private data that may be transmitted to the communication partners accounts.');
- $this->privacy_delete = L10n::t('At any point in time a logged in user can export their account data from the <a href="%1$s/settings/uexport">account settings</a>. If the user wants to delete their account they can do so at <a href="%1$s/removeme">%1$s/removeme</a>. The deletion of the account will be permanent. Deletion of the data will also be requested from the nodes of the communication partners.', System::baseurl());
+ $this->privacy_delete = L10n::t('At any point in time a logged in user can export their account data from the <a href="%1$s/settings/userexport">account settings</a>. If the user wants to delete their account they can do so at <a href="%1$s/removeme">%1$s/removeme</a>. The deletion of the account will be permanent. Deletion of the data will also be requested from the nodes of the communication partners.', System::baseurl());
// In some cases we don't need every single one of the above separate, but all in one block.
// So here is an array to look over
$this->privacy_complete = [L10n::t('Privacy Statement'), $this->privacy_operate, $this->privacy_distribute, $this->privacy_delete];
* dealings with their own node so a TOS is not necessary.
*
**/
- public static function init()
+ public static function init(array $parameters = [])
{
if (strlen(Config::get('system','singleuser'))) {
self::getApp()->internalRedirect('profile/' . Config::get('system','singleuser'));
* @return string
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
- public static function content() {
+ public static function content(array $parameters = []) {
$tpl = Renderer::getMarkupTemplate('tos.tpl');
if (Config::get('system', 'tosdisplay')) {
return Renderer::replaceMacros($tpl, [
'$privstatementtitle' => L10n::t('Privacy Statement'),
'$privacy_operate' => L10n::t('At the time of registration, and for providing communications between the user account and their contacts, the user has to provide a display name (pen name), an username (nickname) and a working email address. The names will be accessible on the profile page of the account by any visitor of the page, even if other profile details are not displayed. The email address will only be used to send the user notifications about interactions, but wont be visibly displayed. The listing of an account in the node\'s user directory or the global user directory is optional and can be controlled in the user settings, it is not necessary for communication.'),
'$privacy_distribute' => L10n::t('This data is required for communication and is passed on to the nodes of the communication partners and is stored there. Users can enter additional private data that may be transmitted to the communication partners accounts.'),
- '$privacy_delete' => L10n::t('At any point in time a logged in user can export their account data from the <a href="%1$s/settings/uexport">account settings</a>. If the user wants to delete their account they can do so at <a href="%1$s/removeme">%1$s/removeme</a>. The deletion of the account will be permanent. Deletion of the data will also be requested from the nodes of the communication partners.', System::baseurl())
+ '$privacy_delete' => L10n::t('At any point in time a logged in user can export their account data from the <a href="%1$s/settings/userexport">account settings</a>. If the user wants to delete their account they can do so at <a href="%1$s/removeme">%1$s/removeme</a>. The deletion of the account will be permanent. Deletion of the data will also be requested from the nodes of the communication partners.', System::baseurl())
]);
} else {
return;
*/
class Recovery extends BaseModule
{
- public static function init()
+ public static function init(array $parameters = [])
{
if (!local_user()) {
return;
}
}
- public static function post()
+ public static function post(array $parameters = [])
{
if (!local_user()) {
return;
}
}
- public static function content()
+ public static function content(array $parameters = [])
{
if (!local_user()) {
self::getApp()->internalRedirect();
{
private static $errors = [];
- public static function post()
+ public static function post(array $parameters = [])
{
if (!local_user()) {
return;
}
}
- public static function content()
+ public static function content(array $parameters = [])
{
if (!local_user()) {
self::getApp()->internalRedirect();
*/
class Welcome extends BaseModule
{
- public static function content()
+ public static function content(array $parameters = [])
{
$config = self::getApp()->getConfig();
*/
class HostMeta extends BaseModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
$app = self::getApp();
$config = $app->getConfig();
*/
class XSocialRelay extends BaseModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
$app = self::getApp();
$config = $app->getConfig();
*/
class Xrd extends BaseModule
{
- public static function rawContent()
+ public static function rawContent(array $parameters = [])
{
$app = self::getApp();
namespace Friendica\Object;
use Exception;
-use Friendica\Core\Cache;
use Friendica\Core\Config;
-use Friendica\Core\Logger;
use Friendica\Core\System;
-use Friendica\Util\Network;
+use Friendica\Util\Images;
use Imagick;
use ImagickPixel;
private $type;
private $types;
- /**
- * @brief supported mimetypes and corresponding file extensions
- * @return array
- */
- public static function supportedTypes()
- {
- if (class_exists('Imagick')) {
- // Imagick::queryFormats won't help us a lot there...
- // At least, not yet, other parts of friendica uses this array
- $t = [
- 'image/jpeg' => 'jpg',
- 'image/png' => 'png',
- 'image/gif' => 'gif'
- ];
- } else {
- $t = [];
- $t['image/jpeg'] ='jpg';
- if (imagetypes() & IMG_PNG) {
- $t['image/png'] = 'png';
- }
- }
-
- return $t;
- }
-
/**
* @brief Constructor
* @param string $data
public function __construct($data, $type = null)
{
$this->imagick = class_exists('Imagick');
- $this->types = static::supportedTypes();
+ $this->types = Images::supportedTypes();
if (!array_key_exists($type, $this->types)) {
- $type='image/jpeg';
+ $type = 'image/jpeg';
}
$this->type = $type;
return $this->imagick;
}
- /**
- * @brief Maps Mime types to Imagick formats
- * @return array With with image formats (mime type as key)
- */
- public static function getFormatsMap()
- {
- $m = [
- 'image/jpeg' => 'JPG',
- 'image/png' => 'PNG',
- 'image/gif' => 'GIF'
- ];
- return $m;
- }
-
/**
* @param string $data data
* @return boolean
/*
* Setup the image to the format it will be saved to
*/
- $map = self::getFormatsMap();
+ $map = Images::getFormatsMap();
$format = $map[$this->type];
$this->image->setFormat($format);
return $string;
}
+ /**
+ * @brief supported mimetypes and corresponding file extensions
+ * @return array
+ * @deprecated in version 2019.12 please use Util\Images::supportedTypes() instead.
+ */
+ public static function supportedTypes()
+ {
+ return Images::supportedTypes();
+ }
+
+ /**
+ * @brief Maps Mime types to Imagick formats
+ * @return array With with image formats (mime type as key)
+ * @deprecated in version 2019.12 please use Util\Images::getFormatsMap() instead.
+ */
+ public static function getFormatsMap()
+ {
+ return Images::getFormatsMap();
+ }
+
/**
* Guess image mimetype from filename or from Content-Type header
*
* @param boolean $fromcurl Check Content-Type header from curl request
* @param string $header passed headers to take into account
*
- * @return object
- * @throws \ImagickException
+ * @return string|null
+ * @throws Exception
+ * @deprecated in version 2019.12 please use Util\Images::guessType() instead.
*/
public static function guessType($filename, $fromcurl = false, $header = '')
{
- Logger::log('Image: guessType: '.$filename . ($fromcurl?' from curl headers':''), Logger::DEBUG);
- $type = null;
- if ($fromcurl) {
- $headers=[];
- $h = explode("\n", $header);
- foreach ($h as $l) {
- $data = array_map("trim", explode(":", trim($l), 2));
- if (count($data) > 1) {
- list($k,$v) = $data;
- $headers[$k] = $v;
- }
- }
- if (array_key_exists('Content-Type', $headers))
- $type = $headers['Content-Type'];
- }
- if (is_null($type)) {
- // Guessing from extension? Isn't that... dangerous?
- if (class_exists('Imagick') && file_exists($filename) && is_readable($filename)) {
- /**
- * Well, this not much better,
- * but at least it comes from the data inside the image,
- * we won't be tricked by a manipulated extension
- */
- $image = new Imagick($filename);
- $type = $image->getImageMimeType();
- $image->setInterlaceScheme(Imagick::INTERLACE_PLANE);
- } else {
- $ext = pathinfo($filename, PATHINFO_EXTENSION);
- $types = self::supportedTypes();
- $type = "image/jpeg";
- foreach ($types as $m => $e) {
- if ($ext == $e) {
- $type = $m;
- }
- }
- }
- }
- Logger::log('Image: guessType: type='.$type, Logger::DEBUG);
- return $type;
+ return Images::guessType($filename, $fromcurl, $header);
}
/**
* @param string $url url
- * @return object
+ * @return array
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
+ * @deprecated in version 2019.12 please use Util\Images::getInfoFromURLCached() instead.
*/
public static function getInfoFromURL($url)
{
- $data = [];
-
- if (empty($url)) {
- return $data;
- }
-
- $data = Cache::get($url);
-
- if (is_null($data) || !$data || !is_array($data)) {
- $img_str = Network::fetchUrl($url, true, 4);
-
- if (!$img_str) {
- return false;
- }
-
- $filesize = strlen($img_str);
-
- try {
- if (function_exists("getimagesizefromstring")) {
- $data = @getimagesizefromstring($img_str);
- } else {
- $tempfile = tempnam(get_temppath(), "cache");
-
- $a = \get_app();
- $stamp1 = microtime(true);
- file_put_contents($tempfile, $img_str);
- $a->getProfiler()->saveTimestamp($stamp1, "file", System::callstack());
-
- $data = getimagesize($tempfile);
- unlink($tempfile);
- }
- } catch (Exception $e) {
- return false;
- }
-
- if ($data) {
- $data["size"] = $filesize;
- }
-
- Cache::set($url, $data);
- }
-
- return $data;
+ return Images::getInfoFromURLCached($url);
}
/**
* @param integer $height height
* @param integer $max max
* @return array
+ * @deprecated in version 2019.12 please use Util\Images::getScalingDimensions() instead.
*/
public static function getScalingDimensions($width, $height, $max)
{
- if ((!$width) || (!$height)) {
- return false;
- }
-
- if ($width > $max && $height > $max) {
- // very tall image (greater than 16:9)
- // constrain the width - let the height float.
-
- if ((($height * 9) / 16) > $width) {
- $dest_width = $max;
- $dest_height = intval(($height * $max) / $width);
- } elseif ($width > $height) {
- // else constrain both dimensions
- $dest_width = $max;
- $dest_height = intval(($height * $max) / $width);
- } else {
- $dest_width = intval(($width * $max) / $height);
- $dest_height = $max;
- }
- } else {
- if ($width > $max) {
- $dest_width = $max;
- $dest_height = intval(($height * $max) / $width);
- } else {
- if ($height > $max) {
- // very tall image (greater than 16:9)
- // but width is OK - don't do anything
-
- if ((($height * 9) / 16) > $width) {
- $dest_width = $width;
- $dest_height = $height;
- } else {
- $dest_width = intval(($width * $max) / $height);
- $dest_height = $max;
- }
- } else {
- $dest_width = $width;
- $dest_height = $height;
- }
- }
- }
- return ["width" => $dest_width, "height" => $dest_height];
+ return Images::getScalingDimensions($width, $height, $max);
}
}
$sparkle = '';
$buttons = '';
$dropping = false;
+ $pinned = '';
+ $pin = false;
$star = false;
$ignore = false;
+ $ispinned = "unpinned";
$isstarred = "unstarred";
$indent = '';
$shiny = '';
if (DBA::isResult($parent)) {
$origin = $parent['origin'];
}
+ } elseif ($item['pinned']) {
+ $pinned = L10n::t('pinned item');
}
if ($origin && ($item['id'] != $item['parent']) && ($item['network'] == Protocol::ACTIVITYPUB)) {
}
if ($conv->getProfileOwner() == local_user() && ($item['uid'] != 0)) {
+ if ($origin) {
+ $ispinned = ($item['pinned'] ? 'pinned' : 'unpinned');
+
+ $pin = [
+ 'do' => L10n::t('pin'),
+ 'undo' => L10n::t('unpin'),
+ 'toggle' => L10n::t('toggle pin status'),
+ 'classdo' => $item['pinned'] ? 'hidden' : '',
+ 'classundo' => $item['pinned'] ? '' : 'hidden',
+ 'pinned' => L10n::t('pinned'),
+ ];
+ }
+
$isstarred = (($item['starred']) ? "starred" : "unstarred");
$star = [
'owner_name' => $owner_name_e,
'plink' => Item::getPlink($item),
'edpost' => $edpost,
+ 'ispinned' => $ispinned,
+ 'pin' => $pin,
+ 'pinned' => $pinned,
'isstarred' => $isstarred,
'star' => $star,
'ignore' => $ignore,
use Friendica\BaseObject;
use Friendica\Content\Feature;
-use Friendica\Database\DBA;
+use Friendica\Content\Text\BBCode;
+use Friendica\Content\Text\Plaintext;
+use Friendica\Core\Cache;
use Friendica\Core\Config;
use Friendica\Core\Logger;
-use Friendica\Core\System;
-use Friendica\Protocol\Activity;
-use Friendica\Util\HTTPSignature;
use Friendica\Core\Protocol;
-use Friendica\Model\Conversation;
-use Friendica\Model\Contact;
+use Friendica\Core\System;
+use Friendica\Database\DBA;
use Friendica\Model\APContact;
+use Friendica\Model\Contact;
+use Friendica\Model\Conversation;
use Friendica\Model\Item;
+use Friendica\Model\Profile;
use Friendica\Model\Term;
use Friendica\Model\User;
+use Friendica\Protocol\Activity;
+use Friendica\Protocol\ActivityPub;
use Friendica\Util\DateTimeFormat;
-use Friendica\Content\Text\BBCode;
-use Friendica\Content\Text\Plaintext;
-use Friendica\Util\XML;
+use Friendica\Util\HTTPSignature;
+use Friendica\Util\Images;
use Friendica\Util\JsonLD;
use Friendica\Util\LDSignature;
-use Friendica\Model\Profile;
-use Friendica\Object\Image;
-use Friendica\Protocol\ActivityPub;
-use Friendica\Core\Cache;
use Friendica\Util\Map;
use Friendica\Util\Network;
+use Friendica\Util\XML;
require_once 'include/api.php';
require_once 'mod/share.php';
// Grab all pictures without alternative descriptions and create attachments out of them
if (preg_match_all("/\[img\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures)) {
foreach ($pictures[1] as $picture) {
- $imgdata = Image::getInfoFromURL($picture);
+ $imgdata = Images::getInfoFromURLCached($picture);
if ($imgdata) {
$attachments[] = ['type' => 'Document',
'mediaType' => $imgdata['mime'],
// Grab all pictures with alternative description and create attachments out of them
if (preg_match_all("/\[img=([^\[\]]*)\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures, PREG_SET_ORDER)) {
foreach ($pictures as $picture) {
- $imgdata = Image::getInfoFromURL($picture[1]);
+ $imgdata = Images::getInfoFromURLCached($picture[1]);
if ($imgdata) {
$attachments[] = ['type' => 'Document',
'mediaType' => $imgdata['mime'],
use Friendica\Protocol\ActivityNamespace;
use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Images;
use Friendica\Util\Network;
use Friendica\Util\Strings;
use Friendica\Util\XML;
$uid
);
$photos = [];
- $ext = Image::supportedTypes();
+ $ext = Images::supportedTypes();
foreach ($rp as $p) {
$photos[$p['scale']] = System::baseUrl().'/photo/'.$p['resource-id'].'-'.$p['scale'].'.'.$ext[$p['type']];
return false;
}
- $batch = (($ret["batch"]) ? $ret["batch"] : implode("/", array_slice(explode("/", $ret["url"]), 0, 3))."/receive/public");
-
- q(
- "INSERT INTO `contact` (`uid`, `network`,`addr`,`created`,`url`,`nurl`,`batch`,`name`,`nick`,`photo`,`pubkey`,`notify`,`poll`,`blocked`,`priority`)
- VALUES (%d, '%s', '%s', '%s', '%s','%s','%s','%s','%s','%s','%s','%s','%s',%d,%d)",
- intval($importer["uid"]),
- DBA::escape($ret["network"]),
- DBA::escape($ret["addr"]),
- DateTimeFormat::utcNow(),
- DBA::escape($ret["url"]),
- DBA::escape(Strings::normaliseLink($ret["url"])),
- DBA::escape($batch),
- DBA::escape($ret["name"]),
- DBA::escape($ret["nick"]),
- DBA::escape($ret["photo"]),
- DBA::escape($ret["pubkey"]),
- DBA::escape($ret["notify"]),
- DBA::escape($ret["poll"]),
- 1,
- 2
- );
-
- // find the contact record we just created
-
- $contact_record = self::contactByHandle($importer["uid"], $author);
-
- if (!$contact_record) {
- Logger::log("unable to locate newly created contact record.");
- return;
- }
-
- Logger::log("Author ".$author." was added as contact number ".$contact_record["id"].".", Logger::DEBUG);
-
- Group::addMember(User::getDefaultGroup($importer['uid'], $ret["network"]), $contact_record['id']);
-
- Contact::updateAvatar($ret["photo"], $importer['uid'], $contact_record["id"], true);
-
- if (in_array($importer["page-flags"], [User::PAGE_FLAGS_NORMAL, User::PAGE_FLAGS_PRVGROUP])) {
- Logger::log("Sending intra message for author ".$author.".", Logger::DEBUG);
-
- $hash = Strings::getRandomHex().(string)time(); // Generate a confirm_key
-
- q(
- "INSERT INTO `intro` (`uid`, `contact-id`, `blocked`, `knowyou`, `note`, `hash`, `datetime`)
- VALUES (%d, %d, %d, %d, '%s', '%s', '%s')",
- intval($importer["uid"]),
- intval($contact_record["id"]),
- 0,
- 0,
- DBA::escape(L10n::t("Sharing notification from Diaspora network")),
- DBA::escape($hash),
- DBA::escape(DateTimeFormat::utcNow())
- );
+ $cid = Contact::getIdForURL($ret['url'], $importer['uid']);
+ if (!empty($cid)) {
+ $contact = DBA::selectFirst('contact', [], ['id' => $cid, 'network' => Protocol::NATIVE_SUPPORT]);
} else {
- // automatic friend approval
-
- Logger::log("Does an automatic friend approval for author ".$author.".", Logger::DEBUG);
+ $contact = [];
+ }
- Contact::updateAvatar($contact_record["photo"], $importer["uid"], $contact_record["id"]);
+ $item = ['author-id' => Contact::getIdForURL($ret['url']),
+ 'author-link' => $ret['url']];
- /*
- * technically they are sharing with us (Contact::SHARING),
- * but if our page-type is Profile::PAGE_COMMUNITY or Profile::PAGE_SOAPBOX
- * we are going to change the relationship and make them a follower.
- */
- if (($importer["page-flags"] == User::PAGE_FLAGS_FREELOVE) && $sharing && $following) {
- $new_relation = Contact::FRIEND;
- } elseif (($importer["page-flags"] == User::PAGE_FLAGS_FREELOVE) && $sharing) {
- $new_relation = Contact::SHARING;
- } else {
- $new_relation = Contact::FOLLOWER;
+ $result = Contact::addRelationship($importer, $contact, $item, false);
+ if ($result === true) {
+ $contact_record = self::contactByHandle($importer['uid'], $author);
+ if (!$contact_record) {
+ Logger::info('unable to locate newly created contact record.');
+ return;
}
- q(
- "UPDATE `contact` SET `rel` = %d,
- `name-date` = '%s',
- `uri-date` = '%s',
- `blocked` = 0,
- `pending` = 0,
- `writable` = 1
- WHERE `id` = %d
- ",
- intval($new_relation),
- DBA::escape(DateTimeFormat::utcNow()),
- DBA::escape(DateTimeFormat::utcNow()),
- intval($contact_record["id"])
- );
-
- $user = DBA::selectFirst('user', [], ['uid' => $importer["uid"]]);
+ $user = DBA::selectFirst('user', [], ['uid' => $importer['uid']]);
if (DBA::isResult($user)) {
- Logger::log("Sending share message (Relation: ".$new_relation.") to author ".$author." - Contact: ".$contact_record["id"]." - User: ".$importer["uid"], Logger::DEBUG);
self::sendShare($user, $contact_record);
// Send the profile data, maybe it weren't transmitted before
- self::sendProfile($importer["uid"], [$contact_record]);
+ self::sendProfile($importer['uid'], [$contact_record]);
}
}
use Friendica\Object\Image;
use Friendica\Protocol\ActivityNamespace;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Images;
use Friendica\Util\Network;
use Friendica\Util\Proxy as ProxyUtils;
use Friendica\Util\Strings;
switch ($siteinfo["type"]) {
case 'photo':
if (!empty($siteinfo["image"])) {
- $imgdata = Image::getInfoFromURL($siteinfo["image"]);
+ $imgdata = Images::getInfoFromURLCached($siteinfo["image"]);
if ($imgdata) {
$attributes = ["rel" => "enclosure",
"href" => $siteinfo["image"],
}
if (!Config::get('system', 'ostatus_not_attach_preview') && ($siteinfo["type"] != "photo") && isset($siteinfo["image"])) {
- $imgdata = Image::getInfoFromURL($siteinfo["image"]);
+ $imgdata = Images::getInfoFromURLCached($siteinfo["image"]);
if ($imgdata) {
$attributes = ["rel" => "enclosure",
"href" => $siteinfo["image"],
--- /dev/null
+<?php
+
+namespace Friendica\Util;
+
+use Friendica\BaseObject;
+use Friendica\Core\Cache;
+use Friendica\Core\Logger;
+use Friendica\Core\System;
+use Imagick;
+
+/**
+ * Image utilities
+ */
+class Images
+{
+ /**
+ * Maps Mime types to Imagick formats
+ *
+ * @return array
+ */
+ public static function getFormatsMap()
+ {
+ $m = [
+ 'image/jpeg' => 'JPG',
+ 'image/png' => 'PNG',
+ 'image/gif' => 'GIF'
+ ];
+
+ return $m;
+ }
+
+ /**
+ * Returns supported image mimetypes and corresponding file extensions
+ *
+ * @return array
+ */
+ public static function supportedTypes()
+ {
+ $types = [
+ 'image/jpeg' => 'jpg'
+ ];
+ if (class_exists('Imagick')) {
+ // Imagick::queryFormats won't help us a lot there...
+ // At least, not yet, other parts of friendica uses this array
+ $types += [
+ 'image/png' => 'png',
+ 'image/gif' => 'gif'
+ ];
+ } elseif (imagetypes() & IMG_PNG) {
+ $types += [
+ 'image/png' => 'png'
+ ];
+ }
+
+ return $types;
+ }
+
+ /**
+ * Guess image mimetype from filename or from Content-Type header
+ *
+ * @param string $filename Image filename
+ * @param boolean $fromcurl Check Content-Type header from curl request
+ * @param string $header passed headers to take into account
+ *
+ * @return string|null
+ * @throws \Exception
+ */
+ public static function guessType($filename, $fromcurl = false, $header = '')
+ {
+ Logger::info('Image: guessType: ' . $filename . ($fromcurl ? ' from curl headers' : ''));
+ $type = null;
+ if ($fromcurl) {
+ $headers = [];
+ $h = explode("\n", $header);
+ foreach ($h as $l) {
+ $data = array_map("trim", explode(":", trim($l), 2));
+ if (count($data) > 1) {
+ list($k, $v) = $data;
+ $headers[$k] = $v;
+ }
+ }
+
+ if (array_key_exists('Content-Type', $headers)) {
+ $type = $headers['Content-Type'];
+ }
+ }
+
+ if (is_null($type)) {
+ // Guessing from extension? Isn't that... dangerous?
+ if (class_exists('Imagick') && file_exists($filename) && is_readable($filename)) {
+ /**
+ * Well, this not much better,
+ * but at least it comes from the data inside the image,
+ * we won't be tricked by a manipulated extension
+ */
+ $image = new Imagick($filename);
+ $type = $image->getImageMimeType();
+ } else {
+ $ext = pathinfo($filename, PATHINFO_EXTENSION);
+ $types = self::supportedTypes();
+ $type = 'image/jpeg';
+ foreach ($types as $m => $e) {
+ if ($ext == $e) {
+ $type = $m;
+ }
+ }
+ }
+ }
+
+ Logger::info('Image: guessType: type=' . $type);
+ return $type;
+ }
+
+
+ /**
+ * @param string $url
+ * @return array
+ * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+ */
+ public static function getInfoFromURLCached($url)
+ {
+ $data = [];
+
+ if (empty($url)) {
+ return $data;
+ }
+
+ $data = Cache::get($url);
+
+ if (empty($data) || !is_array($data)) {
+ $data = self::getInfoFromURL($url);
+
+ Cache::set($url, $data);
+ }
+
+ return $data;
+ }
+
+ /**
+ * @param string $url
+ * @return array
+ * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+ */
+ public static function getInfoFromURL($url)
+ {
+ $data = [];
+
+ if (empty($url)) {
+ return $data;
+ }
+
+ $img_str = Network::fetchUrl($url, true, 4);
+
+ if (!$img_str) {
+ return [];
+ }
+
+ $filesize = strlen($img_str);
+
+ try {
+ if (function_exists("getimagesizefromstring")) {
+ $data = @getimagesizefromstring($img_str);
+ } else {
+ $tempfile = tempnam(get_temppath(), "cache");
+
+ $stamp1 = microtime(true);
+ file_put_contents($tempfile, $img_str);
+ BaseObject::getApp()->getProfiler()->saveTimestamp($stamp1, "file", System::callstack());
+
+ $data = getimagesize($tempfile);
+ unlink($tempfile);
+ }
+ } catch (\Exception $e) {
+ return [];
+ }
+
+ if ($data) {
+ $data['size'] = $filesize;
+ }
+
+ return $data;
+ }
+
+ /**
+ * @param integer $width
+ * @param integer $height
+ * @param integer $max
+ * @return array
+ */
+ public static function getScalingDimensions($width, $height, $max)
+ {
+ if ((!$width) || (!$height)) {
+ return ['width' => 0, 'height' => 0];
+ }
+
+ if ($width > $max && $height > $max) {
+ // very tall image (greater than 16:9)
+ // constrain the width - let the height float.
+
+ if ((($height * 9) / 16) > $width) {
+ $dest_width = $max;
+ $dest_height = intval(($height * $max) / $width);
+ } elseif ($width > $height) {
+ // else constrain both dimensions
+ $dest_width = $max;
+ $dest_height = intval(($height * $max) / $width);
+ } else {
+ $dest_width = intval(($width * $max) / $height);
+ $dest_height = $max;
+ }
+ } else {
+ if ($width > $max) {
+ $dest_width = $max;
+ $dest_height = intval(($height * $max) / $width);
+ } else {
+ if ($height > $max) {
+ // very tall image (greater than 16:9)
+ // but width is OK - don't do anything
+
+ if ((($height * 9) / 16) > $width) {
+ $dest_width = $width;
+ $dest_height = $height;
+ } else {
+ $dest_width = intval(($width * $max) / $height);
+ $dest_height = $max;
+ }
+ } else {
+ $dest_width = $width;
+ $dest_height = $height;
+ }
+ }
+ }
+
+ return ['width' => $dest_width, 'height' => $dest_height];
+ }
+}
use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\Database\DBA;
-use Friendica\Object\Image;
/**
* @brief Class with methods for extracting certain content from an url
}
$src = self::completeUrl($img_tag['src'], $url);
- $photodata = Image::getInfoFromURL($src);
+ $photodata = Images::getInfoFromURLCached($src);
if (($photodata) && ($photodata[0] > 150) && ($photodata[1] > 150)) {
if ($photodata[0] > 300) {
unset($siteinfo['image']);
- $photodata = Image::getInfoFromURL($src);
+ $photodata = Images::getInfoFromURLCached($src);
if (($photodata) && ($photodata[0] > 10) && ($photodata[1] > 10)) {
$siteinfo['images'][] = ['src' => $src,
"iid" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "primary" => "1", "relation" => ["item" => "id"], "comment" => "Item id"],
"uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "primary" => "1", "relation" => ["user" => "uid"], "comment" => "User id"],
"hidden" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Marker to hide an item from the user"],
- "ignored" => ["type" => "boolean", "comment" => "Ignore this thread if set"]
+ "ignored" => ["type" => "boolean", "comment" => "Ignore this thread if set"],
+ "pinned" => ["type" => "boolean", "comment" => "The item is pinned on the profile page"]
],
"indexes" => [
- "PRIMARY" => ["uid", "iid"]
+ "PRIMARY" => ["uid", "iid"],
+ "uid_pinned" => ["uid", "pinned"]
]
],
"worker-ipc" => [
$_SERVER, null
],
'call' => [
- ['addRoutes', [include __DIR__ . '/routes.config.php'], Dice::CHAIN_CALL],
+ ['loadRoutes', [include __DIR__ . '/routes.config.php'], Dice::CHAIN_CALL],
],
],
L10n::class => [
'/compose[/{type}]' => [Module\Item\Compose::class, [R::GET, R::POST]],
'/contact' => [
- '[/]' => [Module\Contact::class, [R::GET]],
- '/{id:\d+}[/]' => [Module\Contact::class, [R::GET, R::POST]],
- '/{id:\d+}/archive' => [Module\Contact::class, [R::GET]],
- '/{id:\d+}/block' => [Module\Contact::class, [R::GET]],
- '/{id:\d+}/conversations' => [Module\Contact::class, [R::GET]],
- '/{id:\d+}/drop' => [Module\Contact::class, [R::GET]],
- '/{id:\d+}/ignore' => [Module\Contact::class, [R::GET]],
- '/{id:\d+}/posts' => [Module\Contact::class, [R::GET]],
- '/{id:\d+}/update' => [Module\Contact::class, [R::GET]],
- '/{id:\d+}/updateprofile' => [Module\Contact::class, [R::GET]],
- '/archived' => [Module\Contact::class, [R::GET]],
- '/batch' => [Module\Contact::class, [R::GET, R::POST]],
- '/pending' => [Module\Contact::class, [R::GET]],
- '/blocked' => [Module\Contact::class, [R::GET]],
- '/hidden' => [Module\Contact::class, [R::GET]],
- '/ignored' => [Module\Contact::class, [R::GET]],
+ '[/]' => [Module\Contact::class, [R::GET]],
+ '/{id:\d+}[/]' => [Module\Contact::class, [R::GET, R::POST]],
+ '/{id:\d+}/archive' => [Module\Contact::class, [R::GET]],
+ '/{id:\d+}/block' => [Module\Contact::class, [R::GET]],
+ '/{id:\d+}/conversations' => [Module\Contact::class, [R::GET]],
+ '/{id:\d+}/drop' => [Module\Contact::class, [R::GET]],
+ '/{id:\d+}/ignore' => [Module\Contact::class, [R::GET]],
+ '/{id:\d+}/posts' => [Module\Contact::class, [R::GET]],
+ '/{id:\d+}/update' => [Module\Contact::class, [R::GET]],
+ '/{id:\d+}/updateprofile' => [Module\Contact::class, [R::GET]],
+ '/archived' => [Module\Contact::class, [R::GET]],
+ '/batch' => [Module\Contact::class, [R::GET, R::POST]],
+ '/pending' => [Module\Contact::class, [R::GET]],
+ '/blocked' => [Module\Contact::class, [R::GET]],
+ '/hidden' => [Module\Contact::class, [R::GET]],
+ '/ignored' => [Module\Contact::class, [R::GET]],
+ '/hovercard' => [Module\Contact\Hovercard::class, [R::GET]],
],
+
'/credits' => [Module\Credits::class, [R::GET]],
'/delegation'=> [Module\Delegation::class, [R::GET, R::POST]],
'/dirfind' => [Module\Search\Directory::class, [R::GET]],
'/{type}/{customize}/{name}' => [Module\Photo::class, [R::GET]],
],
- '/pretheme' => [Module\ThemeDetails::class, [R::GET]],
- '/probe' => [Module\Debug\Probe::class, [R::GET]],
+ '/pinned/{item:\d+}' => [Module\Pinned::class, [R::GET]],
+ '/pretheme' => [Module\ThemeDetails::class, [R::GET]],
+ '/probe' => [Module\Debug\Probe::class, [R::GET]],
'/profile' => [
'/{nickname}' => [Module\Profile::class, [R::GET]],
'/verify' => [Module\Settings\TwoFactor\Verify::class, [R::GET, R::POST]],
],
'/delegation[/{action}/{user_id}]' => [Module\Settings\Delegation::class, [R::GET, R::POST]],
+ '/userexport[/{action}]' => [Module\Settings\UserExport::class, [R::GET, R::POST]],
],
'/randprof' => [Module\RandomProfile::class, [R::GET]],
// The fully-qualified URL of this Friendica node.
// Used by the worker in a non-HTTP execution environment.
'url' => '',
+
+ // max_csv_file_size (Integer)
+ // When uploading a CSV with account addresses to follow
+ // in the user settings, this controls the maximum file
+ // size of the upload file.
+ 'max_csv_file_size' => 30720,
],
// Used in the admin settings to lock certain features
public function testIsBackendButIndex()
{
$server = [];
- $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, true);
+ $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, [], true);
$mobileDetect = new MobileDetect();
$mode = (new Mode())->determineRunMode(false, $module, $server, $mobileDetect);
public function testIsNotBackend()
{
$server = [];
- $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, false);
+ $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, [], false);
$mobileDetect = new MobileDetect();
$mode = (new Mode())->determineRunMode(false, $module, $server, $mobileDetect);
'HTTP_X_REQUESTED_WITH' => 'xmlhttprequest',
];
- $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, false);
+ $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, [], false);
$mobileDetect = new MobileDetect();
$mode = (new Mode())->determineRunMode(true, $module, $server, $mobileDetect);
public function testIsNotAjax()
{
$server = [];
- $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, false);
+ $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, [], false);
$mobileDetect = new MobileDetect();
$mode = (new Mode())->determineRunMode(true, $module, $server, $mobileDetect);
public function testIsMobileIsTablet()
{
$server = [];
- $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, false);
+ $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, [], false);
$mobileDetect = \Mockery::mock(MobileDetect::class);
$mobileDetect->shouldReceive('isMobile')->andReturn(true);
$mobileDetect->shouldReceive('isTablet')->andReturn(true);
public function testIsNotMobileIsNotTablet()
{
$server = [];
- $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, false);
+ $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, [], false);
$mobileDetect = \Mockery::mock(MobileDetect::class);
$mobileDetect->shouldReceive('isMobile')->andReturn(false);
$mobileDetect->shouldReceive('isTablet')->andReturn(false);
$config = \Mockery::mock(Configuration::class);
$config->shouldReceive('get')->with('config', 'private_addons', false)->andReturn($privAdd)->atMost()->once();
- $router = (new App\Router([]))->addRoutes(include __DIR__ . '/../../../static/routes.config.php');
+ $router = (new App\Router([]))->loadRoutes(include __DIR__ . '/../../../static/routes.config.php');
$module = (new App\Module($name))->determineClass(new App\Arguments('', $command), $router, $config);
{
$router = (new Router([
'REQUEST_METHOD' => Router::GET
- ]))->addRoutes($routes);
+ ]))->loadRoutes($routes);
$this->assertEquals(Module\Home::class, $router->getModuleClass('/'));
$this->assertEquals(Module\Friendica::class, $router->getModuleClass('/group/route'));
{
$router = (new Router([
'REQUEST_METHOD' => Router::POST
- ]))->addRoutes($routes);
+ ]))->loadRoutes($routes);
// Don't find GET
$this->assertEquals(Module\NodeInfo::class, $router->getModuleClass('/post/it'));
*/
public function testImagick()
{
- $this->l10nMock->shouldReceive('t')->andReturnUsing(function ($args) { return $args; });
+ $this->markTestIncomplete('needs adapted class_exists() mock');
- $imageMock = \Mockery::mock('alias:'. Image::class);
- $imageMock
- ->shouldReceive('supportedTypes')
- ->andReturn(['image/gif' => 'gif']);
+ $this->l10nMock->shouldReceive('t')->andReturnUsing(function ($args) { return $args; });
$this->setClasses(['Imagick' => true]);
{
$this->l10nMock->shouldReceive('t')->andReturnUsing(function ($args) { return $args; });
- $imageMock = \Mockery::mock('alias:' . Image::class);
- $imageMock
- ->shouldReceive('supportedTypes')
- ->andReturn([]);
-
$this->setClasses(['Imagick' => true]);
$install = new Installer();
});
}
+function dopin(ident) {
+ ident = ident.toString();
+ $('#like-rotator-' + ident).show();
+ $.get('pinned/' + ident, function(data) {
+ if (data.match(/1/)) {
+ $('#pinned-' + ident).addClass('pinned');
+ $('#pinned-' + ident).removeClass('unpinned');
+ $('#pin-' + ident).addClass('hidden');
+ $('#unpin-' + ident).removeClass('hidden');
+ } else {
+ $('#pinned-' + ident).addClass('unpinned');
+ $('#pinned-' + ident).removeClass('pinned');
+ $('#pin-' + ident).removeClass('hidden');
+ $('#unpin-' + ident).addClass('hidden');
+ }
+ $('#like-rotator-' + ident).hide();
+ });
+}
+
function doignore(ident) {
ident = ident.toString();
$('#like-rotator-' + ident).show();
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-09-15 07:45+0200\n"
+"POT-Creation-Date: 2019-11-04 10:26+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Content-Transfer-Encoding: 8bit\n"
-#: include/items.php:354 src/Module/Admin/Themes/Details.php:53
-#: src/Module/Admin/Themes/Index.php:43 src/Module/Debug/ItemBody.php:27
-#: src/Module/Debug/ItemBody.php:40
-msgid "Item not found."
-msgstr ""
-
-#: include/items.php:392
-msgid "Do you really want to delete this item?"
-msgstr ""
-
-#: include/items.php:394 mod/api.php:109 mod/profiles.php:526
-#: mod/profiles.php:529 mod/profiles.php:551 mod/dfrn_request.php:640
-#: mod/follow.php:163 mod/message.php:150 mod/suggest.php:73
-#: mod/settings.php:1089 mod/settings.php:1095 mod/settings.php:1102
-#: mod/settings.php:1106 mod/settings.php:1110 mod/settings.php:1114
-#: mod/settings.php:1118 mod/settings.php:1122 mod/settings.php:1142
-#: mod/settings.php:1143 mod/settings.php:1144 mod/settings.php:1145
-#: mod/settings.php:1146 src/Module/Register.php:97 src/Module/Contact.php:423
-msgid "Yes"
-msgstr ""
-
-#: include/items.php:397 include/conversation.php:1251 mod/tagrm.php:20
-#: mod/tagrm.php:115 mod/unfollow.php:132 mod/dfrn_request.php:650
-#: mod/editpost.php:110 mod/fbrowser.php:110 mod/fbrowser.php:139
-#: mod/follow.php:174 mod/message.php:153 mod/photos.php:1084
-#: mod/photos.php:1191 mod/suggest.php:76 mod/settings.php:678
-#: mod/settings.php:704 src/Module/Contact.php:426
-msgid "Cancel"
-msgstr ""
-
-#: include/items.php:444 mod/api.php:34 mod/api.php:39 mod/delegate.php:30
-#: mod/delegate.php:48 mod/delegate.php:59 mod/ostatus_subscribe.php:18
-#: mod/regmod.php:89 mod/repair_ostatus.php:16 mod/uimport.php:17
-#: mod/unfollow.php:22 mod/unfollow.php:77 mod/unfollow.php:109
-#: mod/wall_attach.php:76 mod/wall_attach.php:79 mod/wall_upload.php:107
-#: mod/wall_upload.php:110 mod/wallmessage.php:19 mod/wallmessage.php:43
-#: mod/wallmessage.php:82 mod/wallmessage.php:106 mod/profiles.php:182
-#: mod/profiles.php:499 mod/cal.php:301 mod/common.php:27 mod/crepair.php:90
-#: mod/dfrn_confirm.php:64 mod/editpost.php:21 mod/follow.php:57
-#: mod/follow.php:134 mod/fsuggest.php:63 mod/manage.php:130 mod/message.php:56
-#: mod/message.php:101 mod/network.php:37 mod/notes.php:27 mod/photos.php:178
-#: mod/photos.php:962 mod/poke.php:141 mod/profile_photo.php:32
-#: mod/profile_photo.php:177 mod/profile_photo.php:197 mod/suggest.php:39
-#: mod/events.php:208 mod/item.php:170 mod/notifications.php:73
-#: mod/settings.php:52 mod/settings.php:165 mod/settings.php:667
-#: src/Module/Attach.php:42 src/Module/FollowConfirm.php:27
-#: src/Module/Group.php:31 src/Module/Group.php:77 src/Module/Invite.php:22
-#: src/Module/Invite.php:110 src/Module/Notifications/Notify.php:19
-#: src/Module/Profile/Contacts.php:50 src/Module/Register.php:192
-#: src/Module/Search/Directory.php:18 src/Module/Contact.php:340
-msgid "Permission denied."
-msgstr ""
-
-#: include/api.php:1119
+#: include/api.php:1121
#, php-format
msgid "Daily posting limit of %d post reached. The post was rejected."
msgid_plural "Daily posting limit of %d posts reached. The post was rejected."
msgstr[0] ""
msgstr[1] ""
-#: include/api.php:1133
+#: include/api.php:1135
#, php-format
msgid "Weekly posting limit of %d post reached. The post was rejected."
msgid_plural "Weekly posting limit of %d posts reached. The post was rejected."
msgstr[0] ""
msgstr[1] ""
-#: include/api.php:1147
+#: include/api.php:1149
#, php-format
msgid "Monthly posting limit of %d post reached. The post was rejected."
msgstr ""
-#: include/api.php:4589 mod/photos.php:91 mod/photos.php:196 mod/photos.php:640
-#: mod/photos.php:1090 mod/photos.php:1107 mod/photos.php:1610
-#: mod/profile_photo.php:85 mod/profile_photo.php:94 mod/profile_photo.php:103
-#: mod/profile_photo.php:210 mod/profile_photo.php:298
-#: mod/profile_photo.php:308 src/Model/User.php:796 src/Model/User.php:804
-#: src/Model/User.php:812
+#: include/api.php:4566 mod/profile_photo.php:85 mod/profile_photo.php:94
+#: mod/profile_photo.php:103 mod/profile_photo.php:210
+#: mod/profile_photo.php:298 mod/profile_photo.php:308 mod/photos.php:90
+#: mod/photos.php:181 mod/photos.php:628 mod/photos.php:1055
+#: mod/photos.php:1072 mod/photos.php:1580 src/Model/User.php:841
+#: src/Model/User.php:849 src/Model/User.php:857
msgid "Profile Photos"
msgstr ""
-#: include/conversation.php:161 include/conversation.php:298
-#: src/Model/Item.php:3309
+#: include/conversation.php:167 include/conversation.php:304
+#: src/Model/Item.php:3322
msgid "event"
msgstr ""
-#: include/conversation.php:164 include/conversation.php:174
-#: include/conversation.php:301 include/conversation.php:310
-#: mod/subthread.php:88 mod/tagger.php:69
+#: include/conversation.php:170 include/conversation.php:180
+#: include/conversation.php:307 include/conversation.php:316
+#: mod/subthread.php:91 mod/tagger.php:72
msgid "status"
msgstr ""
-#: include/conversation.php:169 include/conversation.php:306
-#: mod/subthread.php:88 mod/tagger.php:69 src/Model/Item.php:3311
+#: include/conversation.php:175 include/conversation.php:312
+#: mod/subthread.php:91 mod/tagger.php:72 src/Model/Item.php:3324
msgid "photo"
msgstr ""
-#: include/conversation.php:182
+#: include/conversation.php:188
#, php-format
msgid "%1$s likes %2$s's %3$s"
msgstr ""
-#: include/conversation.php:184
+#: include/conversation.php:190
#, php-format
msgid "%1$s doesn't like %2$s's %3$s"
msgstr ""
-#: include/conversation.php:186
+#: include/conversation.php:192
#, php-format
msgid "%1$s attends %2$s's %3$s"
msgstr ""
-#: include/conversation.php:188
+#: include/conversation.php:194
#, php-format
msgid "%1$s doesn't attend %2$s's %3$s"
msgstr ""
-#: include/conversation.php:190
+#: include/conversation.php:196
#, php-format
msgid "%1$s attends maybe %2$s's %3$s"
msgstr ""
-#: include/conversation.php:225
+#: include/conversation.php:231
#, php-format
msgid "%1$s is now friends with %2$s"
msgstr ""
-#: include/conversation.php:266
+#: include/conversation.php:272
#, php-format
msgid "%1$s poked %2$s"
msgstr ""
-#: include/conversation.php:320 mod/tagger.php:102
+#: include/conversation.php:326 mod/tagger.php:105
#, php-format
msgid "%1$s tagged %2$s's %3$s with %4$s"
msgstr ""
-#: include/conversation.php:342
+#: include/conversation.php:348
msgid "post/item"
msgstr ""
-#: include/conversation.php:343
+#: include/conversation.php:349
#, php-format
msgid "%1$s marked %2$s's %3$s as favorite"
msgstr ""
-#: include/conversation.php:569 mod/profiles.php:352 mod/photos.php:1442
+#: include/conversation.php:574 mod/photos.php:1407 mod/profiles.php:352
msgid "Likes"
msgstr ""
-#: include/conversation.php:570 mod/profiles.php:355 mod/photos.php:1442
+#: include/conversation.php:575 mod/photos.php:1407 mod/profiles.php:355
msgid "Dislikes"
msgstr ""
-#: include/conversation.php:571 include/conversation.php:1566
-#: mod/photos.php:1443
+#: include/conversation.php:576 include/conversation.php:1577
+#: mod/photos.php:1408
msgid "Attending"
msgid_plural "Attending"
msgstr[0] ""
msgstr[1] ""
-#: include/conversation.php:572 mod/photos.php:1443
+#: include/conversation.php:577 mod/photos.php:1408
msgid "Not attending"
msgstr ""
-#: include/conversation.php:573 mod/photos.php:1443
+#: include/conversation.php:578 mod/photos.php:1408
msgid "Might attend"
msgstr ""
-#: include/conversation.php:574
+#: include/conversation.php:579
msgid "Reshares"
msgstr ""
-#: include/conversation.php:654 mod/photos.php:1499 src/Object/Post.php:209
+#: include/conversation.php:659 mod/photos.php:1469 src/Object/Post.php:206
msgid "Select"
msgstr ""
-#: include/conversation.php:655 mod/photos.php:1500 mod/settings.php:738
-#: src/Module/Admin/Users.php:288 src/Module/Contact.php:805
-#: src/Module/Contact.php:1086
+#: include/conversation.php:660 mod/photos.php:1470 mod/settings.php:730
+#: src/Module/Admin/Users.php:288 src/Module/Contact.php:826
+#: src/Module/Contact.php:1107
msgid "Delete"
msgstr ""
-#: include/conversation.php:681 src/Object/Post.php:383 src/Object/Post.php:384
+#: include/conversation.php:689 src/Object/Post.php:383 src/Object/Post.php:384
#, php-format
msgid "View %s's profile @ %s"
msgstr ""
-#: include/conversation.php:694 src/Object/Post.php:371
+#: include/conversation.php:702 src/Object/Post.php:371
msgid "Categories:"
msgstr ""
-#: include/conversation.php:695 src/Object/Post.php:372
+#: include/conversation.php:703 src/Object/Post.php:372
msgid "Filed under:"
msgstr ""
-#: include/conversation.php:702 src/Object/Post.php:397
+#: include/conversation.php:710 src/Object/Post.php:397
#, php-format
msgid "%s from %s"
msgstr ""
-#: include/conversation.php:717
+#: include/conversation.php:725
msgid "View in context"
msgstr ""
-#: include/conversation.php:719 include/conversation.php:1232
-#: mod/wallmessage.php:141 mod/editpost.php:86 mod/message.php:260
-#: mod/message.php:442 mod/photos.php:1415 src/Module/Item/Compose.php:193
+#: include/conversation.php:727 include/conversation.php:1243
+#: mod/editpost.php:87 mod/message.php:260 mod/message.php:442
+#: mod/photos.php:1380 mod/wallmessage.php:141 src/Module/Item/Compose.php:197
#: src/Object/Post.php:424
msgid "Please wait"
msgstr ""
-#: include/conversation.php:783
+#: include/conversation.php:791
msgid "remove"
msgstr ""
-#: include/conversation.php:787
+#: include/conversation.php:795
msgid "Delete Selected Items"
msgstr ""
-#: include/conversation.php:942 view/theme/frio/theme.php:363
+#: include/conversation.php:950 view/theme/frio/theme.php:363
msgid "Follow Thread"
msgstr ""
-#: include/conversation.php:943 src/Model/Contact.php:1225
+#: include/conversation.php:951 src/Model/Contact.php:1255
msgid "View Status"
msgstr ""
-#: include/conversation.php:944 include/conversation.php:962 mod/match.php:87
-#: mod/suggest.php:87 src/Model/Contact.php:1165 src/Model/Contact.php:1218
-#: src/Model/Contact.php:1226 src/Module/AllFriends.php:74
-#: src/Module/BaseSearchModule.php:133 src/Module/Directory.php:150
+#: include/conversation.php:952 include/conversation.php:970 mod/suggest.php:87
+#: mod/match.php:87 src/Model/Contact.php:1185 src/Model/Contact.php:1247
+#: src/Model/Contact.php:1256 src/Module/AllFriends.php:74
+#: src/Module/BaseSearchModule.php:137 src/Module/Directory.php:148
msgid "View Profile"
msgstr ""
-#: include/conversation.php:945 src/Model/Contact.php:1227
+#: include/conversation.php:953 src/Model/Contact.php:1257
msgid "View Photos"
msgstr ""
-#: include/conversation.php:946 src/Model/Contact.php:1219
-#: src/Model/Contact.php:1228
+#: include/conversation.php:954 src/Model/Contact.php:1248
+#: src/Model/Contact.php:1258
msgid "Network Posts"
msgstr ""
-#: include/conversation.php:947 src/Model/Contact.php:1220
-#: src/Model/Contact.php:1229
+#: include/conversation.php:955 src/Model/Contact.php:1249
+#: src/Model/Contact.php:1259
msgid "View Contact"
msgstr ""
-#: include/conversation.php:948 src/Model/Contact.php:1231
+#: include/conversation.php:956 src/Model/Contact.php:1261
msgid "Send PM"
msgstr ""
-#: include/conversation.php:949 src/Module/Admin/Blocklist/Contact.php:67
-#: src/Module/Admin/Users.php:289 src/Module/Contact.php:585
-#: src/Module/Contact.php:802 src/Module/Contact.php:1061
+#: include/conversation.php:957 src/Module/Admin/Blocklist/Contact.php:67
+#: src/Module/Admin/Users.php:289 src/Module/Contact.php:606
+#: src/Module/Contact.php:823 src/Module/Contact.php:1082
msgid "Block"
msgstr ""
-#: include/conversation.php:950 mod/notifications.php:63
-#: mod/notifications.php:197 mod/notifications.php:290
-#: src/Module/Contact.php:586 src/Module/Contact.php:803
-#: src/Module/Contact.php:1069
+#: include/conversation.php:958 mod/notifications.php:66
+#: mod/notifications.php:201 mod/notifications.php:294
+#: src/Module/Contact.php:607 src/Module/Contact.php:824
+#: src/Module/Contact.php:1090
msgid "Ignore"
msgstr ""
-#: include/conversation.php:954 src/Model/Contact.php:1232
+#: include/conversation.php:962 src/Model/Contact.php:1262
msgid "Poke"
msgstr ""
-#: include/conversation.php:959 mod/match.php:88 mod/follow.php:160
-#: mod/suggest.php:88 view/theme/vier/theme.php:201 src/Content/Widget.php:66
-#: src/Model/Contact.php:1221 src/Module/AllFriends.php:75
-#: src/Module/BaseSearchModule.php:134
+#: include/conversation.php:967 mod/suggest.php:88 mod/follow.php:160
+#: mod/match.php:88 view/theme/vier/theme.php:178 src/Content/Widget.php:67
+#: src/Model/Contact.php:1250 src/Model/Contact.php:1263
+#: src/Module/AllFriends.php:75 src/Module/BaseSearchModule.php:138
msgid "Connect/Follow"
msgstr ""
-#: include/conversation.php:1084
+#: include/conversation.php:1095
#, php-format
msgid "%s likes this."
msgstr ""
-#: include/conversation.php:1087
+#: include/conversation.php:1098
#, php-format
msgid "%s doesn't like this."
msgstr ""
-#: include/conversation.php:1090
+#: include/conversation.php:1101
#, php-format
msgid "%s attends."
msgstr ""
-#: include/conversation.php:1093
+#: include/conversation.php:1104
#, php-format
msgid "%s doesn't attend."
msgstr ""
-#: include/conversation.php:1096
+#: include/conversation.php:1107
#, php-format
msgid "%s attends maybe."
msgstr ""
-#: include/conversation.php:1099 include/conversation.php:1142
+#: include/conversation.php:1110 include/conversation.php:1153
#, php-format
msgid "%s reshared this."
msgstr ""
-#: include/conversation.php:1107
+#: include/conversation.php:1118
msgid "and"
msgstr ""
-#: include/conversation.php:1113
+#: include/conversation.php:1124
#, php-format
msgid "and %d other people"
msgstr ""
-#: include/conversation.php:1121
+#: include/conversation.php:1132
#, php-format
msgid "<span %1$s>%2$d people</span> like this"
msgstr ""
-#: include/conversation.php:1122
+#: include/conversation.php:1133
#, php-format
msgid "%s like this."
msgstr ""
-#: include/conversation.php:1125
+#: include/conversation.php:1136
#, php-format
msgid "<span %1$s>%2$d people</span> don't like this"
msgstr ""
-#: include/conversation.php:1126
+#: include/conversation.php:1137
#, php-format
msgid "%s don't like this."
msgstr ""
-#: include/conversation.php:1129
+#: include/conversation.php:1140
#, php-format
msgid "<span %1$s>%2$d people</span> attend"
msgstr ""
-#: include/conversation.php:1130
+#: include/conversation.php:1141
#, php-format
msgid "%s attend."
msgstr ""
-#: include/conversation.php:1133
+#: include/conversation.php:1144
#, php-format
msgid "<span %1$s>%2$d people</span> don't attend"
msgstr ""
-#: include/conversation.php:1134
+#: include/conversation.php:1145
#, php-format
msgid "%s don't attend."
msgstr ""
-#: include/conversation.php:1137
+#: include/conversation.php:1148
#, php-format
msgid "<span %1$s>%2$d people</span> attend maybe"
msgstr ""
-#: include/conversation.php:1138
+#: include/conversation.php:1149
#, php-format
msgid "%s attend maybe."
msgstr ""
-#: include/conversation.php:1141
+#: include/conversation.php:1152
#, php-format
msgid "<span %1$s>%2$d people</span> reshared this"
msgstr ""
-#: include/conversation.php:1171
+#: include/conversation.php:1182
msgid "Visible to <strong>everybody</strong>"
msgstr ""
-#: include/conversation.php:1172 src/Module/Item/Compose.php:187
-#: src/Object/Post.php:888
+#: include/conversation.php:1183 src/Module/Item/Compose.php:191
+#: src/Object/Post.php:893
msgid "Please enter a image/video/audio/webpage URL:"
msgstr ""
-#: include/conversation.php:1173
+#: include/conversation.php:1184
msgid "Tag term:"
msgstr ""
-#: include/conversation.php:1174 src/Module/Filer/SaveTag.php:48
+#: include/conversation.php:1185 src/Module/Filer/SaveTag.php:48
msgid "Save to Folder:"
msgstr ""
-#: include/conversation.php:1175
+#: include/conversation.php:1186
msgid "Where are you right now?"
msgstr ""
-#: include/conversation.php:1176
+#: include/conversation.php:1187
msgid "Delete item(s)?"
msgstr ""
-#: include/conversation.php:1208
+#: include/conversation.php:1219
msgid "New Post"
msgstr ""
-#: include/conversation.php:1211
+#: include/conversation.php:1222
msgid "Share"
msgstr ""
-#: include/conversation.php:1212 mod/wallmessage.php:139 mod/editpost.php:72
-#: mod/message.php:258 mod/message.php:439
+#: include/conversation.php:1223 mod/editpost.php:73 mod/message.php:258
+#: mod/message.php:439 mod/wallmessage.php:139
msgid "Upload photo"
msgstr ""
-#: include/conversation.php:1213 mod/editpost.php:73
+#: include/conversation.php:1224 mod/editpost.php:74
msgid "upload photo"
msgstr ""
-#: include/conversation.php:1214 mod/editpost.php:74
+#: include/conversation.php:1225 mod/editpost.php:75
msgid "Attach file"
msgstr ""
-#: include/conversation.php:1215 mod/editpost.php:75
+#: include/conversation.php:1226 mod/editpost.php:76
msgid "attach file"
msgstr ""
-#: include/conversation.php:1216 src/Module/Item/Compose.php:179
-#: src/Object/Post.php:880
+#: include/conversation.php:1227 src/Module/Item/Compose.php:183
+#: src/Object/Post.php:885
msgid "Bold"
msgstr ""
-#: include/conversation.php:1217 src/Module/Item/Compose.php:180
-#: src/Object/Post.php:881
+#: include/conversation.php:1228 src/Module/Item/Compose.php:184
+#: src/Object/Post.php:886
msgid "Italic"
msgstr ""
-#: include/conversation.php:1218 src/Module/Item/Compose.php:181
-#: src/Object/Post.php:882
+#: include/conversation.php:1229 src/Module/Item/Compose.php:185
+#: src/Object/Post.php:887
msgid "Underline"
msgstr ""
-#: include/conversation.php:1219 src/Module/Item/Compose.php:182
-#: src/Object/Post.php:883
+#: include/conversation.php:1230 src/Module/Item/Compose.php:186
+#: src/Object/Post.php:888
msgid "Quote"
msgstr ""
-#: include/conversation.php:1220 src/Module/Item/Compose.php:183
-#: src/Object/Post.php:884
+#: include/conversation.php:1231 src/Module/Item/Compose.php:187
+#: src/Object/Post.php:889
msgid "Code"
msgstr ""
-#: include/conversation.php:1221 src/Module/Item/Compose.php:184
-#: src/Object/Post.php:885
+#: include/conversation.php:1232 src/Module/Item/Compose.php:188
+#: src/Object/Post.php:890
msgid "Image"
msgstr ""
-#: include/conversation.php:1222 src/Module/Item/Compose.php:185
-#: src/Object/Post.php:886
+#: include/conversation.php:1233 src/Module/Item/Compose.php:189
+#: src/Object/Post.php:891
msgid "Link"
msgstr ""
-#: include/conversation.php:1223 src/Module/Item/Compose.php:186
-#: src/Object/Post.php:887
+#: include/conversation.php:1234 src/Module/Item/Compose.php:190
+#: src/Object/Post.php:892
msgid "Link or Media"
msgstr ""
-#: include/conversation.php:1224 mod/editpost.php:82
-#: src/Module/Item/Compose.php:189
+#: include/conversation.php:1235 mod/editpost.php:83
+#: src/Module/Item/Compose.php:193
msgid "Set your location"
msgstr ""
-#: include/conversation.php:1225 mod/editpost.php:83
+#: include/conversation.php:1236 mod/editpost.php:84
msgid "set location"
msgstr ""
-#: include/conversation.php:1226 mod/editpost.php:84
+#: include/conversation.php:1237 mod/editpost.php:85
msgid "Clear browser location"
msgstr ""
-#: include/conversation.php:1227 mod/editpost.php:85
+#: include/conversation.php:1238 mod/editpost.php:86
msgid "clear location"
msgstr ""
-#: include/conversation.php:1229 mod/editpost.php:99
-#: src/Module/Item/Compose.php:194
+#: include/conversation.php:1240 mod/editpost.php:100
+#: src/Module/Item/Compose.php:198
msgid "Set title"
msgstr ""
-#: include/conversation.php:1231 mod/editpost.php:101
-#: src/Module/Item/Compose.php:195
+#: include/conversation.php:1242 mod/editpost.php:102
+#: src/Module/Item/Compose.php:199
msgid "Categories (comma-separated list)"
msgstr ""
-#: include/conversation.php:1233 mod/editpost.php:87
+#: include/conversation.php:1244 mod/editpost.php:88
msgid "Permission settings"
msgstr ""
-#: include/conversation.php:1234 mod/editpost.php:116
+#: include/conversation.php:1245 mod/editpost.php:117
msgid "permissions"
msgstr ""
-#: include/conversation.php:1243 mod/editpost.php:96
+#: include/conversation.php:1254 mod/editpost.php:97
msgid "Public post"
msgstr ""
-#: include/conversation.php:1247 mod/editpost.php:107 mod/photos.php:1433
-#: mod/photos.php:1472 mod/photos.php:1532 mod/events.php:550
-#: src/Module/Item/Compose.php:188 src/Object/Post.php:889
+#: include/conversation.php:1258 mod/editpost.php:108 mod/events.php:556
+#: mod/photos.php:1398 mod/photos.php:1437 mod/photos.php:1502
+#: src/Module/Item/Compose.php:192 src/Object/Post.php:894
msgid "Preview"
msgstr ""
-#: include/conversation.php:1256
+#: include/conversation.php:1262 include/items.php:392 mod/suggest.php:76
+#: mod/dfrn_request.php:652 mod/editpost.php:111 mod/fbrowser.php:110
+#: mod/fbrowser.php:139 mod/follow.php:174 mod/message.php:153
+#: mod/photos.php:1049 mod/photos.php:1156 mod/settings.php:670
+#: mod/settings.php:696 mod/tagrm.php:20 mod/tagrm.php:115 mod/unfollow.php:132
+#: src/Module/Contact.php:447
+msgid "Cancel"
+msgstr ""
+
+#: include/conversation.php:1267
msgid "Post to Groups"
msgstr ""
-#: include/conversation.php:1257
+#: include/conversation.php:1268
msgid "Post to Contacts"
msgstr ""
-#: include/conversation.php:1258
+#: include/conversation.php:1269
msgid "Private post"
msgstr ""
-#: include/conversation.php:1263 mod/editpost.php:114 src/Model/Profile.php:550
-#: src/Module/Contact.php:301
+#: include/conversation.php:1274 mod/editpost.php:115 src/Model/Profile.php:546
+#: src/Module/Contact.php:322
msgid "Message"
msgstr ""
-#: include/conversation.php:1264 mod/editpost.php:115
+#: include/conversation.php:1275 mod/editpost.php:116
msgid "Browser"
msgstr ""
-#: include/conversation.php:1536
+#: include/conversation.php:1547
msgid "View all"
msgstr ""
-#: include/conversation.php:1560
+#: include/conversation.php:1571
msgid "Like"
msgid_plural "Likes"
msgstr[0] ""
msgstr[1] ""
-#: include/conversation.php:1563
+#: include/conversation.php:1574
msgid "Dislike"
msgid_plural "Dislikes"
msgstr[0] ""
msgstr[1] ""
-#: include/conversation.php:1569
+#: include/conversation.php:1580
msgid "Not Attending"
msgid_plural "Not Attending"
msgstr[0] ""
msgstr[1] ""
-#: include/conversation.php:1572 src/Content/ContactSelector.php:243
+#: include/conversation.php:1583 src/Content/ContactSelector.php:243
msgid "Undecided"
msgid_plural "Undecided"
msgstr[0] ""
msgstr[1] ""
-#: include/enotify.php:57
+#: include/enotify.php:58
msgid "Friendica Notification"
msgstr ""
-#: include/enotify.php:60
+#: include/enotify.php:61
msgid "Thank You,"
msgstr ""
-#: include/enotify.php:63
+#: include/enotify.php:64
#, php-format
msgid "%1$s, %2$s Administrator"
msgstr ""
-#: include/enotify.php:65
+#: include/enotify.php:66
#, php-format
msgid "%s Administrator"
msgstr ""
-#: include/enotify.php:134
+#: include/enotify.php:135
#, php-format
msgid "[Friendica:Notify] New mail received at %s"
msgstr ""
-#: include/enotify.php:136
+#: include/enotify.php:137
#, php-format
msgid "%1$s sent you a new private message at %2$s."
msgstr ""
-#: include/enotify.php:137
+#: include/enotify.php:138
msgid "a private message"
msgstr ""
-#: include/enotify.php:137
+#: include/enotify.php:138
#, php-format
msgid "%1$s sent you %2$s."
msgstr ""
-#: include/enotify.php:139
+#: include/enotify.php:140
#, php-format
msgid "Please visit %s to view and/or reply to your private messages."
msgstr ""
-#: include/enotify.php:172
+#: include/enotify.php:173
#, php-format
msgid "%1$s tagged you on [url=%2$s]a %3$s[/url]"
msgstr ""
-#: include/enotify.php:178
+#: include/enotify.php:179
#, php-format
msgid "%1$s commented on [url=%2$s]a %3$s[/url]"
msgstr ""
-#: include/enotify.php:188
+#: include/enotify.php:189
#, php-format
msgid "%1$s tagged you on [url=%2$s]%3$s's %4$s[/url]"
msgstr ""
-#: include/enotify.php:195
+#: include/enotify.php:196
#, php-format
msgid "%1$s commented on [url=%2$s]%3$s's %4$s[/url]"
msgstr ""
-#: include/enotify.php:207
+#: include/enotify.php:208
#, php-format
msgid "%1$s tagged you on [url=%2$s]your %3$s[/url]"
msgstr ""
-#: include/enotify.php:213
+#: include/enotify.php:214
#, php-format
msgid "%1$s commented on [url=%2$s]your %3$s[/url]"
msgstr ""
-#: include/enotify.php:224
+#: include/enotify.php:225
#, php-format
msgid "%1$s tagged you on [url=%2$s]their %3$s[/url]"
msgstr ""
-#: include/enotify.php:230
+#: include/enotify.php:231
#, php-format
msgid "%1$s commented on [url=%2$s]their %3$s[/url]"
msgstr ""
-#: include/enotify.php:243
+#: include/enotify.php:244
#, php-format
msgid "[Friendica:Notify] %s tagged you"
msgstr ""
-#: include/enotify.php:245
+#: include/enotify.php:246
#, php-format
msgid "%1$s tagged you at %2$s"
msgstr ""
-#: include/enotify.php:247
+#: include/enotify.php:248
#, php-format
msgid "[Friendica:Notify] Comment to conversation #%1$d by %2$s"
msgstr ""
-#: include/enotify.php:249
+#: include/enotify.php:250
#, php-format
msgid "%s commented on an item/conversation you have been following."
msgstr ""
-#: include/enotify.php:254 include/enotify.php:269 include/enotify.php:284
-#: include/enotify.php:303 include/enotify.php:319
+#: include/enotify.php:255 include/enotify.php:270 include/enotify.php:285
+#: include/enotify.php:304 include/enotify.php:320
#, php-format
msgid "Please visit %s to view and/or reply to the conversation."
msgstr ""
-#: include/enotify.php:261
+#: include/enotify.php:262
#, php-format
msgid "[Friendica:Notify] %s posted to your profile wall"
msgstr ""
-#: include/enotify.php:263
+#: include/enotify.php:264
#, php-format
msgid "%1$s posted to your profile wall at %2$s"
msgstr ""
-#: include/enotify.php:264
+#: include/enotify.php:265
#, php-format
msgid "%1$s posted to [url=%2$s]your wall[/url]"
msgstr ""
-#: include/enotify.php:276
+#: include/enotify.php:277
#, php-format
msgid "[Friendica:Notify] %s shared a new post"
msgstr ""
-#: include/enotify.php:278
+#: include/enotify.php:279
#, php-format
msgid "%1$s shared a new post at %2$s"
msgstr ""
-#: include/enotify.php:279
+#: include/enotify.php:280
#, php-format
msgid "%1$s [url=%2$s]shared a post[/url]."
msgstr ""
-#: include/enotify.php:291
+#: include/enotify.php:292
#, php-format
msgid "[Friendica:Notify] %1$s poked you"
msgstr ""
-#: include/enotify.php:293
+#: include/enotify.php:294
#, php-format
msgid "%1$s poked you at %2$s"
msgstr ""
-#: include/enotify.php:294
+#: include/enotify.php:295
#, php-format
msgid "%1$s [url=%2$s]poked you[/url]."
msgstr ""
-#: include/enotify.php:311
+#: include/enotify.php:312
#, php-format
msgid "[Friendica:Notify] %s tagged your post"
msgstr ""
-#: include/enotify.php:313
+#: include/enotify.php:314
#, php-format
msgid "%1$s tagged your post at %2$s"
msgstr ""
-#: include/enotify.php:314
+#: include/enotify.php:315
#, php-format
msgid "%1$s tagged [url=%2$s]your post[/url]"
msgstr ""
-#: include/enotify.php:326
+#: include/enotify.php:327
msgid "[Friendica:Notify] Introduction received"
msgstr ""
-#: include/enotify.php:328
+#: include/enotify.php:329
#, php-format
msgid "You've received an introduction from '%1$s' at %2$s"
msgstr ""
-#: include/enotify.php:329
+#: include/enotify.php:330
#, php-format
msgid "You've received [url=%1$s]an introduction[/url] from %2$s."
msgstr ""
-#: include/enotify.php:334 include/enotify.php:380
+#: include/enotify.php:335 include/enotify.php:381
#, php-format
msgid "You may visit their profile at %s"
msgstr ""
-#: include/enotify.php:336
+#: include/enotify.php:337
#, php-format
msgid "Please visit %s to approve or reject the introduction."
msgstr ""
-#: include/enotify.php:343
+#: include/enotify.php:344
msgid "[Friendica:Notify] A new person is sharing with you"
msgstr ""
-#: include/enotify.php:345 include/enotify.php:346
+#: include/enotify.php:346 include/enotify.php:347
#, php-format
msgid "%1$s is sharing with you at %2$s"
msgstr ""
-#: include/enotify.php:353
+#: include/enotify.php:354
msgid "[Friendica:Notify] You have a new follower"
msgstr ""
-#: include/enotify.php:355 include/enotify.php:356
+#: include/enotify.php:356 include/enotify.php:357
#, php-format
msgid "You have a new follower at %2$s : %1$s"
msgstr ""
-#: include/enotify.php:369
+#: include/enotify.php:370
msgid "[Friendica:Notify] Friend suggestion received"
msgstr ""
-#: include/enotify.php:371
+#: include/enotify.php:372
#, php-format
msgid "You've received a friend suggestion from '%1$s' at %2$s"
msgstr ""
-#: include/enotify.php:372
+#: include/enotify.php:373
#, php-format
msgid "You've received [url=%1$s]a friend suggestion[/url] for %2$s from %3$s."
msgstr ""
-#: include/enotify.php:378
+#: include/enotify.php:379
msgid "Name:"
msgstr ""
-#: include/enotify.php:379
+#: include/enotify.php:380
msgid "Photo:"
msgstr ""
-#: include/enotify.php:382
+#: include/enotify.php:383
#, php-format
msgid "Please visit %s to approve or reject the suggestion."
msgstr ""
-#: include/enotify.php:390 include/enotify.php:405
+#: include/enotify.php:391 include/enotify.php:406
msgid "[Friendica:Notify] Connection accepted"
msgstr ""
-#: include/enotify.php:392 include/enotify.php:407
+#: include/enotify.php:393 include/enotify.php:408
#, php-format
msgid "'%1$s' has accepted your connection request at %2$s"
msgstr ""
-#: include/enotify.php:393 include/enotify.php:408
+#: include/enotify.php:394 include/enotify.php:409
#, php-format
msgid "%2$s has accepted your [url=%1$s]connection request[/url]."
msgstr ""
-#: include/enotify.php:398
+#: include/enotify.php:399
msgid ""
"You are now mutual friends and may exchange status updates, photos, and "
"email without restriction."
msgstr ""
-#: include/enotify.php:400
+#: include/enotify.php:401
#, php-format
msgid "Please visit %s if you wish to make any changes to this relationship."
msgstr ""
-#: include/enotify.php:413
+#: include/enotify.php:414
#, php-format
msgid ""
"'%1$s' has chosen to accept you a fan, which restricts some forms of "
"automatically."
msgstr ""
-#: include/enotify.php:415
+#: include/enotify.php:416
#, php-format
msgid ""
"'%1$s' may choose to extend this into a two-way or more permissive "
"relationship in the future."
msgstr ""
-#: include/enotify.php:417
+#: include/enotify.php:418
#, php-format
msgid "Please visit %s if you wish to make any changes to this relationship."
msgstr ""
-#: include/enotify.php:427 mod/removeme.php:46
+#: include/enotify.php:428 mod/removeme.php:46
msgid "[Friendica System Notify]"
msgstr ""
-#: include/enotify.php:427
+#: include/enotify.php:428
msgid "registration request"
msgstr ""
-#: include/enotify.php:429
+#: include/enotify.php:430
#, php-format
msgid "You've received a registration request from '%1$s' at %2$s"
msgstr ""
-#: include/enotify.php:430
+#: include/enotify.php:431
#, php-format
msgid "You've received a [url=%1$s]registration request[/url] from %2$s."
msgstr ""
-#: include/enotify.php:435
+#: include/enotify.php:436
#, php-format
msgid ""
"Full Name:\t%s\n"
"Login Name:\t%s (%s)"
msgstr ""
-#: include/enotify.php:441
+#: include/enotify.php:442
#, php-format
msgid "Please visit %s to approve or reject the request."
msgstr ""
-#: mod/api.php:84 mod/api.php:106
-msgid "Authorize application connection"
-msgstr ""
-
-#: mod/api.php:85
-msgid "Return to your app and insert this Securty Code:"
-msgstr ""
-
-#: mod/api.php:94 src/Module/BaseAdminModule.php:56
-msgid "Please login to continue."
-msgstr ""
-
-#: mod/api.php:108
-msgid ""
-"Do you want to authorize this application to access your posts and contacts, "
-"and/or create new posts for you?"
-msgstr ""
-
-#: mod/api.php:110 mod/profiles.php:526 mod/profiles.php:530
-#: mod/profiles.php:551 mod/dfrn_request.php:640 mod/follow.php:163
-#: mod/settings.php:1089 mod/settings.php:1095 mod/settings.php:1102
-#: mod/settings.php:1106 mod/settings.php:1110 mod/settings.php:1114
-#: mod/settings.php:1118 mod/settings.php:1122 mod/settings.php:1142
-#: mod/settings.php:1143 mod/settings.php:1144 mod/settings.php:1145
-#: mod/settings.php:1146 src/Module/Register.php:98
-msgid "No"
-msgstr ""
-
-#: mod/delegate.php:42
-msgid "Parent user not found."
-msgstr ""
-
-#: mod/delegate.php:149
-msgid "No parent user"
-msgstr ""
-
-#: mod/delegate.php:164
-msgid "Parent Password:"
-msgstr ""
-
-#: mod/delegate.php:164
-msgid ""
-"Please enter the password of the parent account to legitimize your request."
-msgstr ""
-
-#: mod/delegate.php:171
-msgid "Parent User"
-msgstr ""
-
-#: mod/delegate.php:174
-msgid ""
-"Parent users have total control about this account, including the account "
-"settings. Please double check whom you give this access."
-msgstr ""
-
-#: mod/delegate.php:175 mod/settings.php:677 mod/settings.php:784
-#: mod/settings.php:874 mod/settings.php:953 mod/settings.php:1178
-#: src/Module/Admin/Addons/Index.php:52 src/Module/Admin/Features.php:69
-#: src/Module/Admin/Logs/Settings.php:65 src/Module/Admin/Themes/Index.php:97
-#: src/Module/Admin/Tos.php:50 src/Module/Admin/Site.php:568
-msgid "Save Settings"
-msgstr ""
-
-#: mod/delegate.php:176 src/Content/Nav.php:263
-msgid "Delegate Page Management"
-msgstr ""
-
-#: mod/delegate.php:177
-msgid "Delegates"
-msgstr ""
-
-#: mod/delegate.php:179
-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 ""
-
-#: mod/delegate.php:180
-msgid "Existing Page Delegates"
-msgstr ""
-
-#: mod/delegate.php:182
-msgid "Potential Delegates"
+#: include/items.php:355 src/Module/Admin/Themes/Details.php:53
+#: src/Module/Admin/Themes/Index.php:43 src/Module/Debug/ItemBody.php:27
+#: src/Module/Debug/ItemBody.php:40
+msgid "Item not found."
msgstr ""
-#: mod/delegate.php:184 mod/tagrm.php:114
-msgid "Remove"
+#: include/items.php:387
+msgid "Do you really want to delete this item?"
msgstr ""
-#: mod/delegate.php:185
-msgid "Add"
+#: include/items.php:389 mod/suggest.php:73 mod/api.php:110
+#: mod/dfrn_request.php:642 mod/follow.php:163 mod/message.php:150
+#: mod/profiles.php:526 mod/profiles.php:529 mod/profiles.php:551
+#: mod/settings.php:1081 mod/settings.php:1087 mod/settings.php:1094
+#: mod/settings.php:1098 mod/settings.php:1102 mod/settings.php:1106
+#: mod/settings.php:1110 mod/settings.php:1114 mod/settings.php:1134
+#: mod/settings.php:1135 mod/settings.php:1136 mod/settings.php:1137
+#: mod/settings.php:1138 src/Module/Contact.php:444 src/Module/Register.php:91
+msgid "Yes"
msgstr ""
-#: mod/delegate.php:186
-msgid "No entries."
+#: include/items.php:439 mod/ostatus_subscribe.php:18 mod/repair_ostatus.php:16
+#: mod/notes.php:27 mod/profile_photo.php:32 mod/profile_photo.php:177
+#: mod/profile_photo.php:197 mod/suggest.php:39 mod/api.php:35 mod/api.php:40
+#: mod/cal.php:291 mod/common.php:27 mod/crepair.php:90 mod/dfrn_confirm.php:65
+#: mod/editpost.php:22 mod/events.php:214 mod/follow.php:57 mod/follow.php:134
+#: mod/fsuggest.php:63 mod/item.php:174 mod/message.php:56 mod/message.php:101
+#: mod/network.php:38 mod/notifications.php:76 mod/photos.php:163
+#: mod/photos.php:927 mod/poke.php:142 mod/profiles.php:182
+#: mod/profiles.php:499 mod/regmod.php:89 mod/settings.php:54
+#: mod/settings.php:167 mod/settings.php:659 mod/uimport.php:17
+#: mod/unfollow.php:22 mod/unfollow.php:77 mod/unfollow.php:109
+#: mod/wall_attach.php:63 mod/wall_attach.php:66 mod/wall_upload.php:95
+#: mod/wall_upload.php:98 mod/wallmessage.php:19 mod/wallmessage.php:43
+#: mod/wallmessage.php:82 mod/wallmessage.php:106 src/Module/Attach.php:42
+#: src/Module/Group.php:31 src/Module/Group.php:77 src/Module/Invite.php:22
+#: src/Module/Invite.php:110 src/Module/Notifications/Notify.php:20
+#: src/Module/Profile/Contacts.php:50 src/Module/Search/Directory.php:19
+#: src/Module/Settings/Delegation.php:26 src/Module/Settings/Delegation.php:54
+#: src/Module/Contact.php:361 src/Module/Delegation.php:98
+#: src/Module/FollowConfirm.php:27 src/Module/Register.php:186
+msgid "Permission denied."
msgstr ""
#: mod/oexchange.php:32
msgid "failed"
msgstr ""
-#: mod/ostatus_subscribe.php:89 src/Object/Post.php:285
+#: mod/ostatus_subscribe.php:89 src/Object/Post.php:282
msgid "ignored"
msgstr ""
msgstr ""
#: mod/profperm.php:117 view/theme/frio/theme.php:268 src/Content/Nav.php:161
-#: src/Model/Profile.php:889 src/Model/Profile.php:925
-#: src/Module/Welcome.php:38 src/Module/Contact.php:618
-#: src/Module/Contact.php:847
+#: src/Model/Profile.php:885 src/Model/Profile.php:921
+#: src/Module/Welcome.php:38 src/Module/Contact.php:639
+#: src/Module/Contact.php:868
msgid "Profile"
msgstr ""
msgid "All Contacts (with secure profile access)"
msgstr ""
-#: mod/regmod.php:53
-msgid "Account approved."
-msgstr ""
-
-#: mod/regmod.php:77
-#, php-format
-msgid "Registration revoked for %s"
-msgstr ""
-
-#: mod/regmod.php:84
-msgid "Please login."
-msgstr ""
-
#: mod/removeme.php:46
msgid "User deleted their account"
msgstr ""
msgstr[0] ""
msgstr[1] ""
-#: mod/tagrm.php:31
-msgid "Tag(s) removed"
-msgstr ""
-
-#: mod/tagrm.php:101
-msgid "Remove Item Tag"
+#: mod/update_community.php:23 mod/update_contact.php:23
+#: mod/update_display.php:24 mod/update_network.php:33 mod/update_notes.php:36
+#: mod/update_profile.php:34
+msgid "[Embedded content - reload page to view]"
msgstr ""
-#: mod/tagrm.php:103
-msgid "Select a tag to remove: "
+#: mod/notes.php:34 src/Model/Profile.php:971
+msgid "Personal Notes"
msgstr ""
-#: mod/uimport.php:30
-msgid "User imports on closed servers can only be done by an administrator."
+#: mod/notes.php:46 mod/editpost.php:72 src/Content/Text/HTML.php:905
+#: src/Module/Filer/SaveTag.php:49
+msgid "Save"
msgstr ""
-#: mod/uimport.php:39 src/Module/Register.php:59
-msgid ""
-"This site has exceeded the number of allowed daily account registrations. "
-"Please try again tomorrow."
+#: mod/ping.php:272
+msgid "{0} wants to be your friend"
msgstr ""
-#: mod/uimport.php:54 src/Module/Register.php:141
-msgid "Import"
+#: mod/ping.php:288
+msgid "{0} requested registration"
msgstr ""
-#: mod/uimport.php:56
-msgid "Move account"
+#: mod/profile_photo.php:58
+msgid "Image uploaded but image cropping failed."
msgstr ""
-#: mod/uimport.php:57
-msgid "You can import an account from another Friendica server."
+#: mod/profile_photo.php:88 mod/profile_photo.php:97 mod/profile_photo.php:106
+#: mod/profile_photo.php:311
+#, php-format
+msgid "Image size reduction [%s] failed."
msgstr ""
-#: mod/uimport.php:58
+#: mod/profile_photo.php:125
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."
+"Shift-reload the page or clear browser cache if the new photo does not "
+"display immediately."
msgstr ""
-#: mod/uimport.php:59
-msgid ""
-"This feature is experimental. We can't import contacts from the OStatus "
-"network (GNU Social/Statusnet) or from Diaspora"
+#: mod/profile_photo.php:133
+msgid "Unable to process image"
msgstr ""
-#: mod/uimport.php:60
-msgid "Account file"
+#: mod/profile_photo.php:152 mod/photos.php:674 mod/photos.php:677
+#: mod/photos.php:706 mod/wall_upload.php:186
+#, php-format
+msgid "Image exceeds size limit of %s"
msgstr ""
-#: mod/uimport.php:60
-msgid ""
-"To export your account, go to \"Settings->Export your personal data\" and "
-"select \"Export account\""
+#: mod/profile_photo.php:161 mod/photos.php:729 mod/wall_upload.php:200
+msgid "Unable to process image."
msgstr ""
-#: mod/unfollow.php:36 mod/unfollow.php:92
-msgid "You aren't following this contact."
+#: mod/profile_photo.php:244
+msgid "Upload File:"
msgstr ""
-#: mod/unfollow.php:46 mod/unfollow.php:98
-msgid "Unfollowing is currently not supported by your network."
+#: mod/profile_photo.php:245
+msgid "Select a profile:"
msgstr ""
-#: mod/unfollow.php:67
-msgid "Contact unfollowed"
+#: mod/profile_photo.php:246 mod/profiles.php:583 src/Module/Welcome.php:39
+msgid "Upload Profile Photo"
msgstr ""
-#: mod/unfollow.php:118
-msgid "Disconnect/Unfollow"
+#: mod/profile_photo.php:247 mod/fbrowser.php:112 mod/fbrowser.php:141
+msgid "Upload"
msgstr ""
-#: mod/unfollow.php:128 mod/dfrn_request.php:647 mod/follow.php:170
-msgid "Your Identity Address:"
+#: mod/profile_photo.php:250
+msgid "or"
msgstr ""
-#: mod/unfollow.php:131 mod/dfrn_request.php:649 mod/follow.php:76
-msgid "Submit Request"
+#: mod/profile_photo.php:251
+msgid "skip this step"
msgstr ""
-#: mod/unfollow.php:137 mod/follow.php:179 mod/notifications.php:190
-#: mod/notifications.php:282 src/Module/Admin/Blocklist/Contact.php:83
-#: src/Module/Contact.php:603
-msgid "Profile URL"
+#: mod/profile_photo.php:251
+msgid "select a photo from your photo albums"
msgstr ""
-#: mod/unfollow.php:147 mod/follow.php:195 src/Model/Profile.php:920
-#: src/Module/Contact.php:842
-msgid "Status Messages and Posts"
+#: mod/profile_photo.php:264
+msgid "Crop Image"
msgstr ""
-#: mod/update_community.php:23 mod/update_contact.php:23
-#: mod/update_display.php:24 mod/update_network.php:33 mod/update_notes.php:36
-#: mod/update_profile.php:34
-msgid "[Embedded content - reload page to view]"
+#: mod/profile_photo.php:265
+msgid "Please adjust the image cropping for optimum viewing."
msgstr ""
-#: mod/wall_attach.php:26 mod/wall_attach.php:33 mod/wall_attach.php:85
-#: mod/wall_upload.php:42 mod/wall_upload.php:58 mod/wall_upload.php:116
-#: mod/wall_upload.php:167 mod/wall_upload.php:170
-msgid "Invalid request."
+#: mod/profile_photo.php:267
+msgid "Done Editing"
msgstr ""
-#: mod/wall_attach.php:103
-msgid "Sorry, maybe your upload is bigger than the PHP configuration allows"
+#: mod/profile_photo.php:301
+msgid "Image uploaded successfully."
msgstr ""
-#: mod/wall_attach.php:103
-msgid "Or - did you try to upload an empty file?"
+#: mod/profile_photo.php:303 mod/photos.php:758 mod/wall_upload.php:239
+msgid "Image upload failed."
msgstr ""
-#: mod/wall_attach.php:114
-#, php-format
-msgid "File exceeds size limit of %s"
+#: mod/suggest.php:28
+msgid "Contact suggestion successfully ignored."
msgstr ""
-#: mod/wall_attach.php:129
-msgid "File upload failed."
+#: mod/suggest.php:52
+msgid ""
+"No suggestions available. If this is a new site, please try again in 24 "
+"hours."
msgstr ""
-#: mod/wall_upload.php:198 mod/photos.php:683 mod/photos.php:686
-#: mod/photos.php:715 mod/profile_photo.php:152
-#, php-format
-msgid "Image exceeds size limit of %s"
+#: mod/suggest.php:71
+msgid "Do you really want to delete this suggestion?"
msgstr ""
-#: mod/wall_upload.php:212 mod/photos.php:738 mod/profile_photo.php:161
-msgid "Unable to process image."
+#: mod/suggest.php:89 mod/suggest.php:109
+msgid "Ignore/Hide"
msgstr ""
-#: mod/wall_upload.php:243
-msgid "Wall Photos"
+#: mod/suggest.php:106 mod/match.php:102 src/Content/Widget.php:43
+#: src/Module/AllFriends.php:91 src/Module/BaseSearchModule.php:135
+msgid "Connect"
msgstr ""
-#: mod/wall_upload.php:251 mod/photos.php:767 mod/profile_photo.php:303
-msgid "Image upload failed."
+#: mod/suggest.php:119 view/theme/vier/theme.php:181 src/Content/Widget.php:70
+msgid "Friend Suggestions"
msgstr ""
-#: mod/wallmessage.php:52 mod/wallmessage.php:115
-#, php-format
-msgid "Number of daily wall messages for %s exceeded. Message failed."
+#: mod/api.php:85 mod/api.php:107
+msgid "Authorize application connection"
msgstr ""
-#: mod/wallmessage.php:60 mod/message.php:70
-msgid "No recipient selected."
+#: mod/api.php:86
+msgid "Return to your app and insert this Securty Code:"
msgstr ""
-#: mod/wallmessage.php:63
-msgid "Unable to check your home location."
+#: mod/api.php:95 src/Module/BaseAdminModule.php:56
+msgid "Please login to continue."
msgstr ""
-#: mod/wallmessage.php:66 mod/message.php:77
-msgid "Message could not be sent."
+#: mod/api.php:109
+msgid ""
+"Do you want to authorize this application to access your posts and contacts, "
+"and/or create new posts for you?"
msgstr ""
-#: mod/wallmessage.php:69 mod/message.php:80
-msgid "Message collection failure."
+#: mod/api.php:111 mod/dfrn_request.php:642 mod/follow.php:163
+#: mod/profiles.php:526 mod/profiles.php:530 mod/profiles.php:551
+#: mod/settings.php:1081 mod/settings.php:1087 mod/settings.php:1094
+#: mod/settings.php:1098 mod/settings.php:1102 mod/settings.php:1106
+#: mod/settings.php:1110 mod/settings.php:1114 mod/settings.php:1134
+#: mod/settings.php:1135 mod/settings.php:1136 mod/settings.php:1137
+#: mod/settings.php:1138 src/Module/Register.php:92
+msgid "No"
msgstr ""
-#: mod/wallmessage.php:72 mod/message.php:83
-msgid "Message sent."
+#: mod/cal.php:31 mod/cal.php:35 mod/community.php:32 mod/follow.php:20
+#: src/Module/Debug/ItemBody.php:18 src/Module/Diaspora/Receive.php:39
+#: src/Module/Item/Ignore.php:25
+msgid "Access denied."
msgstr ""
-#: mod/wallmessage.php:89 mod/wallmessage.php:98
-msgid "No recipient."
+#: mod/cal.php:130 mod/display.php:296 src/Module/Profile.php:175
+msgid "Access to this profile has been restricted."
msgstr ""
-#: mod/wallmessage.php:123 mod/message.php:204 mod/message.php:360
-msgid "Please enter a link URL:"
+#: mod/cal.php:261 mod/events.php:389 view/theme/frio/theme.php:271
+#: view/theme/frio/theme.php:275 src/Content/Nav.php:164
+#: src/Content/Nav.php:228 src/Model/Profile.php:949 src/Model/Profile.php:960
+msgid "Events"
msgstr ""
-#: mod/wallmessage.php:128 mod/message.php:246
-msgid "Send Private Message"
+#: mod/cal.php:262 mod/events.php:390
+msgid "View"
msgstr ""
-#: mod/wallmessage.php:129
-#, php-format
-msgid ""
-"If you wish for %s to respond, please check that the privacy settings on "
-"your site allow private mail from unknown senders."
+#: mod/cal.php:263 mod/events.php:392
+msgid "Previous"
msgstr ""
-#: mod/wallmessage.php:130 mod/message.php:247 mod/message.php:430
-msgid "To:"
+#: mod/cal.php:264 mod/events.php:393 src/Module/Install.php:174
+msgid "Next"
msgstr ""
-#: mod/wallmessage.php:131 mod/message.php:251 mod/message.php:432
-msgid "Subject:"
+#: mod/cal.php:267 mod/events.php:398 src/Model/Event.php:429
+msgid "today"
msgstr ""
-#: mod/wallmessage.php:137 mod/message.php:255 mod/message.php:435
-#: src/Module/Invite.php:150
-msgid "Your message:"
+#: mod/cal.php:268 mod/events.php:399 src/Util/Temporal.php:313
+#: src/Model/Event.php:430
+msgid "month"
msgstr ""
-#: mod/wallmessage.php:140 mod/editpost.php:76 mod/message.php:259
-#: mod/message.php:440
-msgid "Insert web link"
+#: mod/cal.php:269 mod/events.php:400 src/Util/Temporal.php:314
+#: src/Model/Event.php:431
+msgid "week"
msgstr ""
-#: mod/match.php:49
-msgid "No keywords to match. Please add keywords to your default profile."
+#: mod/cal.php:270 mod/events.php:401 src/Util/Temporal.php:315
+#: src/Model/Event.php:432
+msgid "day"
msgstr ""
-#: mod/match.php:102 mod/suggest.php:106 src/Content/Widget.php:42
-#: src/Module/AllFriends.php:91 src/Module/BaseSearchModule.php:131
-msgid "Connect"
+#: mod/cal.php:271 mod/events.php:402
+msgid "list"
msgstr ""
-#: mod/match.php:115 src/Content/Pager.php:198
-msgid "first"
+#: mod/cal.php:284 src/Model/User.php:415 src/Console/NewPassword.php:88
+msgid "User not found"
msgstr ""
-#: mod/match.php:120 src/Content/Pager.php:258
-msgid "next"
+#: mod/cal.php:300
+msgid "This calendar format is not supported"
msgstr ""
-#: mod/match.php:130 src/Module/BaseSearchModule.php:92
-msgid "No matches"
+#: mod/cal.php:302
+msgid "No exportable data found"
msgstr ""
-#: mod/match.php:135
-msgid "Profile Match"
+#: mod/cal.php:319
+msgid "calendar"
msgstr ""
-#: mod/profiles.php:43 mod/profiles.php:152 mod/profiles.php:196
-#: mod/profiles.php:511 mod/dfrn_confirm.php:70
-msgid "Profile not found."
+#: mod/common.php:90
+msgid "No contacts in common."
msgstr ""
-#: mod/profiles.php:62
-msgid "Profile deleted."
+#: mod/common.php:141 src/Module/Contact.php:891
+msgid "Common Friends"
msgstr ""
-#: mod/profiles.php:78 mod/profiles.php:114
-msgid "Profile-"
+#: mod/community.php:25 mod/dfrn_request.php:599 mod/display.php:200
+#: mod/photos.php:841 mod/videos.php:115 src/Module/Debug/Probe.php:20
+#: src/Module/Debug/WebFinger.php:19 src/Module/Search/Index.php:31
+#: src/Module/Search/Index.php:36 src/Module/Directory.php:31
+msgid "Public access denied."
msgstr ""
-#: mod/profiles.php:97 mod/profiles.php:135
-msgid "New profile created."
+#: mod/community.php:68
+msgid "Community option not available."
msgstr ""
-#: mod/profiles.php:120
-msgid "Profile unavailable to clone."
+#: mod/community.php:85
+msgid "Not available."
msgstr ""
-#: mod/profiles.php:206
-msgid "Profile Name is required."
+#: mod/community.php:95
+msgid "Local Community"
msgstr ""
-#: mod/profiles.php:346
-msgid "Marital Status"
+#: mod/community.php:98
+msgid "Posts from local users on this server"
msgstr ""
-#: mod/profiles.php:349
-msgid "Romantic Partner"
+#: mod/community.php:106
+msgid "Global Community"
msgstr ""
-#: mod/profiles.php:358
-msgid "Work/Employment"
+#: mod/community.php:109
+msgid "Posts from users of the whole federated network"
msgstr ""
-#: mod/profiles.php:361
-msgid "Religion"
+#: mod/community.php:155 src/Module/Search/Index.php:178
+msgid "No results."
msgstr ""
-#: mod/profiles.php:364
-msgid "Political Views"
+#: mod/community.php:207
+msgid ""
+"This community stream shows all public posts received by this node. They may "
+"not reflect the opinions of this node’s users."
msgstr ""
-#: mod/profiles.php:367
-msgid "Gender"
+#: mod/crepair.php:79
+msgid "Contact settings applied."
msgstr ""
-#: mod/profiles.php:370
-msgid "Sexual Preference"
+#: mod/crepair.php:81
+msgid "Contact update failed."
msgstr ""
-#: mod/profiles.php:373
-msgid "XMPP"
+#: mod/crepair.php:102 mod/dfrn_confirm.php:126 mod/fsuggest.php:32
+#: mod/fsuggest.php:75 mod/redir.php:32 mod/redir.php:122 mod/redir.php:137
+#: src/Module/Group.php:92 src/Module/FollowConfirm.php:46
+msgid "Contact not found."
msgstr ""
-#: mod/profiles.php:376
-msgid "Homepage"
+#: mod/crepair.php:115
+msgid ""
+"<strong>WARNING: This is highly advanced</strong> and if you enter incorrect "
+"information your communications with this contact may stop working."
msgstr ""
-#: mod/profiles.php:379 mod/profiles.php:578
-msgid "Interests"
+#: mod/crepair.php:116
+msgid ""
+"Please use your browser 'Back' button <strong>now</strong> if you are "
+"uncertain what to do on this page."
msgstr ""
-#: mod/profiles.php:382
-msgid "Address"
+#: mod/crepair.php:130 mod/crepair.php:132
+msgid "No mirroring"
msgstr ""
-#: mod/profiles.php:389 mod/profiles.php:574
-msgid "Location"
+#: mod/crepair.php:130
+msgid "Mirror as forwarded posting"
msgstr ""
-#: mod/profiles.php:469
-msgid "Profile updated."
+#: mod/crepair.php:130 mod/crepair.php:132
+msgid "Mirror as my own posting"
msgstr ""
-#: mod/profiles.php:523
-msgid "Hide contacts and friends:"
+#: mod/crepair.php:145
+msgid "Return to contact editor"
msgstr ""
-#: mod/profiles.php:528
-msgid "Hide your contact/friend list from viewers of this profile?"
+#: mod/crepair.php:147
+msgid "Refetch contact data"
msgstr ""
-#: mod/profiles.php:548
-msgid "Show more profile fields:"
+#: mod/crepair.php:149 mod/events.php:558 mod/fsuggest.php:92
+#: mod/message.php:261 mod/message.php:441 mod/photos.php:956
+#: mod/photos.php:1066 mod/photos.php:1352 mod/photos.php:1397
+#: mod/photos.php:1436 mod/photos.php:1501 mod/poke.php:185
+#: mod/profiles.php:562 view/theme/duepuntozero/config.php:72
+#: view/theme/frio/config.php:127 view/theme/quattro/config.php:74
+#: view/theme/vier/config.php:122 src/Module/Debug/Localtime.php:45
+#: src/Module/Invite.php:157 src/Module/Item/Compose.php:182
+#: src/Module/Contact.php:581 src/Module/Delegation.php:131
+#: src/Module/Install.php:212 src/Module/Install.php:252
+#: src/Module/Install.php:288 src/Object/Post.php:884
+msgid "Submit"
msgstr ""
-#: mod/profiles.php:560
-msgid "Profile Actions"
+#: mod/crepair.php:150
+msgid "Remote Self"
msgstr ""
-#: mod/profiles.php:561
-msgid "Edit Profile Details"
+#: mod/crepair.php:153
+msgid "Mirror postings from this contact"
msgstr ""
-#: mod/profiles.php:562 mod/crepair.php:149 mod/fsuggest.php:92
-#: mod/manage.php:183 mod/message.php:261 mod/message.php:441
-#: mod/photos.php:991 mod/photos.php:1101 mod/photos.php:1387
-#: mod/photos.php:1432 mod/photos.php:1471 mod/photos.php:1531 mod/poke.php:184
-#: mod/events.php:552 view/theme/duepuntozero/config.php:72
-#: view/theme/frio/config.php:127 view/theme/quattro/config.php:74
-#: view/theme/vier/config.php:120 src/Module/Debug/Localtime.php:45
-#: src/Module/Invite.php:157 src/Module/Item/Compose.php:178
-#: src/Module/Contact.php:560 src/Module/Install.php:212
-#: src/Module/Install.php:252 src/Module/Install.php:288
-#: src/Object/Post.php:879
-msgid "Submit"
+#: mod/crepair.php:155
+msgid ""
+"Mark this contact as remote_self, this will cause friendica to repost new "
+"entries from this contact."
msgstr ""
-#: mod/profiles.php:563
-msgid "Change Profile Photo"
+#: mod/crepair.php:159 mod/settings.php:671 mod/settings.php:697
+#: src/Module/Admin/Blocklist/Contact.php:73 src/Module/Admin/Users.php:272
+#: src/Module/Admin/Users.php:283 src/Module/Admin/Users.php:297
+#: src/Module/Admin/Users.php:313
+msgid "Name"
msgstr ""
-#: mod/profiles.php:565
-msgid "View this profile"
+#: mod/crepair.php:160
+msgid "Account Nickname"
msgstr ""
-#: mod/profiles.php:566
-msgid "View all profiles"
+#: mod/crepair.php:161
+msgid "@Tagname - overrides Name/Nickname"
msgstr ""
-#: mod/profiles.php:567 mod/profiles.php:662 src/Model/Profile.php:423
-msgid "Edit visibility"
+#: mod/crepair.php:162
+msgid "Account URL"
msgstr ""
-#: mod/profiles.php:568
-msgid "Create a new profile using these settings"
+#: mod/crepair.php:163
+msgid "Account URL Alias"
msgstr ""
-#: mod/profiles.php:569
-msgid "Clone this profile"
+#: mod/crepair.php:164
+msgid "Friend Request URL"
msgstr ""
-#: mod/profiles.php:570
-msgid "Delete this profile"
+#: mod/crepair.php:165
+msgid "Friend Confirm URL"
msgstr ""
-#: mod/profiles.php:572
-msgid "Basic information"
+#: mod/crepair.php:166
+msgid "Notification Endpoint URL"
msgstr ""
-#: mod/profiles.php:573
-msgid "Profile picture"
+#: mod/crepair.php:167
+msgid "Poll/Feed URL"
msgstr ""
-#: mod/profiles.php:575
-msgid "Preferences"
+#: mod/crepair.php:168
+msgid "New photo from this URL"
msgstr ""
-#: mod/profiles.php:576
-msgid "Status information"
+#: mod/dfrn_confirm.php:71 mod/profiles.php:43 mod/profiles.php:152
+#: mod/profiles.php:196 mod/profiles.php:511
+msgid "Profile not found."
msgstr ""
-#: mod/profiles.php:577
-msgid "Additional information"
+#: mod/dfrn_confirm.php:127
+msgid ""
+"This may occasionally happen if contact was requested by both persons and it "
+"has already been approved."
msgstr ""
-#: mod/profiles.php:579 mod/network.php:992
-#: src/Core/NotificationsManager.php:158
-msgid "Personal"
+#: mod/dfrn_confirm.php:228
+msgid "Response from remote site was not understood."
msgstr ""
-#: mod/profiles.php:580
-msgid "Relation"
+#: mod/dfrn_confirm.php:235 mod/dfrn_confirm.php:241
+msgid "Unexpected response from remote site: "
msgstr ""
-#: mod/profiles.php:581 src/Util/Temporal.php:79 src/Util/Temporal.php:81
-msgid "Miscellaneous"
+#: mod/dfrn_confirm.php:250
+msgid "Confirmation completed successfully."
msgstr ""
-#: mod/profiles.php:583 mod/profile_photo.php:246 src/Module/Welcome.php:39
-msgid "Upload Profile Photo"
+#: mod/dfrn_confirm.php:262
+msgid "Temporary failure. Please wait and try again."
msgstr ""
-#: mod/profiles.php:584
-msgid "Your Gender:"
+#: mod/dfrn_confirm.php:265
+msgid "Introduction failed or was revoked."
msgstr ""
-#: mod/profiles.php:585
-msgid "<span class=\"heart\">♥</span> Marital Status:"
+#: mod/dfrn_confirm.php:270
+msgid "Remote site reported: "
msgstr ""
-#: mod/profiles.php:586 src/Model/Profile.php:808
-msgid "Sexual Preference:"
+#: mod/dfrn_confirm.php:375
+#, php-format
+msgid "No user record found for '%s' "
msgstr ""
-#: mod/profiles.php:587
-msgid "Example: fishing photography software"
+#: mod/dfrn_confirm.php:385
+msgid "Our site encryption key is apparently messed up."
msgstr ""
-#: mod/profiles.php:592
-msgid "Profile Name:"
+#: mod/dfrn_confirm.php:396
+msgid "Empty site URL was provided or URL could not be decrypted by us."
msgstr ""
-#: mod/profiles.php:592 mod/events.php:510 mod/events.php:542
-msgid "Required"
+#: mod/dfrn_confirm.php:412
+msgid "Contact record was not found for you on our site."
msgstr ""
-#: mod/profiles.php:594
+#: mod/dfrn_confirm.php:426
+#, php-format
+msgid "Site public key not available in contact record for URL %s."
+msgstr ""
+
+#: mod/dfrn_confirm.php:442
msgid ""
-"This is your <strong>public</strong> profile.<br />It <strong>may</strong> "
-"be visible to anybody using the internet."
+"The ID provided by your system is a duplicate on our system. It should work "
+"if you try again."
msgstr ""
-#: mod/profiles.php:595
-msgid "Your Full Name:"
+#: mod/dfrn_confirm.php:453
+msgid "Unable to set your contact credentials on our system."
msgstr ""
-#: mod/profiles.php:596
-msgid "Title/Description:"
+#: mod/dfrn_confirm.php:509
+msgid "Unable to update your contact profile details on our system"
msgstr ""
-#: mod/profiles.php:599
-msgid "Street Address:"
+#: mod/dfrn_confirm.php:539 mod/dfrn_request.php:562 src/Model/Contact.php:2589
+msgid "[Name Withheld]"
msgstr ""
-#: mod/profiles.php:600
-msgid "Locality/City:"
+#: mod/dfrn_poll.php:123 mod/dfrn_poll.php:526
+#, php-format
+msgid "%1$s welcomes %2$s"
msgstr ""
-#: mod/profiles.php:601
-msgid "Region/State:"
+#: mod/dfrn_request.php:100
+msgid "This introduction has already been accepted."
msgstr ""
-#: mod/profiles.php:602
-msgid "Postal/Zip Code:"
+#: mod/dfrn_request.php:118 mod/dfrn_request.php:356
+msgid "Profile location is not valid or does not contain profile information."
msgstr ""
-#: mod/profiles.php:603
-msgid "Country:"
+#: mod/dfrn_request.php:122 mod/dfrn_request.php:360
+msgid "Warning: profile location has no identifiable owner name."
msgstr ""
-#: mod/profiles.php:604 src/Util/Temporal.php:149
-msgid "Age: "
+#: mod/dfrn_request.php:125 mod/dfrn_request.php:363
+msgid "Warning: profile location has no profile photo."
msgstr ""
-#: mod/profiles.php:607
-msgid "Who: (if applicable)"
-msgstr ""
+#: mod/dfrn_request.php:129 mod/dfrn_request.php:367
+#, 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] ""
+msgstr[1] ""
-#: mod/profiles.php:607
-msgid "Examples: cathy123, Cathy Williams, cathy@example.com"
+#: mod/dfrn_request.php:167
+msgid "Introduction complete."
msgstr ""
-#: mod/profiles.php:608
-msgid "Since [date]:"
+#: mod/dfrn_request.php:203
+msgid "Unrecoverable protocol error."
msgstr ""
-#: mod/profiles.php:610
-msgid "Tell us about yourself..."
+#: mod/dfrn_request.php:230
+msgid "Profile unavailable."
msgstr ""
-#: mod/profiles.php:611
-msgid "XMPP (Jabber) address:"
+#: mod/dfrn_request.php:251
+#, php-format
+msgid "%s has received too many connection requests today."
msgstr ""
-#: mod/profiles.php:611
-msgid ""
-"The XMPP address will be propagated to your contacts so that they can follow "
-"you."
+#: mod/dfrn_request.php:252
+msgid "Spam protection measures have been invoked."
msgstr ""
-#: mod/profiles.php:612
-msgid "Homepage URL:"
+#: mod/dfrn_request.php:253
+msgid "Friends are advised to please try again in 24 hours."
msgstr ""
-#: mod/profiles.php:613 src/Model/Profile.php:816
-msgid "Hometown:"
+#: mod/dfrn_request.php:277
+msgid "Invalid locator"
msgstr ""
-#: mod/profiles.php:614 src/Model/Profile.php:824
-msgid "Political Views:"
+#: mod/dfrn_request.php:313
+msgid "You have already introduced yourself here."
msgstr ""
-#: mod/profiles.php:615
-msgid "Religious Views:"
+#: mod/dfrn_request.php:316
+#, php-format
+msgid "Apparently you are already friends with %s."
msgstr ""
-#: mod/profiles.php:616
-msgid "Public Keywords:"
+#: mod/dfrn_request.php:336
+msgid "Invalid profile URL."
msgstr ""
-#: mod/profiles.php:616
-msgid "(Used for suggesting potential friends, can be seen by others)"
+#: mod/dfrn_request.php:342 src/Model/Contact.php:2212
+msgid "Disallowed profile URL."
msgstr ""
-#: mod/profiles.php:617
-msgid "Private Keywords:"
+#: mod/dfrn_request.php:348 src/Model/Contact.php:2217
+#: src/Module/Friendica.php:59
+msgid "Blocked domain"
msgstr ""
-#: mod/profiles.php:617
-msgid "(Used for searching profiles, never shown to others)"
+#: mod/dfrn_request.php:415 src/Module/Contact.php:143
+msgid "Failed to update contact record."
msgstr ""
-#: mod/profiles.php:618 src/Model/Profile.php:840
-msgid "Likes:"
+#: mod/dfrn_request.php:435
+msgid "Your introduction has been sent."
msgstr ""
-#: mod/profiles.php:619 src/Model/Profile.php:844
-msgid "Dislikes:"
+#: mod/dfrn_request.php:473
+msgid ""
+"Remote subscription can't be done for your network. Please subscribe "
+"directly on your system."
msgstr ""
-#: mod/profiles.php:620
-msgid "Musical interests"
+#: mod/dfrn_request.php:489
+msgid "Please login to confirm introduction."
msgstr ""
-#: mod/profiles.php:621
-msgid "Books, literature"
+#: mod/dfrn_request.php:497
+msgid ""
+"Incorrect identity currently logged in. Please login to <strong>this</"
+"strong> profile."
msgstr ""
-#: mod/profiles.php:622
-msgid "Television"
+#: mod/dfrn_request.php:511 mod/dfrn_request.php:526
+msgid "Confirm"
msgstr ""
-#: mod/profiles.php:623
-msgid "Film/dance/culture/entertainment"
+#: mod/dfrn_request.php:522
+msgid "Hide this contact"
msgstr ""
-#: mod/profiles.php:624
-msgid "Hobbies/Interests"
+#: mod/dfrn_request.php:524
+#, php-format
+msgid "Welcome home %s."
msgstr ""
-#: mod/profiles.php:625
-msgid "Love/romance"
+#: mod/dfrn_request.php:525
+#, php-format
+msgid "Please confirm your introduction/connection request to %s."
msgstr ""
-#: mod/profiles.php:626
-msgid "Work/employment"
+#: mod/dfrn_request.php:634
+msgid ""
+"Please enter your 'Identity Address' from one of the following supported "
+"communications networks:"
msgstr ""
-#: mod/profiles.php:627
-msgid "School/education"
+#: mod/dfrn_request.php:636
+#, php-format
+msgid ""
+"If you are not yet a member of the free social web, <a href=\"%s\">follow "
+"this link to find a public Friendica site and join us today</a>."
msgstr ""
-#: mod/profiles.php:628
-msgid "Contact information and Social Networks"
+#: mod/dfrn_request.php:639
+msgid "Friend/Connection Request"
msgstr ""
-#: mod/profiles.php:659 src/Model/Profile.php:419
-msgid "Profile Image"
+#: mod/dfrn_request.php:640
+msgid ""
+"Examples: jojo@demo.friendica.com, http://demo.friendica.com/profile/jojo, "
+"testuser@gnusocial.de"
msgstr ""
-#: mod/profiles.php:661 src/Model/Profile.php:422
-msgid "visible to everybody"
+#: mod/dfrn_request.php:641 mod/follow.php:162
+msgid "Please answer the following:"
msgstr ""
-#: mod/profiles.php:668
-msgid "Edit/Manage Profiles"
+#: mod/dfrn_request.php:642 mod/follow.php:163
+#, php-format
+msgid "Does %s know you?"
msgstr ""
-#: mod/profiles.php:669 src/Model/Profile.php:409 src/Model/Profile.php:430
-msgid "Change profile photo"
+#: mod/dfrn_request.php:643 mod/follow.php:164
+msgid "Add a personal note:"
msgstr ""
-#: mod/profiles.php:670 src/Model/Profile.php:410
-msgid "Create New Profile"
+#: mod/dfrn_request.php:645
+msgid "Friendica"
msgstr ""
-#: mod/cal.php:34 mod/cal.php:38 mod/community.php:40 mod/follow.php:20
-#: src/Module/Debug/ItemBody.php:18
-msgid "Access denied."
+#: mod/dfrn_request.php:646
+msgid "GNU Social (Pleroma, Mastodon)"
msgstr ""
-#: mod/cal.php:140 mod/display.php:303 src/Module/Profile.php:185
-msgid "Access to this profile has been restricted."
+#: mod/dfrn_request.php:647
+msgid "Diaspora (Socialhome, Hubzilla)"
msgstr ""
-#: mod/cal.php:271 mod/events.php:383 view/theme/frio/theme.php:271
-#: view/theme/frio/theme.php:275 src/Content/Nav.php:164
-#: src/Content/Nav.php:228 src/Model/Profile.php:953 src/Model/Profile.php:964
-msgid "Events"
+#: mod/dfrn_request.php:648
+#, php-format
+msgid ""
+" - please do not use this form. Instead, enter %s into your Diaspora search "
+"bar."
msgstr ""
-#: mod/cal.php:272 mod/events.php:384
-msgid "View"
+#: mod/dfrn_request.php:649 mod/follow.php:170 mod/unfollow.php:128
+msgid "Your Identity Address:"
msgstr ""
-#: mod/cal.php:273 mod/events.php:386
-msgid "Previous"
+#: mod/dfrn_request.php:651 mod/follow.php:76 mod/unfollow.php:131
+msgid "Submit Request"
msgstr ""
-#: mod/cal.php:274 mod/events.php:387 src/Module/Install.php:174
-msgid "Next"
+#: mod/display.php:255 mod/display.php:332
+msgid "The requested item doesn't exist or has been deleted."
msgstr ""
-#: mod/cal.php:277 mod/events.php:392 src/Model/Event.php:428
-msgid "today"
+#: mod/display.php:410
+msgid "The feed for this item is unavailable."
msgstr ""
-#: mod/cal.php:278 mod/events.php:393 src/Util/Temporal.php:314
-#: src/Model/Event.php:429
-msgid "month"
+#: mod/editpost.php:29 mod/editpost.php:39
+msgid "Item not found"
msgstr ""
-#: mod/cal.php:279 mod/events.php:394 src/Util/Temporal.php:315
-#: src/Model/Event.php:430
-msgid "week"
+#: mod/editpost.php:46
+msgid "Edit post"
msgstr ""
-#: mod/cal.php:280 mod/events.php:395 src/Util/Temporal.php:316
-#: src/Model/Event.php:431
-msgid "day"
+#: mod/editpost.php:77 mod/message.php:259 mod/message.php:440
+#: mod/wallmessage.php:140
+msgid "Insert web link"
msgstr ""
-#: mod/cal.php:281 mod/events.php:396
-msgid "list"
+#: mod/editpost.php:78
+msgid "web link"
msgstr ""
-#: mod/cal.php:294 src/Model/User.php:384 src/Console/NewPassword.php:88
-msgid "User not found"
+#: mod/editpost.php:79
+msgid "Insert video link"
msgstr ""
-#: mod/cal.php:310
-msgid "This calendar format is not supported"
+#: mod/editpost.php:80
+msgid "video link"
msgstr ""
-#: mod/cal.php:312
-msgid "No exportable data found"
+#: mod/editpost.php:81
+msgid "Insert audio link"
msgstr ""
-#: mod/cal.php:329
-msgid "calendar"
+#: mod/editpost.php:82
+msgid "audio link"
msgstr ""
-#: mod/common.php:90
-msgid "No contacts in common."
+#: mod/editpost.php:96 src/Core/ACL.php:309 src/Module/Item/Compose.php:204
+msgid "CC: email addresses"
msgstr ""
-#: mod/common.php:141 src/Module/Contact.php:870
-msgid "Common Friends"
+#: mod/editpost.php:103 src/Core/ACL.php:310
+msgid "Example: bob@example.com, mary@example.com"
msgstr ""
-#: mod/community.php:33 mod/dfrn_request.php:597 mod/photos.php:850
-#: mod/search.php:87 mod/search.php:93 mod/videos.php:118 mod/display.php:201
-#: src/Module/Debug/Probe.php:20 src/Module/Debug/WebFinger.php:19
-#: src/Module/Directory.php:30
-msgid "Public access denied."
+#: mod/events.php:120 mod/events.php:122
+msgid "Event can not end before it has started."
msgstr ""
-#: mod/community.php:76
-msgid "Community option not available."
+#: mod/events.php:129 mod/events.php:131
+msgid "Event title and start time are required."
msgstr ""
-#: mod/community.php:93
-msgid "Not available."
+#: mod/events.php:391
+msgid "Create New Event"
msgstr ""
-#: mod/community.php:103
-msgid "Local Community"
+#: mod/events.php:514
+msgid "Event details"
msgstr ""
-#: mod/community.php:106
-msgid "Posts from local users on this server"
+#: mod/events.php:515
+msgid "Starting date and Title are required."
msgstr ""
-#: mod/community.php:114
-msgid "Global Community"
+#: mod/events.php:516 mod/events.php:521
+msgid "Event Starts:"
msgstr ""
-#: mod/community.php:117
-msgid "Posts from users of the whole federated network"
+#: mod/events.php:516 mod/events.php:548 mod/profiles.php:592
+msgid "Required"
msgstr ""
-#: mod/community.php:163 mod/search.php:222
-msgid "No results."
+#: mod/events.php:529 mod/events.php:554
+msgid "Finish date/time is not known or not relevant"
msgstr ""
-#: mod/community.php:215
-msgid ""
-"This community stream shows all public posts received by this node. They may "
-"not reflect the opinions of this node’s users."
+#: mod/events.php:531 mod/events.php:536
+msgid "Event Finishes:"
msgstr ""
-#: mod/crepair.php:79
-msgid "Contact settings applied."
+#: mod/events.php:542 mod/events.php:555
+msgid "Adjust for viewer timezone"
msgstr ""
-#: mod/crepair.php:81
-msgid "Contact update failed."
+#: mod/events.php:544
+msgid "Description:"
msgstr ""
-#: mod/crepair.php:102 mod/dfrn_confirm.php:125 mod/fsuggest.php:32
-#: mod/fsuggest.php:75 mod/redir.php:32 mod/redir.php:140
-#: src/Module/FollowConfirm.php:46 src/Module/Group.php:92
-msgid "Contact not found."
+#: mod/events.php:546 mod/notifications.php:276 src/Model/Event.php:69
+#: src/Model/Event.php:96 src/Model/Event.php:438 src/Model/Event.php:934
+#: src/Model/Profile.php:443 src/Module/Contact.php:628
+#: src/Module/Directory.php:135
+msgid "Location:"
msgstr ""
-#: mod/crepair.php:115
-msgid ""
-"<strong>WARNING: This is highly advanced</strong> and if you enter incorrect "
-"information your communications with this contact may stop working."
+#: mod/events.php:548 mod/events.php:550
+msgid "Title:"
msgstr ""
-#: mod/crepair.php:116
-msgid ""
-"Please use your browser 'Back' button <strong>now</strong> if you are "
-"uncertain what to do on this page."
+#: mod/events.php:551 mod/events.php:552
+msgid "Share this event"
msgstr ""
-#: mod/crepair.php:130 mod/crepair.php:132
-msgid "No mirroring"
+#: mod/events.php:559 src/Model/Profile.php:886
+msgid "Basic"
msgstr ""
-#: mod/crepair.php:130
-msgid "Mirror as forwarded posting"
+#: mod/events.php:560 src/Model/Profile.php:887 src/Module/Admin/Site.php:573
+#: src/Module/Contact.php:901
+msgid "Advanced"
msgstr ""
-#: mod/crepair.php:130 mod/crepair.php:132
-msgid "Mirror as my own posting"
+#: mod/events.php:561 mod/photos.php:974 mod/photos.php:1348
+#: src/Core/ACL.php:315
+msgid "Permissions"
msgstr ""
-#: mod/crepair.php:145
-msgid "Return to contact editor"
+#: mod/events.php:577
+msgid "Failed to remove event"
msgstr ""
-#: mod/crepair.php:147
-msgid "Refetch contact data"
+#: mod/events.php:579
+msgid "Event removed"
msgstr ""
-#: mod/crepair.php:150
-msgid "Remote Self"
+#: mod/fbrowser.php:43 view/theme/frio/theme.php:269 src/Content/Nav.php:162
+#: src/Model/Profile.php:929
+msgid "Photos"
msgstr ""
-#: mod/crepair.php:153
-msgid "Mirror postings from this contact"
+#: mod/fbrowser.php:52 mod/fbrowser.php:76 mod/photos.php:181
+#: mod/photos.php:938 mod/photos.php:1055 mod/photos.php:1072
+#: mod/photos.php:1554 mod/photos.php:1569 src/Model/Photo.php:560
+#: src/Model/Photo.php:569
+msgid "Contact Photos"
msgstr ""
-#: mod/crepair.php:155
-msgid ""
-"Mark this contact as remote_self, this will cause friendica to repost new "
-"entries from this contact."
+#: mod/fbrowser.php:136
+msgid "Files"
msgstr ""
-#: mod/crepair.php:159 mod/settings.php:679 mod/settings.php:705
-#: src/Module/Admin/Blocklist/Contact.php:73 src/Module/Admin/Users.php:272
-#: src/Module/Admin/Users.php:283 src/Module/Admin/Users.php:297
-#: src/Module/Admin/Users.php:313
-msgid "Name"
+#: mod/follow.php:46
+msgid "The contact could not be added."
msgstr ""
-#: mod/crepair.php:160
-msgid "Account Nickname"
+#: mod/follow.php:87
+msgid "You already added this contact."
msgstr ""
-#: mod/crepair.php:161
-msgid "@Tagname - overrides Name/Nickname"
+#: mod/follow.php:99
+msgid "Diaspora support isn't enabled. Contact can't be added."
msgstr ""
-#: mod/crepair.php:162
-msgid "Account URL"
+#: mod/follow.php:106
+msgid "OStatus support is disabled. Contact can't be added."
msgstr ""
-#: mod/crepair.php:163
-msgid "Account URL Alias"
-msgstr ""
-
-#: mod/crepair.php:164
-msgid "Friend Request URL"
-msgstr ""
-
-#: mod/crepair.php:165
-msgid "Friend Confirm URL"
-msgstr ""
-
-#: mod/crepair.php:166
-msgid "Notification Endpoint URL"
-msgstr ""
-
-#: mod/crepair.php:167
-msgid "Poll/Feed URL"
-msgstr ""
-
-#: mod/crepair.php:168
-msgid "New photo from this URL"
-msgstr ""
-
-#: mod/dfrn_confirm.php:126
-msgid ""
-"This may occasionally happen if contact was requested by both persons and it "
-"has already been approved."
-msgstr ""
-
-#: mod/dfrn_confirm.php:227
-msgid "Response from remote site was not understood."
-msgstr ""
-
-#: mod/dfrn_confirm.php:234 mod/dfrn_confirm.php:240
-msgid "Unexpected response from remote site: "
-msgstr ""
-
-#: mod/dfrn_confirm.php:249
-msgid "Confirmation completed successfully."
-msgstr ""
-
-#: mod/dfrn_confirm.php:261
-msgid "Temporary failure. Please wait and try again."
-msgstr ""
-
-#: mod/dfrn_confirm.php:264
-msgid "Introduction failed or was revoked."
-msgstr ""
-
-#: mod/dfrn_confirm.php:269
-msgid "Remote site reported: "
-msgstr ""
-
-#: mod/dfrn_confirm.php:374
-#, php-format
-msgid "No user record found for '%s' "
-msgstr ""
-
-#: mod/dfrn_confirm.php:384
-msgid "Our site encryption key is apparently messed up."
-msgstr ""
-
-#: mod/dfrn_confirm.php:395
-msgid "Empty site URL was provided or URL could not be decrypted by us."
-msgstr ""
-
-#: mod/dfrn_confirm.php:411
-msgid "Contact record was not found for you on our site."
-msgstr ""
-
-#: mod/dfrn_confirm.php:425
-#, php-format
-msgid "Site public key not available in contact record for URL %s."
-msgstr ""
-
-#: mod/dfrn_confirm.php:441
-msgid ""
-"The ID provided by your system is a duplicate on our system. It should work "
-"if you try again."
-msgstr ""
-
-#: mod/dfrn_confirm.php:452
-msgid "Unable to set your contact credentials on our system."
-msgstr ""
-
-#: mod/dfrn_confirm.php:508
-msgid "Unable to update your contact profile details on our system"
-msgstr ""
-
-#: mod/dfrn_confirm.php:538 mod/dfrn_request.php:560 src/Model/Contact.php:2551
-msgid "[Name Withheld]"
-msgstr ""
-
-#: mod/dfrn_poll.php:125 mod/dfrn_poll.php:530
-#, php-format
-msgid "%1$s welcomes %2$s"
-msgstr ""
-
-#: mod/dfrn_request.php:98
-msgid "This introduction has already been accepted."
-msgstr ""
-
-#: mod/dfrn_request.php:116 mod/dfrn_request.php:354
-msgid "Profile location is not valid or does not contain profile information."
-msgstr ""
-
-#: mod/dfrn_request.php:120 mod/dfrn_request.php:358
-msgid "Warning: profile location has no identifiable owner name."
-msgstr ""
-
-#: mod/dfrn_request.php:123 mod/dfrn_request.php:361
-msgid "Warning: profile location has no profile photo."
-msgstr ""
-
-#: mod/dfrn_request.php:127 mod/dfrn_request.php:365
-#, 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] ""
-msgstr[1] ""
-
-#: mod/dfrn_request.php:165
-msgid "Introduction complete."
-msgstr ""
-
-#: mod/dfrn_request.php:201
-msgid "Unrecoverable protocol error."
+#: mod/follow.php:113
+msgid "The network type couldn't be detected. Contact can't be added."
msgstr ""
-#: mod/dfrn_request.php:228
-msgid "Profile unavailable."
+#: mod/follow.php:179 mod/notifications.php:194 mod/notifications.php:286
+#: mod/unfollow.php:137 src/Module/Admin/Blocklist/Contact.php:83
+#: src/Module/Contact.php:624
+msgid "Profile URL"
msgstr ""
-#: mod/dfrn_request.php:249
-#, php-format
-msgid "%s has received too many connection requests today."
+#: mod/follow.php:183 mod/notifications.php:280 src/Model/Profile.php:816
+#: src/Module/Contact.php:634
+msgid "Tags:"
msgstr ""
-#: mod/dfrn_request.php:250
-msgid "Spam protection measures have been invoked."
+#: mod/follow.php:195 mod/unfollow.php:147 src/Model/Profile.php:916
+#: src/Module/Contact.php:863
+msgid "Status Messages and Posts"
msgstr ""
-#: mod/dfrn_request.php:251
-msgid "Friends are advised to please try again in 24 hours."
+#: mod/fsuggest.php:44
+msgid "Suggested contact not found."
msgstr ""
-#: mod/dfrn_request.php:275
-msgid "Invalid locator"
+#: mod/fsuggest.php:57
+msgid "Friend suggestion sent."
msgstr ""
-#: mod/dfrn_request.php:311
-msgid "You have already introduced yourself here."
+#: mod/fsuggest.php:79
+msgid "Suggest Friends"
msgstr ""
-#: mod/dfrn_request.php:314
+#: mod/fsuggest.php:81
#, php-format
-msgid "Apparently you are already friends with %s."
-msgstr ""
-
-#: mod/dfrn_request.php:334
-msgid "Invalid profile URL."
-msgstr ""
-
-#: mod/dfrn_request.php:340 src/Model/Contact.php:2182
-msgid "Disallowed profile URL."
-msgstr ""
-
-#: mod/dfrn_request.php:346 src/Model/Contact.php:2187
-#: src/Module/Friendica.php:59
-msgid "Blocked domain"
-msgstr ""
-
-#: mod/dfrn_request.php:413 src/Module/Contact.php:143
-msgid "Failed to update contact record."
-msgstr ""
-
-#: mod/dfrn_request.php:433
-msgid "Your introduction has been sent."
-msgstr ""
-
-#: mod/dfrn_request.php:471
-msgid ""
-"Remote subscription can't be done for your network. Please subscribe "
-"directly on your system."
-msgstr ""
-
-#: mod/dfrn_request.php:487
-msgid "Please login to confirm introduction."
-msgstr ""
-
-#: mod/dfrn_request.php:495
-msgid ""
-"Incorrect identity currently logged in. Please login to <strong>this</"
-"strong> profile."
-msgstr ""
-
-#: mod/dfrn_request.php:509 mod/dfrn_request.php:524
-msgid "Confirm"
-msgstr ""
-
-#: mod/dfrn_request.php:520
-msgid "Hide this contact"
+msgid "Suggest a friend for %s"
msgstr ""
-#: mod/dfrn_request.php:522
-#, php-format
-msgid "Welcome home %s."
+#: mod/hcard.php:21
+msgid "No profile"
msgstr ""
-#: mod/dfrn_request.php:523
-#, php-format
-msgid "Please confirm your introduction/connection request to %s."
+#: mod/item.php:127
+msgid "Unable to locate original post."
msgstr ""
-#: mod/dfrn_request.php:632
-msgid ""
-"Please enter your 'Identity Address' from one of the following supported "
-"communications networks:"
+#: mod/item.php:330
+msgid "Empty post discarded."
msgstr ""
-#: mod/dfrn_request.php:634
+#: mod/item.php:801
#, php-format
msgid ""
-"If you are not yet a member of the free social web, <a href=\"%s\">follow "
-"this link to find a public Friendica site and join us today</a>."
-msgstr ""
-
-#: mod/dfrn_request.php:637
-msgid "Friend/Connection Request"
-msgstr ""
-
-#: mod/dfrn_request.php:638
-msgid ""
-"Examples: jojo@demo.friendica.com, http://demo.friendica.com/profile/jojo, "
-"testuser@gnusocial.de"
-msgstr ""
-
-#: mod/dfrn_request.php:639 mod/follow.php:162
-msgid "Please answer the following:"
+"This message was sent to you by %s, a member of the Friendica social network."
msgstr ""
-#: mod/dfrn_request.php:640 mod/follow.php:163
+#: mod/item.php:803
#, php-format
-msgid "Does %s know you?"
-msgstr ""
-
-#: mod/dfrn_request.php:641 mod/follow.php:164
-msgid "Add a personal note:"
-msgstr ""
-
-#: mod/dfrn_request.php:643
-msgid "Friendica"
-msgstr ""
-
-#: mod/dfrn_request.php:644
-msgid "GNU Social (Pleroma, Mastodon)"
-msgstr ""
-
-#: mod/dfrn_request.php:645
-msgid "Diaspora (Socialhome, Hubzilla)"
+msgid "You may visit them online at %s"
msgstr ""
-#: mod/dfrn_request.php:646
-#, php-format
+#: mod/item.php:804
msgid ""
-" - please do not use this form. Instead, enter %s into your Diaspora search "
-"bar."
-msgstr ""
-
-#: mod/editpost.php:28 mod/editpost.php:38
-msgid "Item not found"
-msgstr ""
-
-#: mod/editpost.php:45
-msgid "Edit post"
-msgstr ""
-
-#: mod/editpost.php:71 mod/notes.php:46 src/Content/Text/HTML.php:887
-#: src/Module/Filer/SaveTag.php:49
-msgid "Save"
-msgstr ""
-
-#: mod/editpost.php:77
-msgid "web link"
-msgstr ""
-
-#: mod/editpost.php:78
-msgid "Insert video link"
-msgstr ""
-
-#: mod/editpost.php:79
-msgid "video link"
-msgstr ""
-
-#: mod/editpost.php:80
-msgid "Insert audio link"
-msgstr ""
-
-#: mod/editpost.php:81
-msgid "audio link"
-msgstr ""
-
-#: mod/editpost.php:95 src/Core/ACL.php:308 src/Module/Item/Compose.php:200
-msgid "CC: email addresses"
-msgstr ""
-
-#: mod/editpost.php:102 src/Core/ACL.php:309
-msgid "Example: bob@example.com, mary@example.com"
-msgstr ""
-
-#: mod/fbrowser.php:43 view/theme/frio/theme.php:269 src/Content/Nav.php:162
-#: src/Model/Profile.php:933
-msgid "Photos"
-msgstr ""
-
-#: mod/fbrowser.php:52 mod/fbrowser.php:76 mod/photos.php:196
-#: mod/photos.php:973 mod/photos.php:1090 mod/photos.php:1107
-#: mod/photos.php:1584 mod/photos.php:1599 src/Model/Photo.php:574
-#: src/Model/Photo.php:583
-msgid "Contact Photos"
-msgstr ""
-
-#: mod/fbrowser.php:112 mod/fbrowser.php:141 mod/profile_photo.php:247
-msgid "Upload"
-msgstr ""
-
-#: mod/fbrowser.php:136
-msgid "Files"
-msgstr ""
-
-#: mod/follow.php:46
-msgid "The contact could not be added."
-msgstr ""
-
-#: mod/follow.php:87
-msgid "You already added this contact."
-msgstr ""
-
-#: mod/follow.php:99
-msgid "Diaspora support isn't enabled. Contact can't be added."
-msgstr ""
-
-#: mod/follow.php:106
-msgid "OStatus support is disabled. Contact can't be added."
-msgstr ""
-
-#: mod/follow.php:113
-msgid "The network type couldn't be detected. Contact can't be added."
-msgstr ""
-
-#: mod/follow.php:183 mod/notifications.php:276 src/Model/Profile.php:820
-#: src/Module/Contact.php:613
-msgid "Tags:"
-msgstr ""
-
-#: mod/fsuggest.php:44
-msgid "Suggested contact not found."
-msgstr ""
-
-#: mod/fsuggest.php:57
-msgid "Friend suggestion sent."
-msgstr ""
-
-#: mod/fsuggest.php:79
-msgid "Suggest Friends"
+"Please contact the sender by replying to this post if you do not wish to "
+"receive these messages."
msgstr ""
-#: mod/fsuggest.php:81
+#: mod/item.php:808
#, php-format
-msgid "Suggest a friend for %s"
-msgstr ""
-
-#: mod/hcard.php:20
-msgid "No profile"
+msgid "%s posted an update."
msgstr ""
-#: mod/lockview.php:47 mod/lockview.php:58
+#: mod/lockview.php:49 mod/lockview.php:60
msgid "Remote privacy information not available."
msgstr ""
-#: mod/lockview.php:67
+#: mod/lockview.php:72
msgid "Visible to:"
msgstr ""
-#: mod/lockview.php:73 mod/lockview.php:108 src/Content/Widget.php:192
-#: src/Module/Item/Compose.php:97 src/Module/Profile/Contacts.php:126
-#: src/Module/Contact.php:771
+#: mod/lockview.php:78 mod/lockview.php:113 src/Content/Widget.php:193
+#: src/Module/Item/Compose.php:101 src/Module/Profile/Contacts.php:126
+#: src/Module/Contact.php:792
msgid "Followers"
msgstr ""
-#: mod/lockview.php:79 mod/lockview.php:114 src/Module/Item/Compose.php:104
+#: mod/lockview.php:84 mod/lockview.php:119 src/Module/Item/Compose.php:108
msgid "Mutuals"
msgstr ""
-#: mod/lostpass.php:26
+#: mod/lostpass.php:27
msgid "No valid account found."
msgstr ""
-#: mod/lostpass.php:38
+#: mod/lostpass.php:39
msgid "Password reset request issued. Check your email."
msgstr ""
-#: mod/lostpass.php:44
+#: mod/lostpass.php:45
#, php-format
msgid ""
"\n"
"\t\tissued this request."
msgstr ""
-#: mod/lostpass.php:55
+#: mod/lostpass.php:56
#, php-format
msgid ""
"\n"
"\t\tLogin Name:\t%3$s"
msgstr ""
-#: mod/lostpass.php:74
+#: mod/lostpass.php:75
#, php-format
msgid "Password reset requested at %s"
msgstr ""
-#: mod/lostpass.php:89
+#: mod/lostpass.php:90
msgid ""
"Request could not be verified. (You may have previously submitted it.) "
"Password reset failed."
msgstr ""
-#: mod/lostpass.php:102
+#: mod/lostpass.php:103
msgid "Request has expired, please make a new one."
msgstr ""
-#: mod/lostpass.php:117
+#: mod/lostpass.php:118
msgid "Forgot your Password?"
msgstr ""
-#: mod/lostpass.php:118
+#: mod/lostpass.php:119
msgid ""
"Enter your email address and submit to have your password reset. Then check "
"your email for further instructions."
msgstr ""
-#: mod/lostpass.php:119 src/Module/Login.php:318
+#: mod/lostpass.php:120 src/Module/Login.php:355
msgid "Nickname or Email: "
msgstr ""
-#: mod/lostpass.php:120
+#: mod/lostpass.php:121
msgid "Reset"
msgstr ""
-#: mod/lostpass.php:135 src/Module/Login.php:330
+#: mod/lostpass.php:136 src/Module/Login.php:367
msgid "Password Reset"
msgstr ""
-#: mod/lostpass.php:136
+#: mod/lostpass.php:137
msgid "Your password has been reset as requested."
msgstr ""
-#: mod/lostpass.php:137
+#: mod/lostpass.php:138
msgid "Your new password is"
msgstr ""
-#: mod/lostpass.php:138
+#: mod/lostpass.php:139
msgid "Save or copy your new password - and then"
msgstr ""
-#: mod/lostpass.php:139
+#: mod/lostpass.php:140
msgid "click here to login"
msgstr ""
-#: mod/lostpass.php:140
+#: mod/lostpass.php:141
msgid ""
"Your password may be changed from the <em>Settings</em> page after "
"successful login."
msgstr ""
-#: mod/lostpass.php:147
+#: mod/lostpass.php:148
#, php-format
msgid ""
"\n"
"\t\t"
msgstr ""
-#: mod/lostpass.php:153
+#: mod/lostpass.php:154
#, php-format
msgid ""
"\n"
"\t\t"
msgstr ""
-#: mod/lostpass.php:169
+#: mod/lostpass.php:170
#, php-format
msgid "Your password has been changed at %s"
msgstr ""
-#: mod/manage.php:179
-msgid "Manage Identities and/or Pages"
+#: mod/match.php:49
+msgid "No keywords to match. Please add keywords to your default profile."
msgstr ""
-#: mod/manage.php:180
-msgid ""
-"Toggle between different identities or community/group pages which share "
-"your account details or which you have been granted \"manage\" permissions"
+#: mod/match.php:115 src/Content/Pager.php:198
+msgid "first"
msgstr ""
-#: mod/manage.php:181
-msgid "Select an identity to manage: "
+#: mod/match.php:120 src/Content/Pager.php:258
+msgid "next"
+msgstr ""
+
+#: mod/match.php:130 src/Module/BaseSearchModule.php:96
+msgid "No matches"
+msgstr ""
+
+#: mod/match.php:135
+msgid "Profile Match"
msgstr ""
#: mod/message.php:33 mod/message.php:116 src/Content/Nav.php:257
msgid "New Message"
msgstr ""
+#: mod/message.php:70 mod/wallmessage.php:60
+msgid "No recipient selected."
+msgstr ""
+
#: mod/message.php:74
msgid "Unable to locate contact information."
msgstr ""
-#: mod/message.php:110 mod/notifications.php:49 mod/notifications.php:198
-#: mod/notifications.php:254
+#: mod/message.php:77 mod/wallmessage.php:66
+msgid "Message could not be sent."
+msgstr ""
+
+#: mod/message.php:80 mod/wallmessage.php:69
+msgid "Message collection failure."
+msgstr ""
+
+#: mod/message.php:83 mod/wallmessage.php:72
+msgid "Message sent."
+msgstr ""
+
+#: mod/message.php:110 mod/notifications.php:48 mod/notifications.php:202
+#: mod/notifications.php:258
msgid "Discard"
msgstr ""
msgid "Conversation removed."
msgstr ""
+#: mod/message.php:204 mod/message.php:360 mod/wallmessage.php:123
+msgid "Please enter a link URL:"
+msgstr ""
+
+#: mod/message.php:246 mod/wallmessage.php:128
+msgid "Send Private Message"
+msgstr ""
+
+#: mod/message.php:247 mod/message.php:430 mod/wallmessage.php:130
+msgid "To:"
+msgstr ""
+
+#: mod/message.php:251 mod/message.php:432 mod/wallmessage.php:131
+msgid "Subject:"
+msgstr ""
+
+#: mod/message.php:255 mod/message.php:435 mod/wallmessage.php:137
+#: src/Module/Invite.php:150
+msgid "Your message:"
+msgstr ""
+
#: mod/message.php:289
msgid "No messages."
msgstr ""
msgid "D, d M Y - g:i A"
msgstr ""
-#: mod/message.php:423 mod/message.php:537
-msgid "Delete conversation"
+#: mod/message.php:423 mod/message.php:537
+msgid "Delete conversation"
+msgstr ""
+
+#: mod/message.php:425
+msgid ""
+"No secure communications available. You <strong>may</strong> be able to "
+"respond from the sender's profile page."
+msgstr ""
+
+#: mod/message.php:429
+msgid "Send Reply"
+msgstr ""
+
+#: mod/message.php:512
+#, php-format
+msgid "Unknown sender - %s"
+msgstr ""
+
+#: mod/message.php:514
+#, php-format
+msgid "You and %s"
+msgstr ""
+
+#: mod/message.php:516
+#, php-format
+msgid "%s and You"
+msgstr ""
+
+#: mod/message.php:543
+#, php-format
+msgid "%d message"
+msgid_plural "%d messages"
+msgstr[0] ""
+msgstr[1] ""
+
+#: mod/network.php:525
+#, 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] ""
+msgstr[1] ""
+
+#: mod/network.php:528
+msgid "Messages in this group won't be send to these receivers."
+msgstr ""
+
+#: mod/network.php:595
+msgid "No such group"
+msgstr ""
+
+#: mod/network.php:616 src/Module/Group.php:288
+msgid "Group is empty"
+msgstr ""
+
+#: mod/network.php:620
+#, php-format
+msgid "Group: %s"
+msgstr ""
+
+#: mod/network.php:646
+msgid "Private messages to this person are at risk of public disclosure."
+msgstr ""
+
+#: mod/network.php:649 src/Module/AllFriends.php:35
+#: src/Module/AllFriends.php:43
+msgid "Invalid contact."
+msgstr ""
+
+#: mod/network.php:928
+msgid "Latest Activity"
+msgstr ""
+
+#: mod/network.php:931
+msgid "Sort by latest activity"
+msgstr ""
+
+#: mod/network.php:936
+msgid "Latest Posts"
+msgstr ""
+
+#: mod/network.php:939
+msgid "Sort by post received date"
+msgstr ""
+
+#: mod/network.php:946 mod/profiles.php:579
+msgid "Personal"
+msgstr ""
+
+#: mod/network.php:949
+msgid "Posts that mention or involve you"
+msgstr ""
+
+#: mod/network.php:956
+msgid "New"
+msgstr ""
+
+#: mod/network.php:959
+msgid "Activity Stream - by date"
+msgstr ""
+
+#: mod/network.php:967
+msgid "Shared Links"
+msgstr ""
+
+#: mod/network.php:970
+msgid "Interesting Links"
+msgstr ""
+
+#: mod/network.php:977
+msgid "Starred"
+msgstr ""
+
+#: mod/network.php:980
+msgid "Favourite Posts"
+msgstr ""
+
+#: mod/notifications.php:39
+msgid "Invalid request identifier."
+msgstr ""
+
+#: mod/notifications.php:100 src/Content/Nav.php:249
+msgid "Notifications"
+msgstr ""
+
+#: mod/notifications.php:119
+msgid "Network Notifications"
+msgstr ""
+
+#: mod/notifications.php:124
+msgid "System Notifications"
+msgstr ""
+
+#: mod/notifications.php:129
+msgid "Personal Notifications"
msgstr ""
-#: mod/message.php:425
-msgid ""
-"No secure communications available. You <strong>may</strong> be able to "
-"respond from the sender's profile page."
+#: mod/notifications.php:134
+msgid "Home Notifications"
msgstr ""
-#: mod/message.php:429
-msgid "Send Reply"
+#: mod/notifications.php:157
+msgid "Show unread"
msgstr ""
-#: mod/message.php:512
-#, php-format
-msgid "Unknown sender - %s"
+#: mod/notifications.php:157
+msgid "Show all"
msgstr ""
-#: mod/message.php:514
-#, php-format
-msgid "You and %s"
+#: mod/notifications.php:168
+msgid "Show Ignored Requests"
msgstr ""
-#: mod/message.php:516
-#, php-format
-msgid "%s and You"
+#: mod/notifications.php:168
+msgid "Hide Ignored Requests"
msgstr ""
-#: mod/message.php:543
-#, php-format
-msgid "%d message"
-msgid_plural "%d messages"
-msgstr[0] ""
-msgstr[1] ""
+#: mod/notifications.php:181 mod/notifications.php:266
+msgid "Notification type:"
+msgstr ""
-#: mod/network.php:183 mod/search.php:35
-msgid "Remove term"
+#: mod/notifications.php:184
+msgid "Suggested by:"
msgstr ""
-#: mod/network.php:190 mod/search.php:44
-msgid "Saved Searches"
+#: mod/notifications.php:196 mod/notifications.php:283
+#: src/Module/Contact.php:615
+msgid "Hide this contact from others"
msgstr ""
-#: mod/network.php:191 src/Model/Group.php:483
-msgid "add"
+#: mod/notifications.php:198 mod/notifications.php:292
+#: src/Model/Contact.php:1270 src/Module/Admin/Users.php:286
+msgid "Approve"
msgstr ""
-#: mod/network.php:571
-#, 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] ""
-msgstr[1] ""
+#: mod/notifications.php:218
+msgid "Claims to be known to you: "
+msgstr ""
-#: mod/network.php:574
-msgid "Messages in this group won't be send to these receivers."
+#: mod/notifications.php:219
+msgid "yes"
msgstr ""
-#: mod/network.php:641
-msgid "No such group"
+#: mod/notifications.php:219
+msgid "no"
msgstr ""
-#: mod/network.php:662 src/Module/Group.php:288
-msgid "Group is empty"
+#: mod/notifications.php:220 mod/notifications.php:224
+msgid "Shall your connection be bidirectional or not?"
msgstr ""
-#: mod/network.php:666
+#: mod/notifications.php:221 mod/notifications.php:225
#, php-format
-msgid "Group: %s"
+msgid ""
+"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 ""
-#: mod/network.php:692
-msgid "Private messages to this person are at risk of public disclosure."
+#: mod/notifications.php:222
+#, 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 ""
-#: mod/network.php:695 src/Module/AllFriends.php:35
-#: src/Module/AllFriends.php:43
-msgid "Invalid contact."
+#: mod/notifications.php:226
+#, php-format
+msgid ""
+"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 ""
-#: mod/network.php:974
-msgid "Commented Order"
+#: mod/notifications.php:237
+msgid "Friend"
msgstr ""
-#: mod/network.php:977
-msgid "Sort by Comment Date"
+#: mod/notifications.php:238
+msgid "Sharer"
msgstr ""
-#: mod/network.php:982
-msgid "Posted Order"
+#: mod/notifications.php:238
+msgid "Subscriber"
msgstr ""
-#: mod/network.php:985
-msgid "Sort by Post Date"
+#: mod/notifications.php:278 src/Model/Profile.php:449
+#: src/Model/Profile.php:828 src/Module/Contact.php:632
+#: src/Module/Directory.php:143
+msgid "About:"
msgstr ""
-#: mod/network.php:995
-msgid "Posts that mention or involve you"
+#: mod/notifications.php:282 src/Model/Profile.php:446
+#: src/Model/Profile.php:767 src/Module/Directory.php:140
+msgid "Gender:"
msgstr ""
-#: mod/network.php:1002
-msgid "New"
+#: mod/notifications.php:289 src/Model/Profile.php:554
+#: src/Module/Contact.php:316
+msgid "Network:"
msgstr ""
-#: mod/network.php:1005
-msgid "Activity Stream - by date"
+#: mod/notifications.php:303
+msgid "No introductions."
msgstr ""
-#: mod/network.php:1013
-msgid "Shared Links"
+#: mod/notifications.php:337
+#, php-format
+msgid "No more %s notifications."
msgstr ""
-#: mod/network.php:1016
-msgid "Interesting Links"
+#: mod/openid.php:30
+msgid "OpenID protocol error. No ID returned."
msgstr ""
-#: mod/network.php:1023
-msgid "Starred"
+#: mod/openid.php:67
+msgid ""
+"Account not found. Please login to your existing account to add the OpenID "
+"to it."
msgstr ""
-#: mod/network.php:1026
-msgid "Favourite Posts"
+#: mod/openid.php:69
+msgid ""
+"Account not found. Please register a new account or login to your existing "
+"account to add the OpenID to it."
msgstr ""
-#: mod/notes.php:34 src/Model/Profile.php:975
-msgid "Personal Notes"
+#: mod/openid.php:75 src/Module/Login.php:90 src/Module/Login.php:144
+msgid "Login failed."
msgstr ""
-#: mod/photos.php:113 src/Model/Profile.php:936
+#: mod/photos.php:112 src/Model/Profile.php:932
msgid "Photo Albums"
msgstr ""
-#: mod/photos.php:114 mod/photos.php:1639
+#: mod/photos.php:113 mod/photos.php:1609
msgid "Recent Photos"
msgstr ""
-#: mod/photos.php:116 mod/photos.php:1152 mod/photos.php:1641
+#: mod/photos.php:115 mod/photos.php:1117 mod/photos.php:1611
msgid "Upload New Photos"
msgstr ""
-#: mod/photos.php:134 mod/settings.php:60 src/Module/BaseSettingsModule.php:18
+#: mod/photos.php:133 mod/settings.php:62 src/Module/BaseSettingsModule.php:18
msgid "everybody"
msgstr ""
-#: mod/photos.php:185
+#: mod/photos.php:170
msgid "Contact information unavailable"
msgstr ""
-#: mod/photos.php:207
+#: mod/photos.php:192
msgid "Album not found."
msgstr ""
-#: mod/photos.php:265
+#: mod/photos.php:250
msgid "Album successfully deleted"
msgstr ""
-#: mod/photos.php:267
+#: mod/photos.php:252
msgid "Album was empty."
msgstr ""
-#: mod/photos.php:590
+#: mod/photos.php:578
msgid "a photo"
msgstr ""
-#: mod/photos.php:590
+#: mod/photos.php:578
#, php-format
msgid "%1$s was tagged in %2$s by %3$s"
msgstr ""
-#: mod/photos.php:689
+#: mod/photos.php:680
msgid "Image upload didn't complete, please try again"
msgstr ""
-#: mod/photos.php:692
+#: mod/photos.php:683
msgid "Image file is missing"
msgstr ""
-#: mod/photos.php:697
+#: mod/photos.php:688
msgid ""
"Server can't accept new file upload at this time, please contact your "
"administrator"
msgstr ""
-#: mod/photos.php:723
+#: mod/photos.php:714
msgid "Image file is empty."
msgstr ""
-#: mod/photos.php:855
+#: mod/photos.php:846
msgid "No photos selected"
msgstr ""
-#: mod/photos.php:947 mod/videos.php:210
+#: mod/photos.php:912 mod/videos.php:168
msgid "Access to this item is restricted."
msgstr ""
-#: mod/photos.php:1001
+#: mod/photos.php:966
msgid "Upload Photos"
msgstr ""
-#: mod/photos.php:1005 mod/photos.php:1097
+#: mod/photos.php:970 mod/photos.php:1062
msgid "New album name: "
msgstr ""
-#: mod/photos.php:1006
+#: mod/photos.php:971
msgid "or select existing album:"
msgstr ""
-#: mod/photos.php:1007
+#: mod/photos.php:972
msgid "Do not show a status post for this upload"
msgstr ""
-#: mod/photos.php:1009 mod/photos.php:1383 mod/events.php:555
-#: src/Core/ACL.php:314
-msgid "Permissions"
-msgstr ""
-
-#: mod/photos.php:1023 mod/photos.php:1391 mod/settings.php:1213
+#: mod/photos.php:988 mod/photos.php:1356 mod/settings.php:1206
msgid "Show to Groups"
msgstr ""
-#: mod/photos.php:1024 mod/photos.php:1392 mod/settings.php:1214
+#: mod/photos.php:989 mod/photos.php:1357 mod/settings.php:1207
msgid "Show to Contacts"
msgstr ""
-#: mod/photos.php:1079
+#: mod/photos.php:1044
msgid "Do you really want to delete this photo album and all its photos?"
msgstr ""
-#: mod/photos.php:1081 mod/photos.php:1102
+#: mod/photos.php:1046 mod/photos.php:1067
msgid "Delete Album"
msgstr ""
-#: mod/photos.php:1108
+#: mod/photos.php:1073
msgid "Edit Album"
msgstr ""
-#: mod/photos.php:1109
+#: mod/photos.php:1074
msgid "Drop Album"
msgstr ""
-#: mod/photos.php:1114
+#: mod/photos.php:1079
msgid "Show Newest First"
msgstr ""
-#: mod/photos.php:1116
+#: mod/photos.php:1081
msgid "Show Oldest First"
msgstr ""
-#: mod/photos.php:1137 mod/photos.php:1624
+#: mod/photos.php:1102 mod/photos.php:1594
msgid "View Photo"
msgstr ""
-#: mod/photos.php:1174
+#: mod/photos.php:1139
msgid "Permission denied. Access to this item may be restricted."
msgstr ""
-#: mod/photos.php:1176
+#: mod/photos.php:1141
msgid "Photo not available"
msgstr ""
-#: mod/photos.php:1186
+#: mod/photos.php:1151
msgid "Do you really want to delete this photo?"
msgstr ""
-#: mod/photos.php:1188 mod/photos.php:1388
+#: mod/photos.php:1153 mod/photos.php:1353
msgid "Delete Photo"
msgstr ""
-#: mod/photos.php:1279
+#: mod/photos.php:1244
msgid "View photo"
msgstr ""
-#: mod/photos.php:1281
+#: mod/photos.php:1246
msgid "Edit photo"
msgstr ""
-#: mod/photos.php:1282
+#: mod/photos.php:1247
msgid "Delete photo"
msgstr ""
-#: mod/photos.php:1283
+#: mod/photos.php:1248
msgid "Use as profile photo"
msgstr ""
-#: mod/photos.php:1290
+#: mod/photos.php:1255
msgid "Private Photo"
msgstr ""
-#: mod/photos.php:1296
+#: mod/photos.php:1261
msgid "View Full Size"
msgstr ""
-#: mod/photos.php:1356
+#: mod/photos.php:1321
msgid "Tags: "
msgstr ""
-#: mod/photos.php:1359
+#: mod/photos.php:1324
msgid "[Select tags to remove]"
msgstr ""
-#: mod/photos.php:1374
+#: mod/photos.php:1339
msgid "New album name"
msgstr ""
-#: mod/photos.php:1375
+#: mod/photos.php:1340
msgid "Caption"
msgstr ""
-#: mod/photos.php:1376
+#: mod/photos.php:1341
msgid "Add a Tag"
msgstr ""
-#: mod/photos.php:1376
+#: mod/photos.php:1341
msgid "Example: @bob, @Barbara_Jensen, @jim@example.com, #California, #camping"
msgstr ""
-#: mod/photos.php:1377
+#: mod/photos.php:1342
msgid "Do not rotate"
msgstr ""
-#: mod/photos.php:1378
+#: mod/photos.php:1343
msgid "Rotate CW (right)"
msgstr ""
-#: mod/photos.php:1379
+#: mod/photos.php:1344
msgid "Rotate CCW (left)"
msgstr ""
-#: mod/photos.php:1413 src/Object/Post.php:313
+#: mod/photos.php:1378 src/Object/Post.php:310
msgid "I like this (toggle)"
msgstr ""
-#: mod/photos.php:1414 src/Object/Post.php:314
+#: mod/photos.php:1379 src/Object/Post.php:311
msgid "I don't like this (toggle)"
msgstr ""
-#: mod/photos.php:1429 mod/photos.php:1468 mod/photos.php:1528
-#: src/Module/Item/Compose.php:176 src/Module/Contact.php:1002
-#: src/Object/Post.php:876
+#: mod/photos.php:1394 mod/photos.php:1433 mod/photos.php:1498
+#: src/Module/Item/Compose.php:180 src/Module/Contact.php:1023
+#: src/Object/Post.php:881
msgid "This is you"
msgstr ""
-#: mod/photos.php:1431 mod/photos.php:1470 mod/photos.php:1530
-#: src/Object/Post.php:420 src/Object/Post.php:878
+#: mod/photos.php:1396 mod/photos.php:1435 mod/photos.php:1500
+#: src/Object/Post.php:420 src/Object/Post.php:883
msgid "Comment"
msgstr ""
-#: mod/photos.php:1559
+#: mod/photos.php:1529
msgid "Map"
msgstr ""
-#: mod/photos.php:1630 mod/videos.php:287
+#: mod/photos.php:1600 mod/videos.php:245
msgid "View Album"
msgstr ""
-#: mod/ping.php:272
-msgid "{0} wants to be your friend"
-msgstr ""
-
-#: mod/ping.php:288
-msgid "{0} requested registration"
-msgstr ""
-
-#: mod/poke.php:177
+#: mod/poke.php:178
msgid "Poke/Prod"
msgstr ""
-#: mod/poke.php:178
+#: mod/poke.php:179
msgid "poke, prod or do other things to somebody"
msgstr ""
-#: mod/poke.php:179
+#: mod/poke.php:180
msgid "Recipient"
msgstr ""
-#: mod/poke.php:180
+#: mod/poke.php:181
msgid "Choose what you wish to do to recipient"
msgstr ""
-#: mod/poke.php:183
+#: mod/poke.php:184
msgid "Make this post private"
msgstr ""
-#: mod/profile_photo.php:58
-msgid "Image uploaded but image cropping failed."
-msgstr ""
-
-#: mod/profile_photo.php:88 mod/profile_photo.php:97 mod/profile_photo.php:106
-#: mod/profile_photo.php:311
-#, php-format
-msgid "Image size reduction [%s] failed."
-msgstr ""
-
-#: mod/profile_photo.php:125
-msgid ""
-"Shift-reload the page or clear browser cache if the new photo does not "
-"display immediately."
-msgstr ""
-
-#: mod/profile_photo.php:133
-msgid "Unable to process image"
-msgstr ""
-
-#: mod/profile_photo.php:244
-msgid "Upload File:"
-msgstr ""
-
-#: mod/profile_photo.php:245
-msgid "Select a profile:"
-msgstr ""
-
-#: mod/profile_photo.php:250
-msgid "or"
+#: mod/profiles.php:62
+msgid "Profile deleted."
msgstr ""
-#: mod/profile_photo.php:251
-msgid "skip this step"
+#: mod/profiles.php:78 mod/profiles.php:114
+msgid "Profile-"
msgstr ""
-#: mod/profile_photo.php:251
-msgid "select a photo from your photo albums"
+#: mod/profiles.php:97 mod/profiles.php:135
+msgid "New profile created."
msgstr ""
-#: mod/profile_photo.php:264
-msgid "Crop Image"
+#: mod/profiles.php:120
+msgid "Profile unavailable to clone."
msgstr ""
-#: mod/profile_photo.php:265
-msgid "Please adjust the image cropping for optimum viewing."
+#: mod/profiles.php:206
+msgid "Profile Name is required."
msgstr ""
-#: mod/profile_photo.php:267
-msgid "Done Editing"
+#: mod/profiles.php:346
+msgid "Marital Status"
msgstr ""
-#: mod/profile_photo.php:301
-msgid "Image uploaded successfully."
+#: mod/profiles.php:349
+msgid "Romantic Partner"
msgstr ""
-#: mod/search.php:92
-msgid "Only logged in users are permitted to perform a search."
+#: mod/profiles.php:358
+msgid "Work/Employment"
msgstr ""
-#: mod/search.php:114
-msgid "Only one search per minute is permitted for not logged in users."
+#: mod/profiles.php:361
+msgid "Religion"
msgstr ""
-#: mod/search.php:134 src/Content/Text/HTML.php:893 src/Content/Nav.php:200
-msgid "Search"
+#: mod/profiles.php:364
+msgid "Political Views"
msgstr ""
-#: mod/search.php:228
-#, php-format
-msgid "Items tagged with: %s"
+#: mod/profiles.php:367
+msgid "Gender"
msgstr ""
-#: mod/search.php:230 src/Module/Contact.php:794
-#, php-format
-msgid "Results for: %s"
+#: mod/profiles.php:370
+msgid "Sexual Preference"
msgstr ""
-#: mod/subthread.php:104
-#, php-format
-msgid "%1$s is following %2$s's %3$s"
+#: mod/profiles.php:373
+msgid "XMPP"
msgstr ""
-#: mod/suggest.php:28
-msgid "Contact suggestion successfully ignored."
+#: mod/profiles.php:376
+msgid "Homepage"
msgstr ""
-#: mod/suggest.php:52
-msgid ""
-"No suggestions available. If this is a new site, please try again in 24 "
-"hours."
+#: mod/profiles.php:379 mod/profiles.php:578
+msgid "Interests"
msgstr ""
-#: mod/suggest.php:71
-msgid "Do you really want to delete this suggestion?"
+#: mod/profiles.php:382
+msgid "Address"
msgstr ""
-#: mod/suggest.php:89 mod/suggest.php:109
-msgid "Ignore/Hide"
+#: mod/profiles.php:389 mod/profiles.php:574
+msgid "Location"
msgstr ""
-#: mod/suggest.php:119 view/theme/vier/theme.php:204 src/Content/Widget.php:69
-msgid "Friend Suggestions"
+#: mod/profiles.php:469
+msgid "Profile updated."
msgstr ""
-#: mod/uexport.php:52
-msgid "Export account"
+#: mod/profiles.php:523
+msgid "Hide contacts and friends:"
msgstr ""
-#: mod/uexport.php:52
-msgid ""
-"Export your account info and contacts. Use this to make a backup of your "
-"account and/or to move it to another server."
+#: mod/profiles.php:528
+msgid "Hide your contact/friend list from viewers of this profile?"
msgstr ""
-#: mod/uexport.php:53
-msgid "Export all"
+#: mod/profiles.php:548
+msgid "Show more profile fields:"
msgstr ""
-#: mod/uexport.php:53
-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)"
+#: mod/profiles.php:560
+msgid "Profile Actions"
msgstr ""
-#: mod/uexport.php:59 mod/settings.php:131 src/Module/BaseSettingsModule.php:89
-msgid "Export personal data"
+#: mod/profiles.php:561
+msgid "Edit Profile Details"
msgstr ""
-#: mod/videos.php:123
-msgid "No videos selected"
+#: mod/profiles.php:563
+msgid "Change Profile Photo"
msgstr ""
-#: mod/videos.php:280 src/Model/Item.php:3477
-msgid "View Video"
+#: mod/profiles.php:565
+msgid "View this profile"
msgstr ""
-#: mod/videos.php:295
-msgid "Recent Videos"
+#: mod/profiles.php:566
+msgid "View all profiles"
msgstr ""
-#: mod/videos.php:297
-msgid "Upload New Videos"
+#: mod/profiles.php:567 mod/profiles.php:662 src/Model/Profile.php:419
+msgid "Edit visibility"
msgstr ""
-#: mod/display.php:254 mod/display.php:339
-msgid "The requested item doesn't exist or has been deleted."
+#: mod/profiles.php:568
+msgid "Create a new profile using these settings"
msgstr ""
-#: mod/display.php:417
-msgid "The feed for this item is unavailable."
+#: mod/profiles.php:569
+msgid "Clone this profile"
msgstr ""
-#: mod/events.php:118 mod/events.php:120
-msgid "Event can not end before it has started."
+#: mod/profiles.php:570
+msgid "Delete this profile"
msgstr ""
-#: mod/events.php:127 mod/events.php:129
-msgid "Event title and start time are required."
+#: mod/profiles.php:572
+msgid "Basic information"
msgstr ""
-#: mod/events.php:385
-msgid "Create New Event"
+#: mod/profiles.php:573
+msgid "Profile picture"
msgstr ""
-#: mod/events.php:508
-msgid "Event details"
+#: mod/profiles.php:575
+msgid "Preferences"
msgstr ""
-#: mod/events.php:509
-msgid "Starting date and Title are required."
+#: mod/profiles.php:576
+msgid "Status information"
msgstr ""
-#: mod/events.php:510 mod/events.php:515
-msgid "Event Starts:"
+#: mod/profiles.php:577
+msgid "Additional information"
msgstr ""
-#: mod/events.php:523 mod/events.php:548
-msgid "Finish date/time is not known or not relevant"
+#: mod/profiles.php:580
+msgid "Relation"
msgstr ""
-#: mod/events.php:525 mod/events.php:530
-msgid "Event Finishes:"
+#: mod/profiles.php:581 src/Util/Temporal.php:79 src/Util/Temporal.php:81
+msgid "Miscellaneous"
msgstr ""
-#: mod/events.php:536 mod/events.php:549
-msgid "Adjust for viewer timezone"
+#: mod/profiles.php:584
+msgid "Your Gender:"
msgstr ""
-#: mod/events.php:538
-msgid "Description:"
+#: mod/profiles.php:585
+msgid "<span class=\"heart\">♥</span> Marital Status:"
msgstr ""
-#: mod/events.php:540 mod/notifications.php:272 src/Model/Event.php:68
-#: src/Model/Event.php:95 src/Model/Event.php:437 src/Model/Event.php:933
-#: src/Model/Profile.php:447 src/Module/Directory.php:137
-#: src/Module/Contact.php:607
-msgid "Location:"
+#: mod/profiles.php:586 src/Model/Profile.php:804
+msgid "Sexual Preference:"
msgstr ""
-#: mod/events.php:542 mod/events.php:544
-msgid "Title:"
+#: mod/profiles.php:587
+msgid "Example: fishing photography software"
msgstr ""
-#: mod/events.php:545 mod/events.php:546
-msgid "Share this event"
+#: mod/profiles.php:592
+msgid "Profile Name:"
msgstr ""
-#: mod/events.php:553 src/Model/Profile.php:890
-msgid "Basic"
+#: mod/profiles.php:594
+msgid ""
+"This is your <strong>public</strong> profile.<br />It <strong>may</strong> "
+"be visible to anybody using the internet."
msgstr ""
-#: mod/events.php:554 src/Model/Profile.php:891 src/Module/Admin/Site.php:573
-#: src/Module/Contact.php:880
-msgid "Advanced"
+#: mod/profiles.php:595
+msgid "Your Full Name:"
msgstr ""
-#: mod/events.php:571
-msgid "Failed to remove event"
+#: mod/profiles.php:596
+msgid "Title/Description:"
msgstr ""
-#: mod/events.php:573
-msgid "Event removed"
+#: mod/profiles.php:599
+msgid "Street Address:"
msgstr ""
-#: mod/item.php:123
-msgid "Unable to locate original post."
+#: mod/profiles.php:600
+msgid "Locality/City:"
msgstr ""
-#: mod/item.php:323
-msgid "Empty post discarded."
+#: mod/profiles.php:601
+msgid "Region/State:"
msgstr ""
-#: mod/item.php:803
-#, php-format
-msgid ""
-"This message was sent to you by %s, a member of the Friendica social network."
+#: mod/profiles.php:602
+msgid "Postal/Zip Code:"
msgstr ""
-#: mod/item.php:805
-#, php-format
-msgid "You may visit them online at %s"
+#: mod/profiles.php:603
+msgid "Country:"
msgstr ""
-#: mod/item.php:806
-msgid ""
-"Please contact the sender by replying to this post if you do not wish to "
-"receive these messages."
+#: mod/profiles.php:604 src/Util/Temporal.php:148
+msgid "Age: "
msgstr ""
-#: mod/item.php:810
-#, php-format
-msgid "%s posted an update."
+#: mod/profiles.php:607
+msgid "Who: (if applicable)"
msgstr ""
-#: mod/notifications.php:40
-msgid "Invalid request identifier."
+#: mod/profiles.php:607
+msgid "Examples: cathy123, Cathy Williams, cathy@example.com"
msgstr ""
-#: mod/notifications.php:96 src/Content/Nav.php:249
-msgid "Notifications"
+#: mod/profiles.php:608
+msgid "Since [date]:"
msgstr ""
-#: mod/notifications.php:115
-msgid "Network Notifications"
+#: mod/profiles.php:610
+msgid "Tell us about yourself..."
msgstr ""
-#: mod/notifications.php:120
-msgid "System Notifications"
+#: mod/profiles.php:611
+msgid "XMPP (Jabber) address:"
msgstr ""
-#: mod/notifications.php:125
-msgid "Personal Notifications"
+#: mod/profiles.php:611
+msgid ""
+"The XMPP address will be propagated to your contacts so that they can follow "
+"you."
msgstr ""
-#: mod/notifications.php:130
-msgid "Home Notifications"
+#: mod/profiles.php:612
+msgid "Homepage URL:"
msgstr ""
-#: mod/notifications.php:153
-msgid "Show unread"
+#: mod/profiles.php:613 src/Model/Profile.php:812
+msgid "Hometown:"
msgstr ""
-#: mod/notifications.php:153
-msgid "Show all"
+#: mod/profiles.php:614 src/Model/Profile.php:820
+msgid "Political Views:"
msgstr ""
-#: mod/notifications.php:164
-msgid "Show Ignored Requests"
+#: mod/profiles.php:615
+msgid "Religious Views:"
msgstr ""
-#: mod/notifications.php:164
-msgid "Hide Ignored Requests"
+#: mod/profiles.php:616
+msgid "Public Keywords:"
msgstr ""
-#: mod/notifications.php:177 mod/notifications.php:262
-msgid "Notification type:"
+#: mod/profiles.php:616
+msgid "(Used for suggesting potential friends, can be seen by others)"
msgstr ""
-#: mod/notifications.php:180
-msgid "Suggested by:"
+#: mod/profiles.php:617
+msgid "Private Keywords:"
msgstr ""
-#: mod/notifications.php:192 mod/notifications.php:279
-#: src/Module/Contact.php:594
-msgid "Hide this contact from others"
+#: mod/profiles.php:617
+msgid "(Used for searching profiles, never shown to others)"
msgstr ""
-#: mod/notifications.php:194 mod/notifications.php:288
-#: src/Model/Contact.php:1238 src/Module/Admin/Users.php:286
-msgid "Approve"
+#: mod/profiles.php:618 src/Model/Profile.php:836
+msgid "Likes:"
msgstr ""
-#: mod/notifications.php:214
-msgid "Claims to be known to you: "
+#: mod/profiles.php:619 src/Model/Profile.php:840
+msgid "Dislikes:"
msgstr ""
-#: mod/notifications.php:215
-msgid "yes"
+#: mod/profiles.php:620
+msgid "Musical interests"
msgstr ""
-#: mod/notifications.php:215
-msgid "no"
+#: mod/profiles.php:621
+msgid "Books, literature"
msgstr ""
-#: mod/notifications.php:216 mod/notifications.php:220
-msgid "Shall your connection be bidirectional or not?"
+#: mod/profiles.php:622
+msgid "Television"
msgstr ""
-#: mod/notifications.php:217 mod/notifications.php:221
-#, php-format
-msgid ""
-"Accepting %s as a friend allows %s to subscribe to your posts, and you will "
-"also receive updates from them in your news feed."
+#: mod/profiles.php:623
+msgid "Film/dance/culture/entertainment"
msgstr ""
-#: mod/notifications.php:218
-#, 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."
+#: mod/profiles.php:624
+msgid "Hobbies/Interests"
msgstr ""
-#: mod/notifications.php:222
-#, php-format
-msgid ""
-"Accepting %s as a sharer allows them to subscribe to your posts, but you "
-"will not receive updates from them in your news feed."
+#: mod/profiles.php:625
+msgid "Love/romance"
msgstr ""
-#: mod/notifications.php:233
-msgid "Friend"
+#: mod/profiles.php:626
+msgid "Work/employment"
msgstr ""
-#: mod/notifications.php:234
-msgid "Sharer"
+#: mod/profiles.php:627
+msgid "School/education"
msgstr ""
-#: mod/notifications.php:234
-msgid "Subscriber"
+#: mod/profiles.php:628
+msgid "Contact information and Social Networks"
msgstr ""
-#: mod/notifications.php:274 src/Model/Profile.php:453
-#: src/Model/Profile.php:832 src/Module/Directory.php:145
-#: src/Module/Contact.php:611
-msgid "About:"
+#: mod/profiles.php:659 src/Model/Profile.php:415
+msgid "Profile Image"
msgstr ""
-#: mod/notifications.php:278 src/Model/Profile.php:450
-#: src/Model/Profile.php:771 src/Module/Directory.php:142
-msgid "Gender:"
+#: mod/profiles.php:661 src/Model/Profile.php:418
+msgid "visible to everybody"
msgstr ""
-#: mod/notifications.php:285 src/Model/Profile.php:558
-#: src/Module/Contact.php:295
-msgid "Network:"
+#: mod/profiles.php:668
+msgid "Edit/Manage Profiles"
msgstr ""
-#: mod/notifications.php:299
-msgid "No introductions."
+#: mod/profiles.php:669 src/Model/Profile.php:405 src/Model/Profile.php:426
+msgid "Change profile photo"
msgstr ""
-#: mod/notifications.php:333
-#, php-format
-msgid "No more %s notifications."
+#: mod/profiles.php:670 src/Model/Profile.php:406
+msgid "Create New Profile"
msgstr ""
-#: mod/openid.php:30
-msgid "OpenID protocol error. No ID returned."
+#: mod/regmod.php:53
+msgid "Account approved."
msgstr ""
-#: mod/openid.php:60
-msgid ""
-"Account not found and OpenID registration is not permitted on this site."
+#: mod/regmod.php:77
+#, php-format
+msgid "Registration revoked for %s"
msgstr ""
-#: mod/openid.php:108 src/Module/Login.php:88 src/Module/Login.php:139
-msgid "Login failed."
+#: mod/regmod.php:84
+msgid "Please login."
msgstr ""
-#: mod/settings.php:65 src/Module/BaseSettingsModule.php:24
+#: mod/settings.php:67 src/Module/BaseSettingsModule.php:24
msgid "Account"
msgstr ""
-#: mod/settings.php:73 src/Module/BaseSettingsModule.php:31
-#: src/Module/Settings/TwoFactor/Index.php:89
-#: src/Module/TwoFactor/Verify.php:62
+#: mod/settings.php:75 src/Module/Settings/TwoFactor/Index.php:89
+#: src/Module/TwoFactor/Verify.php:62 src/Module/BaseSettingsModule.php:31
msgid "Two-factor authentication"
msgstr ""
-#: mod/settings.php:80 src/Content/Nav.php:268 src/Model/Profile.php:402
+#: mod/settings.php:82 src/Content/Nav.php:266 src/Model/Profile.php:398
#: src/Module/BaseSettingsModule.php:38
msgid "Profiles"
msgstr ""
-#: mod/settings.php:88 src/Module/BaseAdminModule.php:84
+#: mod/settings.php:90 src/Module/BaseAdminModule.php:84
#: src/Module/BaseSettingsModule.php:46
msgid "Additional features"
msgstr ""
-#: mod/settings.php:96 src/Module/BaseSettingsModule.php:54
+#: mod/settings.php:98 src/Module/BaseSettingsModule.php:54
msgid "Display"
msgstr ""
-#: mod/settings.php:103 mod/settings.php:843
+#: mod/settings.php:105 mod/settings.php:835
#: src/Module/BaseSettingsModule.php:61
msgid "Social Networks"
msgstr ""
-#: mod/settings.php:110 src/Module/Admin/Addons/Details.php:100
+#: mod/settings.php:112 src/Module/Admin/Addons/Details.php:100
#: src/Module/Admin/Addons/Index.php:51 src/Module/BaseAdminModule.php:82
#: src/Module/BaseSettingsModule.php:68
msgid "Addons"
msgstr ""
-#: mod/settings.php:117 src/Content/Nav.php:263
-#: src/Module/BaseSettingsModule.php:75
+#: mod/settings.php:119 src/Module/BaseSettingsModule.php:75
msgid "Delegations"
msgstr ""
-#: mod/settings.php:124 src/Module/BaseSettingsModule.php:82
+#: mod/settings.php:126 src/Module/BaseSettingsModule.php:82
msgid "Connected apps"
msgstr ""
-#: mod/settings.php:138 src/Module/BaseSettingsModule.php:96
+#: mod/settings.php:133 src/Module/Settings/UserExport.php:52
+#: src/Module/BaseSettingsModule.php:89
+msgid "Export personal data"
+msgstr ""
+
+#: mod/settings.php:140 src/Module/BaseSettingsModule.php:96
msgid "Remove account"
msgstr ""
-#: mod/settings.php:147 view/theme/frio/theme.php:277 src/Content/Nav.php:265
+#: mod/settings.php:149 view/theme/frio/theme.php:277 src/Content/Nav.php:263
#: src/Module/Admin/Addons/Details.php:102
-#: src/Module/Admin/Themes/Details.php:107
-#: src/Module/BaseSettingsModule.php:105 src/Module/Welcome.php:33
+#: src/Module/Admin/Themes/Details.php:107 src/Module/Welcome.php:33
+#: src/Module/BaseSettingsModule.php:105
msgid "Settings"
msgstr ""
-#: mod/settings.php:190
+#: mod/settings.php:192
msgid "Missing some important data!"
msgstr ""
-#: mod/settings.php:192 mod/settings.php:703 src/Module/Contact.php:801
+#: mod/settings.php:194 mod/settings.php:695 src/Module/Contact.php:822
msgid "Update"
msgstr ""
-#: mod/settings.php:302
+#: mod/settings.php:301
msgid "Failed to connect with email account using the settings provided."
msgstr ""
-#: mod/settings.php:307
+#: mod/settings.php:306
msgid "Email settings updated."
msgstr ""
-#: mod/settings.php:323
+#: mod/settings.php:322
msgid "Features updated"
msgstr ""
-#: mod/settings.php:384
+#: mod/settings.php:383
msgid "The theme you chose isn't available."
msgstr ""
-#: mod/settings.php:396
+#: mod/settings.php:399
+msgid "Contact CSV file upload error"
+msgstr ""
+
+#: mod/settings.php:413
+msgid "Importing Contacts done"
+msgstr ""
+
+#: mod/settings.php:422
msgid "Relocate message has been send to your contacts"
msgstr ""
-#: mod/settings.php:408
+#: mod/settings.php:434
msgid "Passwords do not match."
msgstr ""
-#: mod/settings.php:416 src/Console/NewPassword.php:101
+#: mod/settings.php:442 src/Console/NewPassword.php:101
msgid "Password update failed. Please try again."
msgstr ""
-#: mod/settings.php:419 src/Console/NewPassword.php:104
+#: mod/settings.php:445 src/Console/NewPassword.php:104
msgid "Password changed."
msgstr ""
-#: mod/settings.php:422
+#: mod/settings.php:448
msgid "Password unchanged."
msgstr ""
-#: mod/settings.php:503
+#: mod/settings.php:530
msgid " Please use a shorter name."
msgstr ""
-#: mod/settings.php:506
+#: mod/settings.php:533
msgid " Name too short."
msgstr ""
-#: mod/settings.php:513 src/Module/Settings/TwoFactor/Index.php:72
+#: mod/settings.php:540 src/Module/Settings/TwoFactor/Index.php:72
msgid "Wrong Password"
msgstr ""
-#: mod/settings.php:518
+#: mod/settings.php:545
msgid "Invalid email."
msgstr ""
-#: mod/settings.php:524
+#: mod/settings.php:551
msgid "Cannot change to that email."
msgstr ""
-#: mod/settings.php:574
+#: mod/settings.php:589
msgid "Private forum has no privacy permissions. Using default privacy group."
msgstr ""
-#: mod/settings.php:577
+#: mod/settings.php:592
msgid "Private forum has no privacy permissions and no default privacy group."
msgstr ""
-#: mod/settings.php:617
+#: mod/settings.php:609
msgid "Settings updated."
msgstr ""
-#: mod/settings.php:676 mod/settings.php:702 mod/settings.php:736
+#: mod/settings.php:668 mod/settings.php:694 mod/settings.php:728
msgid "Add application"
msgstr ""
-#: mod/settings.php:680 mod/settings.php:706
+#: mod/settings.php:669 mod/settings.php:776 mod/settings.php:866
+#: mod/settings.php:945 mod/settings.php:1170
+#: src/Module/Admin/Addons/Index.php:52 src/Module/Admin/Features.php:69
+#: src/Module/Admin/Logs/Settings.php:65 src/Module/Admin/Themes/Index.php:97
+#: src/Module/Admin/Tos.php:50 src/Module/Admin/Site.php:568
+#: src/Module/Settings/Delegation.php:158
+msgid "Save Settings"
+msgstr ""
+
+#: mod/settings.php:672 mod/settings.php:698
msgid "Consumer Key"
msgstr ""
-#: mod/settings.php:681 mod/settings.php:707
+#: mod/settings.php:673 mod/settings.php:699
msgid "Consumer Secret"
msgstr ""
-#: mod/settings.php:682 mod/settings.php:708
+#: mod/settings.php:674 mod/settings.php:700
msgid "Redirect"
msgstr ""
-#: mod/settings.php:683 mod/settings.php:709
+#: mod/settings.php:675 mod/settings.php:701
msgid "Icon url"
msgstr ""
-#: mod/settings.php:694
+#: mod/settings.php:686
msgid "You can't edit this application."
msgstr ""
-#: mod/settings.php:735
+#: mod/settings.php:727
msgid "Connected Apps"
msgstr ""
-#: mod/settings.php:737 src/Object/Post.php:168 src/Object/Post.php:170
+#: mod/settings.php:729 src/Object/Post.php:165 src/Object/Post.php:167
msgid "Edit"
msgstr ""
-#: mod/settings.php:739
+#: mod/settings.php:731
msgid "Client key starts with"
msgstr ""
-#: mod/settings.php:740
+#: mod/settings.php:732
msgid "No name"
msgstr ""
-#: mod/settings.php:741
+#: mod/settings.php:733
msgid "Remove authorization"
msgstr ""
-#: mod/settings.php:752
+#: mod/settings.php:744
msgid "No Addon settings configured"
msgstr ""
-#: mod/settings.php:761
+#: mod/settings.php:753
msgid "Addon Settings"
msgstr ""
-#: mod/settings.php:775 src/Module/Admin/Features.php:58
+#: mod/settings.php:767 src/Module/Admin/Features.php:58
#: src/Module/Admin/Features.php:59
msgid "Off"
msgstr ""
-#: mod/settings.php:775 src/Module/Admin/Features.php:58
+#: mod/settings.php:767 src/Module/Admin/Features.php:58
#: src/Module/Admin/Features.php:59
msgid "On"
msgstr ""
-#: mod/settings.php:782
+#: mod/settings.php:774
msgid "Additional Features"
msgstr ""
-#: mod/settings.php:806 src/Content/ContactSelector.php:120
+#: mod/settings.php:798 src/Content/ContactSelector.php:120
msgid "Diaspora"
msgstr ""
-#: mod/settings.php:806 mod/settings.php:807
+#: mod/settings.php:798 mod/settings.php:799
msgid "enabled"
msgstr ""
-#: mod/settings.php:806 mod/settings.php:807
+#: mod/settings.php:798 mod/settings.php:799
msgid "disabled"
msgstr ""
-#: mod/settings.php:806 mod/settings.php:807
+#: mod/settings.php:798 mod/settings.php:799
#, php-format
msgid "Built-in support for %s connectivity is %s"
msgstr ""
-#: mod/settings.php:807
+#: mod/settings.php:799
msgid "GNU Social (OStatus)"
msgstr ""
-#: mod/settings.php:838
+#: mod/settings.php:830
msgid "Email access is disabled on this site."
msgstr ""
-#: mod/settings.php:848
+#: mod/settings.php:840
msgid "General Social Media Settings"
msgstr ""
-#: mod/settings.php:849
+#: mod/settings.php:841
msgid "Accept only top level posts by contacts you follow"
msgstr ""
-#: mod/settings.php:849
+#: mod/settings.php:841
msgid ""
"The system does an auto completion of threads when a comment arrives. This "
"has got the side effect that you can receive posts that had been started by "
"posts from people you really do follow."
msgstr ""
-#: mod/settings.php:850
+#: mod/settings.php:842
msgid "Disable Content Warning"
msgstr ""
-#: mod/settings.php:850
+#: mod/settings.php:842
msgid ""
"Users on networks like Mastodon or Pleroma are able to set a content warning "
"field which collapse their post by default. This disables the automatic "
"any other content filtering you eventually set up."
msgstr ""
-#: mod/settings.php:851
+#: mod/settings.php:843
msgid "Disable intelligent shortening"
msgstr ""
-#: mod/settings.php:851
+#: mod/settings.php:843
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 ""
-#: mod/settings.php:852
+#: mod/settings.php:844
msgid "Automatically follow any GNU Social (OStatus) followers/mentioners"
msgstr ""
-#: mod/settings.php:852
+#: mod/settings.php:844
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 ""
-#: mod/settings.php:853
+#: mod/settings.php:845
msgid "Default group for OStatus contacts"
msgstr ""
-#: mod/settings.php:854
+#: mod/settings.php:846
msgid "Your legacy GNU Social account"
msgstr ""
-#: mod/settings.php:854
+#: mod/settings.php:846
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 ""
-#: mod/settings.php:857
+#: mod/settings.php:849
msgid "Repair OStatus subscriptions"
msgstr ""
-#: mod/settings.php:861
+#: mod/settings.php:853
msgid "Email/Mailbox Setup"
msgstr ""
-#: mod/settings.php:862
+#: mod/settings.php:854
msgid ""
"If you wish to communicate with email contacts using this service "
"(optional), please specify how to connect to your mailbox."
msgstr ""
-#: mod/settings.php:863
+#: mod/settings.php:855
msgid "Last successful email check:"
msgstr ""
-#: mod/settings.php:865
+#: mod/settings.php:857
msgid "IMAP server name:"
msgstr ""
-#: mod/settings.php:866
+#: mod/settings.php:858
msgid "IMAP port:"
msgstr ""
-#: mod/settings.php:867
+#: mod/settings.php:859
msgid "Security:"
msgstr ""
-#: mod/settings.php:867 mod/settings.php:872
+#: mod/settings.php:859 mod/settings.php:864
msgid "None"
msgstr ""
-#: mod/settings.php:868
+#: mod/settings.php:860
msgid "Email login name:"
msgstr ""
-#: mod/settings.php:869
+#: mod/settings.php:861
msgid "Email password:"
msgstr ""
-#: mod/settings.php:870
+#: mod/settings.php:862
msgid "Reply-to address:"
msgstr ""
-#: mod/settings.php:871
+#: mod/settings.php:863
msgid "Send public posts to all email contacts:"
msgstr ""
-#: mod/settings.php:872
+#: mod/settings.php:864
msgid "Action after import:"
msgstr ""
-#: mod/settings.php:872 src/Content/Nav.php:251
+#: mod/settings.php:864 src/Content/Nav.php:251
msgid "Mark as seen"
msgstr ""
-#: mod/settings.php:872
+#: mod/settings.php:864
msgid "Move to folder"
msgstr ""
-#: mod/settings.php:873
+#: mod/settings.php:865
msgid "Move to folder:"
msgstr ""
-#: mod/settings.php:897 src/Module/Admin/Site.php:433
+#: mod/settings.php:889 src/Module/Admin/Site.php:433
msgid "No special theme for mobile devices"
msgstr ""
-#: mod/settings.php:905
+#: mod/settings.php:897
#, php-format
msgid "%s - (Unsupported)"
msgstr ""
-#: mod/settings.php:907 src/Module/Admin/Site.php:450
+#: mod/settings.php:899 src/Module/Admin/Site.php:450
#, php-format
msgid "%s - (Experimental)"
msgstr ""
-#: mod/settings.php:935 src/Core/L10n/L10n.php:370 src/Model/Event.php:395
+#: mod/settings.php:927 src/Core/L10n/L10n.php:404 src/Model/Event.php:396
msgid "Sunday"
msgstr ""
-#: mod/settings.php:935 src/Core/L10n/L10n.php:370 src/Model/Event.php:396
+#: mod/settings.php:927 src/Core/L10n/L10n.php:404 src/Model/Event.php:397
msgid "Monday"
msgstr ""
-#: mod/settings.php:951
+#: mod/settings.php:943
msgid "Display Settings"
msgstr ""
-#: mod/settings.php:957
+#: mod/settings.php:949
msgid "Display Theme:"
msgstr ""
-#: mod/settings.php:958
+#: mod/settings.php:950
msgid "Mobile Theme:"
msgstr ""
-#: mod/settings.php:959
+#: mod/settings.php:951
msgid "Suppress warning of insecure networks"
msgstr ""
-#: mod/settings.php:959
+#: mod/settings.php:951
msgid ""
"Should the system suppress the warning that the current group contains "
"members of networks that can't receive non public postings."
msgstr ""
-#: mod/settings.php:960
+#: mod/settings.php:952
msgid "Update browser every xx seconds"
msgstr ""
-#: mod/settings.php:960
+#: mod/settings.php:952
msgid "Minimum of 10 seconds. Enter -1 to disable it."
msgstr ""
-#: mod/settings.php:961
+#: mod/settings.php:953
msgid "Number of items to display per page:"
msgstr ""
-#: mod/settings.php:961 mod/settings.php:962
+#: mod/settings.php:953 mod/settings.php:954
msgid "Maximum of 100 items"
msgstr ""
-#: mod/settings.php:962
+#: mod/settings.php:954
msgid "Number of items to display per page when viewed from mobile device:"
msgstr ""
-#: mod/settings.php:963
+#: mod/settings.php:955
msgid "Don't show emoticons"
msgstr ""
-#: mod/settings.php:964
+#: mod/settings.php:956
msgid "Calendar"
msgstr ""
-#: mod/settings.php:965
+#: mod/settings.php:957
msgid "Beginning of week:"
msgstr ""
-#: mod/settings.php:966
+#: mod/settings.php:958
msgid "Don't show notices"
msgstr ""
-#: mod/settings.php:967
+#: mod/settings.php:959
msgid "Infinite scroll"
msgstr ""
-#: mod/settings.php:968
+#: mod/settings.php:960
msgid "Automatic updates only at the top of the network page"
msgstr ""
-#: mod/settings.php:968
+#: mod/settings.php:960
msgid ""
"When disabled, the network page is updated all the time, which could be "
"confusing while reading."
msgstr ""
-#: mod/settings.php:969
+#: mod/settings.php:961
msgid "Bandwidth Saver Mode"
msgstr ""
-#: mod/settings.php:969
+#: mod/settings.php:961
msgid ""
"When enabled, embedded content is not displayed on automatic updates, they "
"only show on page reload."
msgstr ""
-#: mod/settings.php:970
+#: mod/settings.php:962
msgid "Smart Threading"
msgstr ""
-#: mod/settings.php:970
+#: mod/settings.php:962
msgid ""
"When enabled, suppress extraneous thread indentation while keeping it where "
"it matters. Only works if threading is available and enabled."
msgstr ""
-#: mod/settings.php:972
+#: mod/settings.php:964
msgid "General Theme Settings"
msgstr ""
-#: mod/settings.php:973
+#: mod/settings.php:965
msgid "Custom Theme Settings"
msgstr ""
-#: mod/settings.php:974
+#: mod/settings.php:966
msgid "Content Settings"
msgstr ""
-#: mod/settings.php:975 view/theme/duepuntozero/config.php:73
+#: mod/settings.php:967 view/theme/duepuntozero/config.php:73
#: view/theme/frio/config.php:128 view/theme/quattro/config.php:75
-#: view/theme/vier/config.php:121
+#: view/theme/vier/config.php:123
msgid "Theme settings"
msgstr ""
-#: mod/settings.php:989
+#: mod/settings.php:981
msgid "Unable to find your profile. Please contact your admin."
msgstr ""
-#: mod/settings.php:1028
+#: mod/settings.php:1020
msgid "Account Types"
msgstr ""
-#: mod/settings.php:1029
+#: mod/settings.php:1021
msgid "Personal Page Subtypes"
msgstr ""
-#: mod/settings.php:1030
+#: mod/settings.php:1022
msgid "Community Forum Subtypes"
msgstr ""
-#: mod/settings.php:1037 src/Module/Admin/Users.php:229
+#: mod/settings.php:1029 src/Module/Admin/Users.php:229
msgid "Personal Page"
msgstr ""
-#: mod/settings.php:1038
+#: mod/settings.php:1030
msgid "Account for a personal profile."
msgstr ""
-#: mod/settings.php:1041 src/Module/Admin/Users.php:230
+#: mod/settings.php:1033 src/Module/Admin/Users.php:230
msgid "Organisation Page"
msgstr ""
-#: mod/settings.php:1042
+#: mod/settings.php:1034
msgid ""
"Account for an organisation that automatically approves contact requests as "
"\"Followers\"."
msgstr ""
-#: mod/settings.php:1045 src/Module/Admin/Users.php:231
+#: mod/settings.php:1037 src/Module/Admin/Users.php:231
msgid "News Page"
msgstr ""
-#: mod/settings.php:1046
+#: mod/settings.php:1038
msgid ""
"Account for a news reflector that automatically approves contact requests as "
"\"Followers\"."
msgstr ""
-#: mod/settings.php:1049 src/Module/Admin/Users.php:232
+#: mod/settings.php:1041 src/Module/Admin/Users.php:232
msgid "Community Forum"
msgstr ""
-#: mod/settings.php:1050
+#: mod/settings.php:1042
msgid "Account for community discussions."
msgstr ""
-#: mod/settings.php:1053 src/Module/Admin/Users.php:222
+#: mod/settings.php:1045 src/Module/Admin/Users.php:222
msgid "Normal Account Page"
msgstr ""
-#: mod/settings.php:1054
+#: mod/settings.php:1046
msgid ""
"Account for a regular personal profile that requires manual approval of "
"\"Friends\" and \"Followers\"."
msgstr ""
-#: mod/settings.php:1057 src/Module/Admin/Users.php:223
+#: mod/settings.php:1049 src/Module/Admin/Users.php:223
msgid "Soapbox Page"
msgstr ""
-#: mod/settings.php:1058
+#: mod/settings.php:1050
msgid ""
"Account for a public profile that automatically approves contact requests as "
"\"Followers\"."
msgstr ""
-#: mod/settings.php:1061 src/Module/Admin/Users.php:224
+#: mod/settings.php:1053 src/Module/Admin/Users.php:224
msgid "Public Forum"
msgstr ""
-#: mod/settings.php:1062
+#: mod/settings.php:1054
msgid "Automatically approves all contact requests."
msgstr ""
-#: mod/settings.php:1065 src/Module/Admin/Users.php:225
+#: mod/settings.php:1057 src/Module/Admin/Users.php:225
msgid "Automatic Friend Page"
msgstr ""
-#: mod/settings.php:1066
+#: mod/settings.php:1058
msgid ""
"Account for a popular profile that automatically approves contact requests "
"as \"Friends\"."
msgstr ""
-#: mod/settings.php:1069
+#: mod/settings.php:1061
msgid "Private Forum [Experimental]"
msgstr ""
-#: mod/settings.php:1070
+#: mod/settings.php:1062
msgid "Requires manual approval of contact requests."
msgstr ""
-#: mod/settings.php:1081
+#: mod/settings.php:1073
msgid "OpenID:"
msgstr ""
-#: mod/settings.php:1081
+#: mod/settings.php:1073
msgid "(Optional) Allow this OpenID to login to this account."
msgstr ""
-#: mod/settings.php:1089
+#: mod/settings.php:1081
msgid "Publish your default profile in your local site directory?"
msgstr ""
-#: mod/settings.php:1089
+#: mod/settings.php:1081
#, php-format
msgid ""
"Your profile will be published in this node's <a href=\"%s\">local "
"system settings."
msgstr ""
-#: mod/settings.php:1095
+#: mod/settings.php:1087
msgid "Publish your default profile in the global social directory?"
msgstr ""
-#: mod/settings.php:1095
+#: mod/settings.php:1087
#, php-format
msgid ""
"Your profile will be published in the global friendica directories (e.g. <a "
"href=\"%s\">%s</a>). Your profile will be visible in public."
msgstr ""
-#: mod/settings.php:1095
+#: mod/settings.php:1087
msgid ""
"This setting also determines whether Friendica will inform search engines "
"that your profile should be indexed or not. Third-party search engines may "
"or may not respect this setting."
msgstr ""
-#: mod/settings.php:1102
+#: mod/settings.php:1094
msgid "Hide your contact/friend list from viewers of your default profile?"
msgstr ""
-#: mod/settings.php:1102
+#: mod/settings.php:1094
msgid ""
"Your contact list won't be shown in your default profile page. You can "
"decide to show your contact list separately for each additional profile you "
"create"
msgstr ""
-#: mod/settings.php:1106
+#: mod/settings.php:1098
msgid "Hide your profile details from anonymous viewers?"
msgstr ""
-#: mod/settings.php:1106
+#: mod/settings.php:1098
msgid ""
"Anonymous visitors will only see your profile picture, your display name and "
"the nickname you are using on your profile page. Your public posts and "
"replies will still be accessible by other means."
msgstr ""
-#: mod/settings.php:1110
+#: mod/settings.php:1102
msgid "Allow friends to post to your profile page?"
msgstr ""
-#: mod/settings.php:1110
+#: mod/settings.php:1102
msgid ""
"Your contacts may write posts on your profile wall. These posts will be "
"distributed to your contacts"
msgstr ""
-#: mod/settings.php:1114
+#: mod/settings.php:1106
msgid "Allow friends to tag your posts?"
msgstr ""
-#: mod/settings.php:1114
+#: mod/settings.php:1106
msgid "Your contacts can add additional tags to your posts."
msgstr ""
-#: mod/settings.php:1118
+#: mod/settings.php:1110
msgid "Allow us to suggest you as a potential friend to new members?"
msgstr ""
-#: mod/settings.php:1118
+#: mod/settings.php:1110
msgid "If you like, Friendica may suggest new members to add you as a contact."
msgstr ""
-#: mod/settings.php:1122
+#: mod/settings.php:1114
msgid "Permit unknown people to send you private mail?"
msgstr ""
-#: mod/settings.php:1122
+#: mod/settings.php:1114
msgid ""
"Friendica network users may send you private messages even if they are not "
"in your contact list."
msgstr ""
-#: mod/settings.php:1126
+#: mod/settings.php:1118
msgid "Profile is <strong>not published</strong>."
msgstr ""
-#: mod/settings.php:1132
+#: mod/settings.php:1124
#, php-format
msgid "Your Identity Address is <strong>'%s'</strong> or '%s'."
msgstr ""
-#: mod/settings.php:1139
+#: mod/settings.php:1131
msgid "Automatically expire posts after this many days:"
msgstr ""
-#: mod/settings.php:1139
+#: mod/settings.php:1131
msgid "If empty, posts will not expire. Expired posts will be deleted"
msgstr ""
-#: mod/settings.php:1140
+#: mod/settings.php:1132
msgid "Advanced expiration settings"
msgstr ""
-#: mod/settings.php:1141
+#: mod/settings.php:1133
msgid "Advanced Expiration"
msgstr ""
-#: mod/settings.php:1142
+#: mod/settings.php:1134
msgid "Expire posts:"
msgstr ""
-#: mod/settings.php:1143
+#: mod/settings.php:1135
msgid "Expire personal notes:"
msgstr ""
-#: mod/settings.php:1144
+#: mod/settings.php:1136
msgid "Expire starred posts:"
msgstr ""
-#: mod/settings.php:1145
+#: mod/settings.php:1137
msgid "Expire photos:"
msgstr ""
-#: mod/settings.php:1146
+#: mod/settings.php:1138
msgid "Only expire posts by others:"
msgstr ""
-#: mod/settings.php:1176
+#: mod/settings.php:1168
msgid "Account Settings"
msgstr ""
-#: mod/settings.php:1184
+#: mod/settings.php:1176
msgid "Password Settings"
msgstr ""
-#: mod/settings.php:1185 src/Module/Register.php:130
+#: mod/settings.php:1177 src/Module/Register.php:124
msgid "New Password:"
msgstr ""
-#: mod/settings.php:1185
+#: mod/settings.php:1177
msgid ""
"Allowed characters are a-z, A-Z, 0-9 and special characters except white "
"spaces, accentuated letters and colon (:)."
msgstr ""
-#: mod/settings.php:1186 src/Module/Register.php:131
+#: mod/settings.php:1178 src/Module/Register.php:125
msgid "Confirm:"
msgstr ""
-#: mod/settings.php:1186
+#: mod/settings.php:1178
msgid "Leave password fields blank unless changing"
msgstr ""
-#: mod/settings.php:1187
+#: mod/settings.php:1179
msgid "Current Password:"
msgstr ""
-#: mod/settings.php:1187 mod/settings.php:1188
+#: mod/settings.php:1179 mod/settings.php:1180
msgid "Your current password to confirm the changes"
msgstr ""
-#: mod/settings.php:1188
+#: mod/settings.php:1180
msgid "Password:"
msgstr ""
-#: mod/settings.php:1192
+#: mod/settings.php:1183
+msgid "Delete OpenID URL"
+msgstr ""
+
+#: mod/settings.php:1185
msgid "Basic Settings"
msgstr ""
-#: mod/settings.php:1193 src/Model/Profile.php:764
+#: mod/settings.php:1186 src/Model/Profile.php:760
msgid "Full Name:"
msgstr ""
-#: mod/settings.php:1194
+#: mod/settings.php:1187
msgid "Email Address:"
msgstr ""
-#: mod/settings.php:1195
+#: mod/settings.php:1188
msgid "Your Timezone:"
msgstr ""
-#: mod/settings.php:1196
+#: mod/settings.php:1189
msgid "Your Language:"
msgstr ""
-#: mod/settings.php:1196
+#: mod/settings.php:1189
msgid ""
"Set the language we use to show you friendica interface and to send you "
"emails"
msgstr ""
-#: mod/settings.php:1197
+#: mod/settings.php:1190
msgid "Default Post Location:"
msgstr ""
-#: mod/settings.php:1198
+#: mod/settings.php:1191
msgid "Use Browser Location:"
msgstr ""
-#: mod/settings.php:1201
+#: mod/settings.php:1194
msgid "Security and Privacy Settings"
msgstr ""
-#: mod/settings.php:1203
+#: mod/settings.php:1196
msgid "Maximum Friend Requests/Day:"
msgstr ""
-#: mod/settings.php:1203 mod/settings.php:1232
+#: mod/settings.php:1196 mod/settings.php:1225
msgid "(to prevent spam abuse)"
msgstr ""
-#: mod/settings.php:1204
+#: mod/settings.php:1197
msgid "Default Post Permissions"
msgstr ""
-#: mod/settings.php:1205
+#: mod/settings.php:1198
msgid "(click to open/close)"
msgstr ""
-#: mod/settings.php:1215
+#: mod/settings.php:1208
msgid "Default Private Post"
msgstr ""
-#: mod/settings.php:1216
+#: mod/settings.php:1209
msgid "Default Public Post"
msgstr ""
-#: mod/settings.php:1220
+#: mod/settings.php:1213
msgid "Default Permissions for New Posts"
msgstr ""
-#: mod/settings.php:1232
+#: mod/settings.php:1225
msgid "Maximum private messages per day from unknown people:"
msgstr ""
-#: mod/settings.php:1235
+#: mod/settings.php:1228
msgid "Notification Settings"
msgstr ""
-#: mod/settings.php:1236
+#: mod/settings.php:1229
msgid "Send a notification email when:"
msgstr ""
-#: mod/settings.php:1237
+#: mod/settings.php:1230
msgid "You receive an introduction"
msgstr ""
-#: mod/settings.php:1238
+#: mod/settings.php:1231
msgid "Your introductions are confirmed"
msgstr ""
-#: mod/settings.php:1239
+#: mod/settings.php:1232
msgid "Someone writes on your profile wall"
msgstr ""
-#: mod/settings.php:1240
+#: mod/settings.php:1233
msgid "Someone writes a followup comment"
msgstr ""
-#: mod/settings.php:1241
+#: mod/settings.php:1234
msgid "You receive a private message"
msgstr ""
-#: mod/settings.php:1242
+#: mod/settings.php:1235
msgid "You receive a friend suggestion"
msgstr ""
-#: mod/settings.php:1243
+#: mod/settings.php:1236
msgid "You are tagged in a post"
msgstr ""
-#: mod/settings.php:1244
+#: mod/settings.php:1237
msgid "You are poked/prodded/etc. in a post"
msgstr ""
-#: mod/settings.php:1246
+#: mod/settings.php:1239
msgid "Activate desktop notifications"
msgstr ""
-#: mod/settings.php:1246
+#: mod/settings.php:1239
msgid "Show desktop popup on new notifications"
msgstr ""
-#: mod/settings.php:1248
+#: mod/settings.php:1241
msgid "Text-only notification emails"
msgstr ""
-#: mod/settings.php:1250
+#: mod/settings.php:1243
msgid "Send text only notification emails, without the html part"
msgstr ""
-#: mod/settings.php:1252
+#: mod/settings.php:1245
msgid "Show detailled notifications"
msgstr ""
-#: mod/settings.php:1254
+#: mod/settings.php:1247
msgid ""
"Per default, notifications are condensed to a single notification per item. "
"When enabled every notification is displayed."
msgstr ""
-#: mod/settings.php:1256
+#: mod/settings.php:1249
msgid "Advanced Account/Page Type Settings"
msgstr ""
-#: mod/settings.php:1257
+#: mod/settings.php:1250
msgid "Change the behaviour of this account for special situations"
msgstr ""
-#: mod/settings.php:1260
+#: mod/settings.php:1253
+msgid "Import Contacts"
+msgstr ""
+
+#: mod/settings.php:1254
+msgid ""
+"Upload a CSV file that contains the handle of your followed accounts in the "
+"first column you exported from the old account."
+msgstr ""
+
+#: mod/settings.php:1255
+msgid "Upload File"
+msgstr ""
+
+#: mod/settings.php:1257
msgid "Relocate"
msgstr ""
-#: mod/settings.php:1261
+#: mod/settings.php:1258
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 ""
-#: mod/settings.php:1262
+#: mod/settings.php:1259
msgid "Resend relocate message to contacts"
msgstr ""
-#: view/theme/duepuntozero/config.php:55 src/Model/User.php:745
+#: mod/subthread.php:107
+#, php-format
+msgid "%1$s is following %2$s's %3$s"
+msgstr ""
+
+#: mod/tagrm.php:31
+msgid "Tag(s) removed"
+msgstr ""
+
+#: mod/tagrm.php:101
+msgid "Remove Item Tag"
+msgstr ""
+
+#: mod/tagrm.php:103
+msgid "Select a tag to remove: "
+msgstr ""
+
+#: mod/tagrm.php:114 src/Module/Settings/Delegation.php:167
+msgid "Remove"
+msgstr ""
+
+#: mod/uimport.php:30
+msgid "User imports on closed servers can only be done by an administrator."
+msgstr ""
+
+#: mod/uimport.php:39 src/Module/Register.php:60
+msgid ""
+"This site has exceeded the number of allowed daily account registrations. "
+"Please try again tomorrow."
+msgstr ""
+
+#: mod/uimport.php:46 src/Module/Register.php:135
+msgid "Import"
+msgstr ""
+
+#: mod/uimport.php:48
+msgid "Move account"
+msgstr ""
+
+#: mod/uimport.php:49
+msgid "You can import an account from another Friendica server."
+msgstr ""
+
+#: mod/uimport.php:50
+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 ""
+
+#: mod/uimport.php:51
+msgid ""
+"This feature is experimental. We can't import contacts from the OStatus "
+"network (GNU Social/Statusnet) or from Diaspora"
+msgstr ""
+
+#: mod/uimport.php:52
+msgid "Account file"
+msgstr ""
+
+#: mod/uimport.php:52
+msgid ""
+"To export your account, go to \"Settings->Export your personal data\" and "
+"select \"Export account\""
+msgstr ""
+
+#: mod/unfollow.php:36 mod/unfollow.php:92
+msgid "You aren't following this contact."
+msgstr ""
+
+#: mod/unfollow.php:46 mod/unfollow.php:98
+msgid "Unfollowing is currently not supported by your network."
+msgstr ""
+
+#: mod/unfollow.php:67
+msgid "Contact unfollowed"
+msgstr ""
+
+#: mod/unfollow.php:118
+msgid "Disconnect/Unfollow"
+msgstr ""
+
+#: mod/videos.php:120
+msgid "No videos selected"
+msgstr ""
+
+#: mod/videos.php:238 src/Model/Item.php:3514
+msgid "View Video"
+msgstr ""
+
+#: mod/videos.php:253
+msgid "Recent Videos"
+msgstr ""
+
+#: mod/videos.php:255
+msgid "Upload New Videos"
+msgstr ""
+
+#: mod/wall_attach.php:27 mod/wall_attach.php:34 mod/wall_attach.php:72
+#: mod/wall_upload.php:43 mod/wall_upload.php:59 mod/wall_upload.php:104
+#: mod/wall_upload.php:155 mod/wall_upload.php:158
+msgid "Invalid request."
+msgstr ""
+
+#: mod/wall_attach.php:90
+msgid "Sorry, maybe your upload is bigger than the PHP configuration allows"
+msgstr ""
+
+#: mod/wall_attach.php:90
+msgid "Or - did you try to upload an empty file?"
+msgstr ""
+
+#: mod/wall_attach.php:101
+#, php-format
+msgid "File exceeds size limit of %s"
+msgstr ""
+
+#: mod/wall_attach.php:116
+msgid "File upload failed."
+msgstr ""
+
+#: mod/wall_upload.php:231
+msgid "Wall Photos"
+msgstr ""
+
+#: mod/wallmessage.php:52 mod/wallmessage.php:115
+#, php-format
+msgid "Number of daily wall messages for %s exceeded. Message failed."
+msgstr ""
+
+#: mod/wallmessage.php:63
+msgid "Unable to check your home location."
+msgstr ""
+
+#: mod/wallmessage.php:89 mod/wallmessage.php:98
+msgid "No recipient."
+msgstr ""
+
+#: mod/wallmessage.php:129
+#, php-format
+msgid ""
+"If you wish for %s to respond, please check that the privacy settings on "
+"your site allow private mail from unknown senders."
+msgstr ""
+
+#: view/theme/duepuntozero/config.php:55 src/Model/User.php:790
msgid "default"
msgstr ""
"Resize image to repeat it on a single row, either vertical or horizontal."
msgstr ""
-#: view/theme/frio/php/Image.php:27
-msgid "Mosaic"
+#: view/theme/frio/php/Image.php:27
+msgid "Mosaic"
+msgstr ""
+
+#: view/theme/frio/php/Image.php:27
+msgid "Repeat image to fill the screen."
+msgstr ""
+
+#: view/theme/frio/theme.php:246
+msgid "Guest"
+msgstr ""
+
+#: view/theme/frio/theme.php:251
+msgid "Visitor"
+msgstr ""
+
+#: view/theme/frio/theme.php:267 src/Content/Nav.php:160
+#: src/Model/Profile.php:913 src/Module/Settings/TwoFactor/Index.php:91
+#: src/Module/Contact.php:637 src/Module/Contact.php:852
+msgid "Status"
+msgstr ""
+
+#: view/theme/frio/theme.php:267 src/Content/Nav.php:160
+#: src/Content/Nav.php:244
+msgid "Your posts and conversations"
+msgstr ""
+
+#: view/theme/frio/theme.php:268 src/Content/Nav.php:161
+msgid "Your profile page"
+msgstr ""
+
+#: view/theme/frio/theme.php:269 src/Content/Nav.php:162
+msgid "Your photos"
+msgstr ""
+
+#: view/theme/frio/theme.php:270 src/Content/Nav.php:163
+#: src/Model/Profile.php:937 src/Model/Profile.php:940
+msgid "Videos"
+msgstr ""
+
+#: view/theme/frio/theme.php:270 src/Content/Nav.php:163
+msgid "Your videos"
+msgstr ""
+
+#: view/theme/frio/theme.php:271 src/Content/Nav.php:164
+msgid "Your events"
+msgstr ""
+
+#: view/theme/frio/theme.php:274 src/Content/Nav.php:241
+msgid "Network"
+msgstr ""
+
+#: view/theme/frio/theme.php:274 src/Content/Nav.php:241
+msgid "Conversations from your friends"
+msgstr ""
+
+#: view/theme/frio/theme.php:275 src/Content/Nav.php:228
+#: src/Model/Profile.php:952 src/Model/Profile.php:963
+msgid "Events and Calendar"
+msgstr ""
+
+#: view/theme/frio/theme.php:276 src/Content/Nav.php:254
+msgid "Private mail"
+msgstr ""
+
+#: view/theme/frio/theme.php:277 src/Content/Nav.php:263
+msgid "Account settings"
+msgstr ""
+
+#: view/theme/frio/theme.php:278 src/Content/Text/HTML.php:922
+#: src/Content/Nav.php:205 src/Content/Nav.php:269 src/Model/Profile.php:992
+#: src/Model/Profile.php:995 src/Module/Contact.php:795
+#: src/Module/Contact.php:880
+msgid "Contacts"
msgstr ""
-#: view/theme/frio/php/Image.php:27
-msgid "Repeat image to fill the screen."
+#: view/theme/frio/theme.php:278 src/Content/Nav.php:269
+msgid "Manage/edit friends and contacts"
msgstr ""
#: view/theme/frio/config.php:111
msgid "Leave background image and color empty for theme defaults"
msgstr ""
-#: view/theme/frio/theme.php:246
-msgid "Guest"
-msgstr ""
-
-#: view/theme/frio/theme.php:251
-msgid "Visitor"
-msgstr ""
-
-#: view/theme/frio/theme.php:267 src/Content/Nav.php:160
-#: src/Model/Profile.php:917 src/Module/Settings/TwoFactor/Index.php:91
-#: src/Module/Contact.php:616 src/Module/Contact.php:831
-msgid "Status"
-msgstr ""
-
-#: view/theme/frio/theme.php:267 src/Content/Nav.php:160
-#: src/Content/Nav.php:244
-msgid "Your posts and conversations"
-msgstr ""
-
-#: view/theme/frio/theme.php:268 src/Content/Nav.php:161
-msgid "Your profile page"
-msgstr ""
-
-#: view/theme/frio/theme.php:269 src/Content/Nav.php:162
-msgid "Your photos"
-msgstr ""
-
-#: view/theme/frio/theme.php:270 src/Content/Nav.php:163
-#: src/Model/Profile.php:941 src/Model/Profile.php:944
-msgid "Videos"
-msgstr ""
-
-#: view/theme/frio/theme.php:270 src/Content/Nav.php:163
-msgid "Your videos"
-msgstr ""
-
-#: view/theme/frio/theme.php:271 src/Content/Nav.php:164
-msgid "Your events"
-msgstr ""
-
-#: view/theme/frio/theme.php:274 src/Core/NotificationsManager.php:151
-#: src/Content/Nav.php:241
-msgid "Network"
-msgstr ""
-
-#: view/theme/frio/theme.php:274 src/Content/Nav.php:241
-msgid "Conversations from your friends"
-msgstr ""
-
-#: view/theme/frio/theme.php:275 src/Content/Nav.php:228
-#: src/Model/Profile.php:956 src/Model/Profile.php:967
-msgid "Events and Calendar"
-msgstr ""
-
-#: view/theme/frio/theme.php:276 src/Content/Nav.php:254
-msgid "Private mail"
-msgstr ""
-
-#: view/theme/frio/theme.php:277 src/Content/Nav.php:265
-msgid "Account settings"
-msgstr ""
-
-#: view/theme/frio/theme.php:278 src/Content/Text/HTML.php:904
-#: src/Content/Nav.php:205 src/Content/Nav.php:271 src/Model/Profile.php:996
-#: src/Model/Profile.php:999 src/Module/Contact.php:774
-#: src/Module/Contact.php:859
-msgid "Contacts"
-msgstr ""
-
-#: view/theme/frio/theme.php:278 src/Content/Nav.php:271
-msgid "Manage/edit friends and contacts"
-msgstr ""
-
#: view/theme/quattro/config.php:76
msgid "Alignment"
msgstr ""
msgid "Textareas font size"
msgstr ""
-#: view/theme/vier/config.php:76
+#: view/theme/vier/config.php:78
msgid "Comma separated list of helper forums"
msgstr ""
-#: view/theme/vier/config.php:116 src/Core/ACL.php:302
+#: view/theme/vier/config.php:118 src/Core/ACL.php:303
msgid "don't show"
msgstr ""
-#: view/theme/vier/config.php:116 src/Core/ACL.php:301
+#: view/theme/vier/config.php:118 src/Core/ACL.php:302
msgid "show"
msgstr ""
-#: view/theme/vier/config.php:122
+#: view/theme/vier/config.php:124
msgid "Set style"
msgstr ""
-#: view/theme/vier/config.php:123
+#: view/theme/vier/config.php:125
msgid "Community Pages"
msgstr ""
-#: view/theme/vier/config.php:124 view/theme/vier/theme.php:151
+#: view/theme/vier/config.php:126 view/theme/vier/theme.php:128
msgid "Community Profiles"
msgstr ""
-#: view/theme/vier/config.php:125
+#: view/theme/vier/config.php:127
msgid "Help or @NewHere ?"
msgstr ""
-#: view/theme/vier/config.php:126 view/theme/vier/theme.php:373
+#: view/theme/vier/config.php:128 view/theme/vier/theme.php:350
msgid "Connect Services"
msgstr ""
-#: view/theme/vier/config.php:127
+#: view/theme/vier/config.php:129
msgid "Find Friends"
msgstr ""
-#: view/theme/vier/config.php:128 view/theme/vier/theme.php:181
+#: view/theme/vier/config.php:130 view/theme/vier/theme.php:158
msgid "Last users"
msgstr ""
-#: view/theme/vier/theme.php:199 src/Content/Widget.php:64
+#: view/theme/vier/theme.php:176 src/Content/Widget.php:65
msgid "Find People"
msgstr ""
-#: view/theme/vier/theme.php:200 src/Content/Widget.php:65
+#: view/theme/vier/theme.php:177 src/Content/Widget.php:66
msgid "Enter name or interest"
msgstr ""
-#: view/theme/vier/theme.php:202 src/Content/Widget.php:67
+#: view/theme/vier/theme.php:179 src/Content/Widget.php:68
msgid "Examples: Robert Morgenstein, Fishing"
msgstr ""
-#: view/theme/vier/theme.php:203 src/Content/Widget.php:68
-#: src/Module/Directory.php:86 src/Module/Contact.php:795
+#: view/theme/vier/theme.php:180 src/Content/Widget.php:69
+#: src/Module/Contact.php:816 src/Module/Directory.php:84
msgid "Find"
msgstr ""
-#: view/theme/vier/theme.php:205 src/Content/Widget.php:70
+#: view/theme/vier/theme.php:182 src/Content/Widget.php:71
msgid "Similar Interests"
msgstr ""
-#: view/theme/vier/theme.php:206 src/Content/Widget.php:71
+#: view/theme/vier/theme.php:183 src/Content/Widget.php:72
msgid "Random Profile"
msgstr ""
-#: view/theme/vier/theme.php:207 src/Content/Widget.php:72
+#: view/theme/vier/theme.php:184 src/Content/Widget.php:73
msgid "Invite Friends"
msgstr ""
-#: view/theme/vier/theme.php:208 src/Content/Widget.php:73
-#: src/Module/Directory.php:78
+#: view/theme/vier/theme.php:185 src/Content/Widget.php:74
+#: src/Module/Directory.php:76
msgid "Global Directory"
msgstr ""
-#: view/theme/vier/theme.php:210 src/Content/Widget.php:75
+#: view/theme/vier/theme.php:187 src/Content/Widget.php:76
msgid "Local Directory"
msgstr ""
-#: view/theme/vier/theme.php:250 src/Content/Text/HTML.php:907
-#: src/Content/Nav.php:209 src/Content/ForumManager.php:130
+#: view/theme/vier/theme.php:227 src/Content/Text/HTML.php:926
+#: src/Content/ForumManager.php:130 src/Content/Nav.php:209
msgid "Forums"
msgstr ""
-#: view/theme/vier/theme.php:252 src/Content/ForumManager.php:132
+#: view/theme/vier/theme.php:229 src/Content/ForumManager.php:132
msgid "External link to forum"
msgstr ""
-#: view/theme/vier/theme.php:255 src/Content/Widget.php:407
-#: src/Content/Widget.php:507 src/Content/ForumManager.php:135
+#: view/theme/vier/theme.php:232 src/Content/ForumManager.php:135
+#: src/Content/Widget.php:405 src/Content/Widget.php:505
msgid "show more"
msgstr ""
-#: view/theme/vier/theme.php:288
+#: view/theme/vier/theme.php:265
msgid "Quick Start"
msgstr ""
-#: view/theme/vier/theme.php:294 src/Content/Nav.php:192 src/Module/Help.php:50
+#: view/theme/vier/theme.php:271 src/Content/Nav.php:192 src/Module/Help.php:50
#: src/Module/Settings/TwoFactor/AppSpecific.php:99
-#: src/Module/Settings/TwoFactor/Index.php:90
#: src/Module/Settings/TwoFactor/Recovery.php:77
+#: src/Module/Settings/TwoFactor/Index.php:90
#: src/Module/Settings/TwoFactor/Verify.php:117
msgid "Help"
msgstr ""
-#: src/Core/L10n/L10n.php:370 src/Model/Event.php:397
+#: src/Core/L10n/L10n.php:404 src/Model/Event.php:398
msgid "Tuesday"
msgstr ""
-#: src/Core/L10n/L10n.php:370 src/Model/Event.php:398
+#: src/Core/L10n/L10n.php:404 src/Model/Event.php:399
msgid "Wednesday"
msgstr ""
-#: src/Core/L10n/L10n.php:370 src/Model/Event.php:399
+#: src/Core/L10n/L10n.php:404 src/Model/Event.php:400
msgid "Thursday"
msgstr ""
-#: src/Core/L10n/L10n.php:370 src/Model/Event.php:400
+#: src/Core/L10n/L10n.php:404 src/Model/Event.php:401
msgid "Friday"
msgstr ""
-#: src/Core/L10n/L10n.php:370 src/Model/Event.php:401
+#: src/Core/L10n/L10n.php:404 src/Model/Event.php:402
msgid "Saturday"
msgstr ""
-#: src/Core/L10n/L10n.php:374 src/Model/Event.php:416
+#: src/Core/L10n/L10n.php:408 src/Model/Event.php:417
msgid "January"
msgstr ""
-#: src/Core/L10n/L10n.php:374 src/Model/Event.php:417
+#: src/Core/L10n/L10n.php:408 src/Model/Event.php:418
msgid "February"
msgstr ""
-#: src/Core/L10n/L10n.php:374 src/Model/Event.php:418
+#: src/Core/L10n/L10n.php:408 src/Model/Event.php:419
msgid "March"
msgstr ""
-#: src/Core/L10n/L10n.php:374 src/Model/Event.php:419
+#: src/Core/L10n/L10n.php:408 src/Model/Event.php:420
msgid "April"
msgstr ""
-#: src/Core/L10n/L10n.php:374 src/Core/L10n/L10n.php:394
-#: src/Model/Event.php:407
+#: src/Core/L10n/L10n.php:408 src/Core/L10n/L10n.php:428
+#: src/Model/Event.php:408
msgid "May"
msgstr ""
-#: src/Core/L10n/L10n.php:374 src/Model/Event.php:420
+#: src/Core/L10n/L10n.php:408 src/Model/Event.php:421
msgid "June"
msgstr ""
-#: src/Core/L10n/L10n.php:374 src/Model/Event.php:421
+#: src/Core/L10n/L10n.php:408 src/Model/Event.php:422
msgid "July"
msgstr ""
-#: src/Core/L10n/L10n.php:374 src/Model/Event.php:422
+#: src/Core/L10n/L10n.php:408 src/Model/Event.php:423
msgid "August"
msgstr ""
-#: src/Core/L10n/L10n.php:374 src/Model/Event.php:423
+#: src/Core/L10n/L10n.php:408 src/Model/Event.php:424
msgid "September"
msgstr ""
-#: src/Core/L10n/L10n.php:374 src/Model/Event.php:424
+#: src/Core/L10n/L10n.php:408 src/Model/Event.php:425
msgid "October"
msgstr ""
-#: src/Core/L10n/L10n.php:374 src/Model/Event.php:425
+#: src/Core/L10n/L10n.php:408 src/Model/Event.php:426
msgid "November"
msgstr ""
-#: src/Core/L10n/L10n.php:374 src/Model/Event.php:426
+#: src/Core/L10n/L10n.php:408 src/Model/Event.php:427
msgid "December"
msgstr ""
-#: src/Core/L10n/L10n.php:390 src/Model/Event.php:388
+#: src/Core/L10n/L10n.php:424 src/Model/Event.php:389
msgid "Mon"
msgstr ""
-#: src/Core/L10n/L10n.php:390 src/Model/Event.php:389
+#: src/Core/L10n/L10n.php:424 src/Model/Event.php:390
msgid "Tue"
msgstr ""
-#: src/Core/L10n/L10n.php:390 src/Model/Event.php:390
+#: src/Core/L10n/L10n.php:424 src/Model/Event.php:391
msgid "Wed"
msgstr ""
-#: src/Core/L10n/L10n.php:390 src/Model/Event.php:391
+#: src/Core/L10n/L10n.php:424 src/Model/Event.php:392
msgid "Thu"
msgstr ""
-#: src/Core/L10n/L10n.php:390 src/Model/Event.php:392
+#: src/Core/L10n/L10n.php:424 src/Model/Event.php:393
msgid "Fri"
msgstr ""
-#: src/Core/L10n/L10n.php:390 src/Model/Event.php:393
+#: src/Core/L10n/L10n.php:424 src/Model/Event.php:394
msgid "Sat"
msgstr ""
-#: src/Core/L10n/L10n.php:390 src/Model/Event.php:387
+#: src/Core/L10n/L10n.php:424 src/Model/Event.php:388
msgid "Sun"
msgstr ""
-#: src/Core/L10n/L10n.php:394 src/Model/Event.php:403
+#: src/Core/L10n/L10n.php:428 src/Model/Event.php:404
msgid "Jan"
msgstr ""
-#: src/Core/L10n/L10n.php:394 src/Model/Event.php:404
+#: src/Core/L10n/L10n.php:428 src/Model/Event.php:405
msgid "Feb"
msgstr ""
-#: src/Core/L10n/L10n.php:394 src/Model/Event.php:405
+#: src/Core/L10n/L10n.php:428 src/Model/Event.php:406
msgid "Mar"
msgstr ""
-#: src/Core/L10n/L10n.php:394 src/Model/Event.php:406
+#: src/Core/L10n/L10n.php:428 src/Model/Event.php:407
msgid "Apr"
msgstr ""
-#: src/Core/L10n/L10n.php:394 src/Model/Event.php:408
+#: src/Core/L10n/L10n.php:428 src/Model/Event.php:409
msgid "Jun"
msgstr ""
-#: src/Core/L10n/L10n.php:394 src/Model/Event.php:409
+#: src/Core/L10n/L10n.php:428 src/Model/Event.php:410
msgid "Jul"
msgstr ""
-#: src/Core/L10n/L10n.php:394 src/Model/Event.php:410
+#: src/Core/L10n/L10n.php:428 src/Model/Event.php:411
msgid "Aug"
msgstr ""
-#: src/Core/L10n/L10n.php:394
+#: src/Core/L10n/L10n.php:428
msgid "Sep"
msgstr ""
-#: src/Core/L10n/L10n.php:394 src/Model/Event.php:412
+#: src/Core/L10n/L10n.php:428 src/Model/Event.php:413
msgid "Oct"
msgstr ""
-#: src/Core/L10n/L10n.php:394 src/Model/Event.php:413
+#: src/Core/L10n/L10n.php:428 src/Model/Event.php:414
msgid "Nov"
msgstr ""
-#: src/Core/L10n/L10n.php:394 src/Model/Event.php:414
+#: src/Core/L10n/L10n.php:428 src/Model/Event.php:415
msgid "Dec"
msgstr ""
-#: src/Core/L10n/L10n.php:413
+#: src/Core/L10n/L10n.php:447
msgid "poke"
msgstr ""
-#: src/Core/L10n/L10n.php:413
+#: src/Core/L10n/L10n.php:447
msgid "poked"
msgstr ""
-#: src/Core/L10n/L10n.php:414
+#: src/Core/L10n/L10n.php:448
msgid "ping"
msgstr ""
-#: src/Core/L10n/L10n.php:414
+#: src/Core/L10n/L10n.php:448
msgid "pinged"
msgstr ""
-#: src/Core/L10n/L10n.php:415
+#: src/Core/L10n/L10n.php:449
msgid "prod"
msgstr ""
-#: src/Core/L10n/L10n.php:415
+#: src/Core/L10n/L10n.php:449
msgid "prodded"
msgstr ""
-#: src/Core/L10n/L10n.php:416
+#: src/Core/L10n/L10n.php:450
msgid "slap"
msgstr ""
-#: src/Core/L10n/L10n.php:416
+#: src/Core/L10n/L10n.php:450
msgid "slapped"
msgstr ""
-#: src/Core/L10n/L10n.php:417
+#: src/Core/L10n/L10n.php:451
msgid "finger"
msgstr ""
-#: src/Core/L10n/L10n.php:417
+#: src/Core/L10n/L10n.php:451
msgid "fingered"
msgstr ""
-#: src/Core/L10n/L10n.php:418
+#: src/Core/L10n/L10n.php:452
msgid "rebuff"
msgstr ""
-#: src/Core/L10n/L10n.php:418
+#: src/Core/L10n/L10n.php:452
msgid "rebuffed"
msgstr ""
msgid "Done. You can now login with your username and password"
msgstr ""
+#: src/Core/ACL.php:289 src/Module/Item/Compose.php:143
+msgid "Post to Email"
+msgstr ""
+
+#: src/Core/ACL.php:301
+msgid "Visible to everybody"
+msgstr ""
+
+#: src/Core/ACL.php:312
+msgid "Connectors"
+msgstr ""
+
+#: src/Core/ACL.php:314
+msgid "Hide your profile details from unknown viewers?"
+msgstr ""
+
+#: src/Core/ACL.php:314
+#, php-format
+msgid "Connectors disabled, since \"%s\" is enabled."
+msgstr ""
+
+#: src/Core/ACL.php:316
+msgid "Close"
+msgstr ""
+
#: src/Core/Installer.php:162
msgid ""
"The database configuration file \"config/local.config.php\" could not be "
msgid "ImageMagick PHP extension is installed"
msgstr ""
-#: src/Core/Installer.php:582 tests/src/Core/InstallerTest.php:372
-#: tests/src/Core/InstallerTest.php:400
+#: src/Core/Installer.php:582 tests/src/Core/InstallerTest.php:366
+#: tests/src/Core/InstallerTest.php:389
msgid "ImageMagick supports GIF"
msgstr ""
msgid "Could not connect to database."
msgstr ""
-#: src/Core/NotificationsManager.php:144
-msgid "System"
-msgstr ""
-
-#: src/Core/NotificationsManager.php:165 src/Content/Nav.php:182
-#: src/Content/Nav.php:244
-msgid "Home"
-msgstr ""
-
-#: src/Core/NotificationsManager.php:172 src/Content/Nav.php:248
-msgid "Introductions"
-msgstr ""
-
-#: src/Core/NotificationsManager.php:234 src/Core/NotificationsManager.php:246
-#, php-format
-msgid "%s commented on %s's post"
-msgstr ""
-
-#: src/Core/NotificationsManager.php:245
-#, php-format
-msgid "%s created a new post"
-msgstr ""
-
-#: src/Core/NotificationsManager.php:259
-#, php-format
-msgid "%s liked %s's post"
-msgstr ""
-
-#: src/Core/NotificationsManager.php:272
-#, php-format
-msgid "%s disliked %s's post"
-msgstr ""
-
-#: src/Core/NotificationsManager.php:285
-#, php-format
-msgid "%s is attending %s's event"
-msgstr ""
-
-#: src/Core/NotificationsManager.php:298
-#, php-format
-msgid "%s is not attending %s's event"
-msgstr ""
-
-#: src/Core/NotificationsManager.php:311
-#, php-format
-msgid "%s may attend %s's event"
-msgstr ""
-
-#: src/Core/NotificationsManager.php:344
-#, php-format
-msgid "%s is now friends with %s"
-msgstr ""
-
-#: src/Core/NotificationsManager.php:629
-msgid "Friend Suggestion"
-msgstr ""
-
-#: src/Core/NotificationsManager.php:663
-msgid "Friend/Connect Request"
-msgstr ""
-
-#: src/Core/NotificationsManager.php:663
-msgid "New Follower"
-msgstr ""
-
-#: src/Core/Session.php:186
+#: src/Core/Session.php:199
#, php-format
msgid "Welcome %s"
msgstr ""
-#: src/Core/Session.php:187
+#: src/Core/Session.php:200
msgid "Please upload a profile photo."
msgstr ""
-#: src/Core/Session.php:190
+#: src/Core/Session.php:203
#, php-format
msgid "Welcome back %s"
msgstr ""
-#: src/Core/ACL.php:288 src/Module/Item/Compose.php:139
-msgid "Post to Email"
-msgstr ""
-
-#: src/Core/ACL.php:300
-msgid "Visible to everybody"
-msgstr ""
-
-#: src/Core/ACL.php:311
-msgid "Connectors"
-msgstr ""
-
-#: src/Core/ACL.php:313
-msgid "Hide your profile details from unknown viewers?"
-msgstr ""
-
-#: src/Core/ACL.php:313
-#, php-format
-msgid "Connectors disabled, since \"%s\" is enabled."
-msgstr ""
-
-#: src/Core/ACL.php:315
-msgid "Close"
-msgstr ""
-
-#: src/Util/Temporal.php:147 src/Model/Profile.php:784
+#: src/Util/Temporal.php:146 src/Model/Profile.php:780
msgid "Birthday:"
msgstr ""
-#: src/Util/Temporal.php:151
+#: src/Util/Temporal.php:150
msgid "YYYY-MM-DD or MM-DD"
msgstr ""
-#: src/Util/Temporal.php:298
+#: src/Util/Temporal.php:297
msgid "never"
msgstr ""
-#: src/Util/Temporal.php:305
+#: src/Util/Temporal.php:304
msgid "less than a second ago"
msgstr ""
-#: src/Util/Temporal.php:313
+#: src/Util/Temporal.php:312
msgid "year"
msgstr ""
-#: src/Util/Temporal.php:313
+#: src/Util/Temporal.php:312
msgid "years"
msgstr ""
-#: src/Util/Temporal.php:314
+#: src/Util/Temporal.php:313
msgid "months"
msgstr ""
-#: src/Util/Temporal.php:315
+#: src/Util/Temporal.php:314
msgid "weeks"
msgstr ""
-#: src/Util/Temporal.php:316
+#: src/Util/Temporal.php:315
msgid "days"
msgstr ""
-#: src/Util/Temporal.php:317
+#: src/Util/Temporal.php:316
msgid "hour"
msgstr ""
-#: src/Util/Temporal.php:317
+#: src/Util/Temporal.php:316
msgid "hours"
msgstr ""
-#: src/Util/Temporal.php:318
+#: src/Util/Temporal.php:317
msgid "minute"
msgstr ""
-#: src/Util/Temporal.php:318
+#: src/Util/Temporal.php:317
msgid "minutes"
msgstr ""
-#: src/Util/Temporal.php:319
+#: src/Util/Temporal.php:318
msgid "second"
msgstr ""
-#: src/Util/Temporal.php:319
+#: src/Util/Temporal.php:318
msgid "seconds"
msgstr ""
-#: src/Util/Temporal.php:329
+#: src/Util/Temporal.php:328
#, php-format
msgid "in %1$d %2$s"
msgstr ""
-#: src/Util/Temporal.php:332
+#: src/Util/Temporal.php:331
#, php-format
msgid "%1$d %2$s ago"
msgstr ""
-#: src/Content/Text/HTML.php:793
-msgid "Loading more entries..."
-msgstr ""
-
-#: src/Content/Text/HTML.php:794
-msgid "The end"
-msgstr ""
-
-#: src/Content/Text/HTML.php:887 src/Model/Profile.php:544
-#: src/Module/Contact.php:297
-msgid "Follow"
-msgstr ""
-
-#: src/Content/Text/HTML.php:896 src/Content/Nav.php:79
-msgid "@name, !forum, #tags, content"
-msgstr ""
-
-#: src/Content/Text/HTML.php:902 src/Content/Nav.php:203
-msgid "Full Text"
-msgstr ""
-
-#: src/Content/Text/HTML.php:903 src/Content/Widget/TagCloud.php:54
-#: src/Content/Nav.php:204
-msgid "Tags"
-msgstr ""
-
-#: src/Content/Text/HTML.php:944 src/Content/Text/BBCode.php:1478
-msgid "Click to open/close"
-msgstr ""
-
-#: src/Content/Text/BBCode.php:465
+#: src/Content/Text/BBCode.php:467
msgid "view full size"
msgstr ""
-#: src/Content/Text/BBCode.php:899 src/Content/Text/BBCode.php:1560
-#: src/Content/Text/BBCode.php:1561
+#: src/Content/Text/BBCode.php:913 src/Content/Text/BBCode.php:1579
+#: src/Content/Text/BBCode.php:1580
msgid "Image/photo"
msgstr ""
-#: src/Content/Text/BBCode.php:1017
+#: src/Content/Text/BBCode.php:1031
#, php-format
msgid "<a href=\"%1$s\" target=\"_blank\">%2$s</a> %3$s"
msgstr ""
-#: src/Content/Text/BBCode.php:1509
+#: src/Content/Text/BBCode.php:1497 src/Content/Text/HTML.php:963
+msgid "Click to open/close"
+msgstr ""
+
+#: src/Content/Text/BBCode.php:1528
msgid "$1 wrote:"
msgstr ""
-#: src/Content/Text/BBCode.php:1563 src/Content/Text/BBCode.php:1564
+#: src/Content/Text/BBCode.php:1582 src/Content/Text/BBCode.php:1583
msgid "Encrypted content"
msgstr ""
-#: src/Content/Text/BBCode.php:1788
+#: src/Content/Text/BBCode.php:1805
msgid "Invalid source protocol"
msgstr ""
-#: src/Content/Text/BBCode.php:1803
+#: src/Content/Text/BBCode.php:1820
msgid "Invalid link protocol"
msgstr ""
-#: src/Content/Widget/CalendarExport.php:64
-msgid "Export"
+#: src/Content/Text/HTML.php:811
+msgid "Loading more entries..."
msgstr ""
-#: src/Content/Widget/CalendarExport.php:65
-msgid "Export calendar as ical"
+#: src/Content/Text/HTML.php:812
+msgid "The end"
msgstr ""
-#: src/Content/Widget/CalendarExport.php:66
-msgid "Export calendar as csv"
+#: src/Content/Text/HTML.php:905 src/Model/Profile.php:540
+#: src/Module/Contact.php:318
+msgid "Follow"
msgstr ""
-#: src/Content/Widget/ContactBlock.php:58
-msgid "No contacts"
+#: src/Content/Text/HTML.php:911 src/Content/Nav.php:200
+#: src/Module/Search/Index.php:80
+msgid "Search"
msgstr ""
-#: src/Content/Widget/ContactBlock.php:90
-#, php-format
-msgid "%d Contact"
-msgid_plural "%d Contacts"
-msgstr[0] ""
-msgstr[1] ""
+#: src/Content/Text/HTML.php:913 src/Content/Nav.php:79
+msgid "@name, !forum, #tags, content"
+msgstr ""
-#: src/Content/Widget/ContactBlock.php:109
-msgid "View Contacts"
+#: src/Content/Text/HTML.php:920 src/Content/Nav.php:203
+msgid "Full Text"
+msgstr ""
+
+#: src/Content/Text/HTML.php:921 src/Content/Widget/TagCloud.php:54
+#: src/Content/Nav.php:204
+msgid "Tags"
msgstr ""
#: src/Content/Widget/TrendingTags.php:34
msgid "More Trending Tags"
msgstr ""
-#: src/Content/Pager.php:153
-msgid "newer"
+#: src/Content/Widget/CalendarExport.php:64
+msgid "Export"
+msgstr ""
+
+#: src/Content/Widget/CalendarExport.php:65
+msgid "Export calendar as ical"
+msgstr ""
+
+#: src/Content/Widget/CalendarExport.php:66
+msgid "Export calendar as csv"
+msgstr ""
+
+#: src/Content/Widget/ContactBlock.php:58
+msgid "No contacts"
msgstr ""
-#: src/Content/Pager.php:158
-msgid "older"
+#: src/Content/Widget/ContactBlock.php:90
+#, php-format
+msgid "%d Contact"
+msgid_plural "%d Contacts"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/Content/Widget/ContactBlock.php:109
+msgid "View Contacts"
msgstr ""
-#: src/Content/Pager.php:203
-msgid "prev"
+#: src/Content/Widget/SavedSearches.php:29
+msgid "Remove term"
msgstr ""
-#: src/Content/Pager.php:263
-msgid "last"
+#: src/Content/Widget/SavedSearches.php:37
+msgid "Saved Searches"
msgstr ""
#: src/Content/Feature.php:82
msgid "Network Sidebar"
msgstr ""
-#: src/Content/Feature.php:100 src/Content/Widget.php:501
+#: src/Content/Feature.php:100 src/Content/Widget.php:499
msgid "Archives"
msgstr ""
msgid "Display membership date in profile"
msgstr ""
-#: src/Content/Nav.php:74
-msgid "Nothing new here"
-msgstr ""
-
-#: src/Content/Nav.php:78
-msgid "Clear notifications"
-msgstr ""
-
-#: src/Content/Nav.php:153 src/Module/Login.php:315
-msgid "Logout"
-msgstr ""
-
-#: src/Content/Nav.php:153
-msgid "End this session"
-msgstr ""
-
-#: src/Content/Nav.php:155 src/Module/Login.php:316
-#: src/Module/Bookmarklet.php:25
-msgid "Login"
-msgstr ""
-
-#: src/Content/Nav.php:155
-msgid "Sign in"
-msgstr ""
-
-#: src/Content/Nav.php:165
-msgid "Personal notes"
-msgstr ""
-
-#: src/Content/Nav.php:165
-msgid "Your personal notes"
-msgstr ""
-
-#: src/Content/Nav.php:182
-msgid "Home Page"
-msgstr ""
-
-#: src/Content/Nav.php:186 src/Module/Login.php:287 src/Module/Register.php:136
-msgid "Register"
-msgstr ""
-
-#: src/Content/Nav.php:186
-msgid "Create an account"
-msgstr ""
-
-#: src/Content/Nav.php:192
-msgid "Help and documentation"
-msgstr ""
-
-#: src/Content/Nav.php:196
-msgid "Apps"
-msgstr ""
-
-#: src/Content/Nav.php:196
-msgid "Addon applications, utilities, games"
-msgstr ""
-
-#: src/Content/Nav.php:200
-msgid "Search site content"
-msgstr ""
-
-#: src/Content/Nav.php:224
-msgid "Community"
-msgstr ""
-
-#: src/Content/Nav.php:224
-msgid "Conversations on this and other servers"
-msgstr ""
-
-#: src/Content/Nav.php:231
-msgid "Directory"
-msgstr ""
-
-#: src/Content/Nav.php:231
-msgid "People directory"
-msgstr ""
-
-#: src/Content/Nav.php:233 src/Module/BaseAdminModule.php:75
-msgid "Information"
-msgstr ""
-
-#: src/Content/Nav.php:233
-msgid "Information about this friendica instance"
-msgstr ""
-
-#: src/Content/Nav.php:236 src/Module/Tos.php:73 src/Module/Admin/Tos.php:43
-#: src/Module/BaseAdminModule.php:85 src/Module/Register.php:144
-msgid "Terms of Service"
-msgstr ""
-
-#: src/Content/Nav.php:236
-msgid "Terms of Service of this Friendica instance"
-msgstr ""
-
-#: src/Content/Nav.php:242
-msgid "Network Reset"
-msgstr ""
-
-#: src/Content/Nav.php:242
-msgid "Load Network page with no filters"
-msgstr ""
-
-#: src/Content/Nav.php:248
-msgid "Friend Requests"
-msgstr ""
-
-#: src/Content/Nav.php:250
-msgid "See all notifications"
-msgstr ""
-
-#: src/Content/Nav.php:251
-msgid "Mark all system notifications seen"
-msgstr ""
-
-#: src/Content/Nav.php:255
-msgid "Inbox"
-msgstr ""
-
-#: src/Content/Nav.php:256
-msgid "Outbox"
-msgstr ""
-
-#: src/Content/Nav.php:260
-msgid "Manage"
-msgstr ""
-
-#: src/Content/Nav.php:260
-msgid "Manage other pages"
-msgstr ""
-
-#: src/Content/Nav.php:268
-msgid "Manage/Edit Profiles"
-msgstr ""
-
-#: src/Content/Nav.php:276 src/Module/BaseAdminModule.php:114
-msgid "Admin"
-msgstr ""
-
-#: src/Content/Nav.php:276
-msgid "Site setup and configuration"
-msgstr ""
-
-#: src/Content/Nav.php:279
-msgid "Navigation"
-msgstr ""
-
-#: src/Content/Nav.php:279
-msgid "Site map"
-msgstr ""
-
#: src/Content/OEmbed.php:254
msgid "Embedding disabled"
msgstr ""
msgid "Embedded content"
msgstr ""
-#: src/Content/Widget.php:38
-msgid "Add New Contact"
-msgstr ""
-
-#: src/Content/Widget.php:39
-msgid "Enter address or web location"
-msgstr ""
-
-#: src/Content/Widget.php:40
-msgid "Example: bob@example.com, http://example.com/barbara"
-msgstr ""
-
-#: src/Content/Widget.php:58
-#, php-format
-msgid "%d invitation available"
-msgid_plural "%d invitations available"
-msgstr[0] ""
-msgstr[1] ""
-
-#: src/Content/Widget.php:193 src/Module/Profile/Contacts.php:127
-#: src/Module/Contact.php:772
-msgid "Following"
-msgstr ""
-
-#: src/Content/Widget.php:194 src/Module/Profile/Contacts.php:128
-#: src/Module/Contact.php:773
-msgid "Mutual friends"
-msgstr ""
-
-#: src/Content/Widget.php:199
-msgid "Relationships"
-msgstr ""
-
-#: src/Content/Widget.php:201 src/Module/Group.php:287
-#: src/Module/Contact.php:660
-msgid "All Contacts"
-msgstr ""
-
-#: src/Content/Widget.php:244
-msgid "Protocols"
-msgstr ""
-
-#: src/Content/Widget.php:246
-msgid "All Protocols"
-msgstr ""
-
-#: src/Content/Widget.php:279
-msgid "Saved Folders"
-msgstr ""
-
-#: src/Content/Widget.php:281 src/Content/Widget.php:320
-msgid "Everything"
-msgstr ""
-
-#: src/Content/Widget.php:318
-msgid "Categories"
-msgstr ""
-
-#: src/Content/Widget.php:402
-#, php-format
-msgid "%d contact in common"
-msgid_plural "%d contacts in common"
-msgstr[0] ""
-msgstr[1] ""
-
#: src/Content/ContactSelector.php:58
msgid "Frequently"
msgstr ""
msgid "Sex Addict"
msgstr ""
-#: src/Content/ContactSelector.php:316 src/Model/User.php:762
+#: src/Content/ContactSelector.php:316 src/Model/User.php:807
msgid "Friends"
msgstr ""
msgid "Ask me"
msgstr ""
-#: src/Database/DBStructure.php:50
-msgid "There are no tables on MyISAM."
+#: src/Content/Nav.php:74
+msgid "Nothing new here"
msgstr ""
-#: src/Database/DBStructure.php:74
-#, php-format
-msgid ""
-"\n"
-"Error %d occurred during database update:\n"
-"%s\n"
+#: src/Content/Nav.php:78
+msgid "Clear notifications"
msgstr ""
-#: src/Database/DBStructure.php:77
-msgid "Errors encountered performing database changes: "
+#: src/Content/Nav.php:153 src/Module/Login.php:352
+msgid "Logout"
msgstr ""
-#: src/Database/DBStructure.php:266
-#, php-format
-msgid "%s: Database update"
+#: src/Content/Nav.php:153
+msgid "End this session"
msgstr ""
-#: src/Database/DBStructure.php:527
-#, php-format
-msgid "%s: updating %s table."
+#: src/Content/Nav.php:155 src/Module/Bookmarklet.php:25
+#: src/Module/Login.php:353
+msgid "Login"
msgstr ""
-#: src/Model/Storage/Filesystem.php:63
-#, php-format
-msgid ""
-"Filesystem storage failed to create \"%s\". Check you write permissions."
+#: src/Content/Nav.php:155
+msgid "Sign in"
msgstr ""
-#: src/Model/Storage/Filesystem.php:105
-#, php-format
-msgid ""
-"Filesystem storage failed to save data to \"%s\". Check your write "
-"permissions"
+#: src/Content/Nav.php:165
+msgid "Personal notes"
msgstr ""
-#: src/Model/Storage/Filesystem.php:126
-msgid "Storage base path"
+#: src/Content/Nav.php:165
+msgid "Your personal notes"
msgstr ""
-#: src/Model/Storage/Filesystem.php:128
-msgid ""
-"Folder where uploaded files are saved. For maximum security, This should be "
-"a path outside web server folder tree"
+#: src/Content/Nav.php:182 src/Content/Nav.php:244
+msgid "Home"
+msgstr ""
+
+#: src/Content/Nav.php:182
+msgid "Home Page"
+msgstr ""
+
+#: src/Content/Nav.php:186 src/Module/Login.php:313 src/Module/Register.php:130
+msgid "Register"
msgstr ""
-#: src/Model/Storage/Filesystem.php:138
-msgid "Enter a valid existing folder"
+#: src/Content/Nav.php:186
+msgid "Create an account"
msgstr ""
-#: src/Model/Storage/Database.php:36
-#, php-format
-msgid "Database storage failed to update %s"
+#: src/Content/Nav.php:192
+msgid "Help and documentation"
msgstr ""
-#: src/Model/Storage/Database.php:43
-msgid "Database storage failed to insert data"
+#: src/Content/Nav.php:196
+msgid "Apps"
msgstr ""
-#: src/Model/Event.php:34 src/Model/Event.php:847
-#: src/Module/Debug/Localtime.php:17
-msgid "l F d, Y \\@ g:i A"
+#: src/Content/Nav.php:196
+msgid "Addon applications, utilities, games"
msgstr ""
-#: src/Model/Event.php:61 src/Model/Event.php:78 src/Model/Event.php:435
-#: src/Model/Event.php:915
-msgid "Starts:"
+#: src/Content/Nav.php:200
+msgid "Search site content"
msgstr ""
-#: src/Model/Event.php:64 src/Model/Event.php:84 src/Model/Event.php:436
-#: src/Model/Event.php:919
-msgid "Finishes:"
+#: src/Content/Nav.php:224
+msgid "Community"
msgstr ""
-#: src/Model/Event.php:385
-msgid "all-day"
+#: src/Content/Nav.php:224
+msgid "Conversations on this and other servers"
msgstr ""
-#: src/Model/Event.php:411
-msgid "Sept"
+#: src/Content/Nav.php:231
+msgid "Directory"
msgstr ""
-#: src/Model/Event.php:433
-msgid "No events to display"
+#: src/Content/Nav.php:231
+msgid "People directory"
msgstr ""
-#: src/Model/Event.php:561
-msgid "l, F j"
+#: src/Content/Nav.php:233 src/Module/BaseAdminModule.php:75
+msgid "Information"
msgstr ""
-#: src/Model/Event.php:592
-msgid "Edit event"
+#: src/Content/Nav.php:233
+msgid "Information about this friendica instance"
msgstr ""
-#: src/Model/Event.php:593
-msgid "Duplicate event"
+#: src/Content/Nav.php:236 src/Module/Admin/Tos.php:43
+#: src/Module/BaseAdminModule.php:85 src/Module/Register.php:138
+#: src/Module/Tos.php:73
+msgid "Terms of Service"
msgstr ""
-#: src/Model/Event.php:594
-msgid "Delete event"
+#: src/Content/Nav.php:236
+msgid "Terms of Service of this Friendica instance"
msgstr ""
-#: src/Model/Event.php:626 src/Model/Item.php:3547 src/Model/Item.php:3554
-msgid "link to source"
+#: src/Content/Nav.php:242
+msgid "Network Reset"
msgstr ""
-#: src/Model/Event.php:848
-msgid "D g:i A"
+#: src/Content/Nav.php:242
+msgid "Load Network page with no filters"
msgstr ""
-#: src/Model/Event.php:849
-msgid "g:i A"
+#: src/Content/Nav.php:248
+msgid "Introductions"
msgstr ""
-#: src/Model/Event.php:934 src/Model/Event.php:936
-msgid "Show map"
+#: src/Content/Nav.php:248
+msgid "Friend Requests"
msgstr ""
-#: src/Model/Event.php:935
-msgid "Hide map"
+#: src/Content/Nav.php:250
+msgid "See all notifications"
msgstr ""
-#: src/Model/Event.php:1027
-#, php-format
-msgid "%s's birthday"
+#: src/Content/Nav.php:251
+msgid "Mark all system notifications seen"
msgstr ""
-#: src/Model/Event.php:1028
-#, php-format
-msgid "Happy Birthday %s"
+#: src/Content/Nav.php:255
+msgid "Inbox"
msgstr ""
-#: src/Model/FileTag.php:265
-msgid "Item filed"
+#: src/Content/Nav.php:256
+msgid "Outbox"
msgstr ""
-#: src/Model/User.php:331
-msgid "Login failed"
+#: src/Content/Nav.php:260
+msgid "Delegation"
msgstr ""
-#: src/Model/User.php:362
-msgid "Not enough information to authenticate"
+#: src/Content/Nav.php:260
+msgid "Manage other pages"
msgstr ""
-#: src/Model/User.php:440
-msgid "Password can't be empty"
+#: src/Content/Nav.php:266
+msgid "Manage/Edit Profiles"
msgstr ""
-#: src/Model/User.php:459
-msgid "Empty passwords are not allowed."
+#: src/Content/Nav.php:274 src/Module/BaseAdminModule.php:114
+msgid "Admin"
msgstr ""
-#: src/Model/User.php:463
-msgid ""
-"The new password has been exposed in a public data dump, please choose "
-"another."
+#: src/Content/Nav.php:274
+msgid "Site setup and configuration"
msgstr ""
-#: src/Model/User.php:469
-msgid ""
-"The password can't contain accentuated letters, white spaces or colons (:)"
+#: src/Content/Nav.php:277
+msgid "Navigation"
msgstr ""
-#: src/Model/User.php:569
-msgid "Passwords do not match. Password unchanged."
+#: src/Content/Nav.php:277
+msgid "Site map"
msgstr ""
-#: src/Model/User.php:576
-msgid "An invitation is required."
+#: src/Content/Pager.php:153
+msgid "newer"
msgstr ""
-#: src/Model/User.php:580
-msgid "Invitation could not be verified."
+#: src/Content/Pager.php:158
+msgid "older"
msgstr ""
-#: src/Model/User.php:587
-msgid "Invalid OpenID url"
+#: src/Content/Pager.php:203
+msgid "prev"
msgstr ""
-#: src/Model/User.php:600 src/Module/Login.php:102
-msgid ""
-"We encountered a problem while logging in with the OpenID you provided. "
-"Please check the correct spelling of the ID."
+#: src/Content/Pager.php:263
+msgid "last"
msgstr ""
-#: src/Model/User.php:600 src/Module/Login.php:102
-msgid "The error message was:"
+#: src/Content/Widget.php:39
+msgid "Add New Contact"
msgstr ""
-#: src/Model/User.php:606
-msgid "Please enter the required information."
+#: src/Content/Widget.php:40
+msgid "Enter address or web location"
msgstr ""
-#: src/Model/User.php:620
-#, php-format
-msgid ""
-"system.username_min_length (%s) and system.username_max_length (%s) are "
-"excluding each other, swapping values."
+#: src/Content/Widget.php:41
+msgid "Example: bob@example.com, http://example.com/barbara"
msgstr ""
-#: src/Model/User.php:627
+#: src/Content/Widget.php:59
#, php-format
-msgid "Username should be at least %s character."
-msgid_plural "Username should be at least %s characters."
+msgid "%d invitation available"
+msgid_plural "%d invitations available"
msgstr[0] ""
msgstr[1] ""
-#: src/Model/User.php:631
-#, php-format
-msgid "Username should be at most %s character."
-msgid_plural "Username should be at most %s characters."
-msgstr[0] ""
-msgstr[1] ""
+#: src/Content/Widget.php:194 src/Module/Profile/Contacts.php:127
+#: src/Module/Contact.php:793
+msgid "Following"
+msgstr ""
-#: src/Model/User.php:639
-msgid "That doesn't appear to be your full (First Last) name."
+#: src/Content/Widget.php:195 src/Module/Profile/Contacts.php:128
+#: src/Module/Contact.php:794
+msgid "Mutual friends"
msgstr ""
-#: src/Model/User.php:644
-msgid "Your email domain is not among those allowed on this site."
+#: src/Content/Widget.php:200
+msgid "Relationships"
msgstr ""
-#: src/Model/User.php:648
-msgid "Not a valid email address."
+#: src/Content/Widget.php:202 src/Module/Group.php:287
+#: src/Module/Contact.php:681
+msgid "All Contacts"
msgstr ""
-#: src/Model/User.php:651
-msgid "The nickname was blocked from registration by the nodes admin."
+#: src/Content/Widget.php:245
+msgid "Protocols"
msgstr ""
-#: src/Model/User.php:655 src/Model/User.php:663
-msgid "Cannot use that email."
+#: src/Content/Widget.php:247
+msgid "All Protocols"
msgstr ""
-#: src/Model/User.php:670
-msgid "Your nickname can only contain a-z, 0-9 and _."
+#: src/Content/Widget.php:284
+msgid "Saved Folders"
msgstr ""
-#: src/Model/User.php:677 src/Model/User.php:734
-msgid "Nickname is already registered. Please choose another."
+#: src/Content/Widget.php:286 src/Content/Widget.php:325
+msgid "Everything"
msgstr ""
-#: src/Model/User.php:687
-msgid "SERIOUS ERROR: Generation of security keys failed."
+#: src/Content/Widget.php:323
+msgid "Categories"
msgstr ""
-#: src/Model/User.php:721 src/Model/User.php:725
-msgid "An error occurred during registration. Please try again."
+#: src/Content/Widget.php:400
+#, php-format
+msgid "%d contact in common"
+msgid_plural "%d contacts in common"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/Database/DBStructure.php:50
+msgid "There are no tables on MyISAM."
msgstr ""
-#: src/Model/User.php:750
-msgid "An error occurred creating your default profile. Please try again."
+#: src/Database/DBStructure.php:74
+#, php-format
+msgid ""
+"\n"
+"Error %d occurred during database update:\n"
+"%s\n"
msgstr ""
-#: src/Model/User.php:757
-msgid "An error occurred creating your self contact. Please try again."
+#: src/Database/DBStructure.php:77
+msgid "Errors encountered performing database changes: "
msgstr ""
-#: src/Model/User.php:766
-msgid ""
-"An error occurred creating your default contact group. Please try again."
+#: src/Database/DBStructure.php:266
+#, php-format
+msgid "%s: Database update"
msgstr ""
-#: src/Model/User.php:842
+#: src/Database/DBStructure.php:527
#, php-format
-msgid ""
-"\n"
-"\t\t\tDear %1$s,\n"
-"\t\t\t\tThank you for registering at %2$s. Your account is pending for "
-"approval by the administrator.\n"
-"\n"
-"\t\t\tYour login details are as follows:\n"
-"\n"
-"\t\t\tSite Location:\t%3$s\n"
-"\t\t\tLogin Name:\t\t%4$s\n"
-"\t\t\tPassword:\t\t%5$s\n"
-"\t\t"
+msgid "%s: updating %s table."
msgstr ""
-#: src/Model/User.php:859
+#: src/Model/Storage/Database.php:36
#, php-format
-msgid "Registration at %s"
+msgid "Database storage failed to update %s"
+msgstr ""
+
+#: src/Model/Storage/Database.php:43
+msgid "Database storage failed to insert data"
msgstr ""
-#: src/Model/User.php:878
+#: src/Model/Storage/Filesystem.php:63
#, php-format
msgid ""
-"\n"
-"\t\t\tDear %1$s,\n"
-"\t\t\t\tThank you for registering at %2$s. Your account has been created.\n"
-"\t\t"
+"Filesystem storage failed to create \"%s\". Check you write permissions."
msgstr ""
-#: src/Model/User.php:884
+#: src/Model/Storage/Filesystem.php:105
#, php-format
msgid ""
-"\n"
-"\t\t\tThe login details are as follows:\n"
-"\n"
-"\t\t\tSite Location:\t%3$s\n"
-"\t\t\tLogin Name:\t\t%1$s\n"
-"\t\t\tPassword:\t\t%5$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\tIf you ever want to delete your account, you can do so at %3$s/"
-"removeme\n"
-"\n"
-"\t\t\tThank you and welcome to %2$s."
+"Filesystem storage failed to save data to \"%s\". Check your write "
+"permissions"
msgstr ""
-#: src/Model/User.php:919 src/Module/Admin/Users.php:88
-#, php-format
-msgid "Registration details for %s"
+#: src/Model/Storage/Filesystem.php:126
+msgid "Storage base path"
+msgstr ""
+
+#: src/Model/Storage/Filesystem.php:128
+msgid ""
+"Folder where uploaded files are saved. For maximum security, This should be "
+"a path outside web server folder tree"
+msgstr ""
+
+#: src/Model/Storage/Filesystem.php:138
+msgid "Enter a valid existing folder"
+msgstr ""
+
+#: src/Model/FileTag.php:265
+msgid "Item filed"
+msgstr ""
+
+#: src/Model/Contact.php:1251 src/Model/Contact.php:1264
+msgid "UnFollow"
msgstr ""
-#: src/Model/Contact.php:1230
+#: src/Model/Contact.php:1260
msgid "Drop Contact"
msgstr ""
-#: src/Model/Contact.php:1783
+#: src/Model/Contact.php:1814
msgid "Organisation"
msgstr ""
-#: src/Model/Contact.php:1787
+#: src/Model/Contact.php:1818
msgid "News"
msgstr ""
-#: src/Model/Contact.php:1791
+#: src/Model/Contact.php:1822
msgid "Forum"
msgstr ""
-#: src/Model/Contact.php:2192
+#: src/Model/Contact.php:2222
msgid "Connect URL missing."
msgstr ""
-#: src/Model/Contact.php:2201
+#: src/Model/Contact.php:2231
msgid ""
"The contact could not be added. Please check the relevant network "
"credentials in your Settings -> Social Networks page."
msgstr ""
-#: src/Model/Contact.php:2242
+#: src/Model/Contact.php:2272
msgid ""
"This site is not configured to allow communications with other networks."
msgstr ""
-#: src/Model/Contact.php:2243 src/Model/Contact.php:2256
+#: src/Model/Contact.php:2273 src/Model/Contact.php:2286
msgid "No compatible communication protocols or feeds were discovered."
msgstr ""
-#: src/Model/Contact.php:2254
+#: src/Model/Contact.php:2284
msgid "The profile address specified does not provide adequate information."
msgstr ""
-#: src/Model/Contact.php:2259
+#: src/Model/Contact.php:2289
msgid "An author or name was not found."
msgstr ""
-#: src/Model/Contact.php:2262
+#: src/Model/Contact.php:2292
msgid "No browser URL could be matched to this address."
msgstr ""
-#: src/Model/Contact.php:2265
+#: src/Model/Contact.php:2295
msgid ""
"Unable to match @-style Identity Address with a known protocol or email "
"contact."
msgstr ""
-#: src/Model/Contact.php:2266
+#: src/Model/Contact.php:2296
msgid "Use mailto: in front of address to force email check."
msgstr ""
-#: src/Model/Contact.php:2272
+#: src/Model/Contact.php:2302
msgid ""
"The profile address specified belongs to a network which has been disabled "
"on this site."
msgstr ""
-#: src/Model/Contact.php:2277
+#: src/Model/Contact.php:2307
msgid ""
"Limited profile. This person will be unable to receive direct/personal "
"notifications from you."
msgstr ""
-#: src/Model/Contact.php:2332
+#: src/Model/Contact.php:2368
msgid "Unable to retrieve contact information."
msgstr ""
+#: src/Model/Event.php:35 src/Model/Event.php:848
+#: src/Module/Debug/Localtime.php:17
+msgid "l F d, Y \\@ g:i A"
+msgstr ""
+
+#: src/Model/Event.php:62 src/Model/Event.php:79 src/Model/Event.php:436
+#: src/Model/Event.php:916
+msgid "Starts:"
+msgstr ""
+
+#: src/Model/Event.php:65 src/Model/Event.php:85 src/Model/Event.php:437
+#: src/Model/Event.php:920
+msgid "Finishes:"
+msgstr ""
+
+#: src/Model/Event.php:386
+msgid "all-day"
+msgstr ""
+
+#: src/Model/Event.php:412
+msgid "Sept"
+msgstr ""
+
+#: src/Model/Event.php:434
+msgid "No events to display"
+msgstr ""
+
+#: src/Model/Event.php:562
+msgid "l, F j"
+msgstr ""
+
+#: src/Model/Event.php:593
+msgid "Edit event"
+msgstr ""
+
+#: src/Model/Event.php:594
+msgid "Duplicate event"
+msgstr ""
+
+#: src/Model/Event.php:595
+msgid "Delete event"
+msgstr ""
+
+#: src/Model/Event.php:627 src/Model/Item.php:3584 src/Model/Item.php:3591
+msgid "link to source"
+msgstr ""
+
+#: src/Model/Event.php:849
+msgid "D g:i A"
+msgstr ""
+
+#: src/Model/Event.php:850
+msgid "g:i A"
+msgstr ""
+
+#: src/Model/Event.php:935 src/Model/Event.php:937
+msgid "Show map"
+msgstr ""
+
+#: src/Model/Event.php:936
+msgid "Hide map"
+msgstr ""
+
+#: src/Model/Event.php:1028
+#, php-format
+msgid "%s's birthday"
+msgstr ""
+
+#: src/Model/Event.php:1029
+#, php-format
+msgid "Happy Birthday %s"
+msgstr ""
+
#: src/Model/Group.php:77
msgid ""
"A deleted group with this name was revived. Existing item permissions "
msgid "edit"
msgstr ""
-#: src/Model/Group.php:484 src/Module/Welcome.php:57 src/Module/Contact.php:708
+#: src/Model/Group.php:483
+msgid "add"
+msgstr ""
+
+#: src/Model/Group.php:484 src/Module/Welcome.php:57 src/Module/Contact.php:729
msgid "Groups"
msgstr ""
msgid "Edit groups"
msgstr ""
-#: src/Model/Mail.php:113 src/Model/Mail.php:250
+#: src/Model/Item.php:3326
+msgid "activity"
+msgstr ""
+
+#: src/Model/Item.php:3328 src/Object/Post.php:474
+msgid "comment"
+msgid_plural "comments"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/Model/Item.php:3331
+msgid "post"
+msgstr ""
+
+#: src/Model/Item.php:3454
+#, php-format
+msgid "Content warning: %s"
+msgstr ""
+
+#: src/Model/Item.php:3531
+msgid "bytes"
+msgstr ""
+
+#: src/Model/Item.php:3578
+msgid "View on separate page"
+msgstr ""
+
+#: src/Model/Item.php:3579
+msgid "view on separate page"
+msgstr ""
+
+#: src/Model/Mail.php:114 src/Model/Mail.php:251
msgid "[no subject]"
msgstr ""
-#: src/Model/Profile.php:212 src/Model/Profile.php:428
-#: src/Model/Profile.php:885
+#: src/Model/Notify.php:275 src/Model/Notify.php:287
+#, php-format
+msgid "%s commented on %s's post"
+msgstr ""
+
+#: src/Model/Notify.php:286
+#, php-format
+msgid "%s created a new post"
+msgstr ""
+
+#: src/Model/Notify.php:300
+#, php-format
+msgid "%s liked %s's post"
+msgstr ""
+
+#: src/Model/Notify.php:313
+#, php-format
+msgid "%s disliked %s's post"
+msgstr ""
+
+#: src/Model/Notify.php:326
+#, php-format
+msgid "%s is attending %s's event"
+msgstr ""
+
+#: src/Model/Notify.php:339
+#, php-format
+msgid "%s is not attending %s's event"
+msgstr ""
+
+#: src/Model/Notify.php:352
+#, php-format
+msgid "%s may attend %s's event"
+msgstr ""
+
+#: src/Model/Notify.php:385
+#, php-format
+msgid "%s is now friends with %s"
+msgstr ""
+
+#: src/Model/Notify.php:678
+msgid "Friend Suggestion"
+msgstr ""
+
+#: src/Model/Notify.php:712
+msgid "Friend/Connect Request"
+msgstr ""
+
+#: src/Model/Notify.php:712
+msgid "New Follower"
+msgstr ""
+
+#: src/Model/Profile.php:213 src/Model/Profile.php:424
+#: src/Model/Profile.php:881
msgid "Edit profile"
msgstr ""
-#: src/Model/Profile.php:402
+#: src/Model/Profile.php:398
msgid "Manage/edit profiles"
msgstr ""
-#: src/Model/Profile.php:451 src/Model/Profile.php:795
-#: src/Module/Directory.php:143
+#: src/Model/Profile.php:447 src/Model/Profile.php:791
+#: src/Module/Directory.php:141
msgid "Status:"
msgstr ""
-#: src/Model/Profile.php:452 src/Model/Profile.php:812
-#: src/Module/Directory.php:144
+#: src/Model/Profile.php:448 src/Model/Profile.php:808
+#: src/Module/Directory.php:142
msgid "Homepage:"
msgstr ""
-#: src/Model/Profile.php:454 src/Module/Contact.php:609
+#: src/Model/Profile.php:450 src/Module/Contact.php:630
msgid "XMPP:"
msgstr ""
-#: src/Model/Profile.php:546 src/Module/Contact.php:299
+#: src/Model/Profile.php:542 src/Module/Contact.php:320
msgid "Unfollow"
msgstr ""
-#: src/Model/Profile.php:548
+#: src/Model/Profile.php:544
msgid "Atom feed"
msgstr ""
-#: src/Model/Profile.php:588 src/Model/Profile.php:685
+#: src/Model/Profile.php:584 src/Model/Profile.php:681
msgid "g A l F d"
msgstr ""
-#: src/Model/Profile.php:589
+#: src/Model/Profile.php:585
msgid "F d"
msgstr ""
-#: src/Model/Profile.php:651 src/Model/Profile.php:736
+#: src/Model/Profile.php:647 src/Model/Profile.php:732
msgid "[today]"
msgstr ""
-#: src/Model/Profile.php:661
+#: src/Model/Profile.php:657
msgid "Birthday Reminders"
msgstr ""
-#: src/Model/Profile.php:662
+#: src/Model/Profile.php:658
msgid "Birthdays this week:"
msgstr ""
-#: src/Model/Profile.php:723
+#: src/Model/Profile.php:719
msgid "[No description]"
msgstr ""
-#: src/Model/Profile.php:749
+#: src/Model/Profile.php:745
msgid "Event Reminders"
msgstr ""
-#: src/Model/Profile.php:750
+#: src/Model/Profile.php:746
msgid "Upcoming events the next 7 days:"
msgstr ""
-#: src/Model/Profile.php:767
+#: src/Model/Profile.php:763
msgid "Member since:"
msgstr ""
-#: src/Model/Profile.php:775
+#: src/Model/Profile.php:771
msgid "j F, Y"
msgstr ""
-#: src/Model/Profile.php:776
+#: src/Model/Profile.php:772
msgid "j F"
msgstr ""
-#: src/Model/Profile.php:791
+#: src/Model/Profile.php:787
msgid "Age:"
msgstr ""
-#: src/Model/Profile.php:804
+#: src/Model/Profile.php:800
#, php-format
msgid "for %1$d %2$s"
msgstr ""
-#: src/Model/Profile.php:828
+#: src/Model/Profile.php:824
msgid "Religion:"
msgstr ""
-#: src/Model/Profile.php:836
+#: src/Model/Profile.php:832
msgid "Hobbies/Interests:"
msgstr ""
-#: src/Model/Profile.php:848
+#: src/Model/Profile.php:844
msgid "Contact information and Social Networks:"
msgstr ""
-#: src/Model/Profile.php:852
+#: src/Model/Profile.php:848
msgid "Musical interests:"
msgstr ""
-#: src/Model/Profile.php:856
+#: src/Model/Profile.php:852
msgid "Books, literature:"
msgstr ""
-#: src/Model/Profile.php:860
+#: src/Model/Profile.php:856
msgid "Television:"
msgstr ""
-#: src/Model/Profile.php:864
+#: src/Model/Profile.php:860
msgid "Film/dance/culture/entertainment:"
msgstr ""
-#: src/Model/Profile.php:868
+#: src/Model/Profile.php:864
msgid "Love/Romance:"
msgstr ""
-#: src/Model/Profile.php:872
+#: src/Model/Profile.php:868
msgid "Work/employment:"
msgstr ""
-#: src/Model/Profile.php:876
+#: src/Model/Profile.php:872
msgid "School/education:"
msgstr ""
-#: src/Model/Profile.php:881
+#: src/Model/Profile.php:877
msgid "Forums:"
msgstr ""
-#: src/Model/Profile.php:928 src/Module/Contact.php:850
+#: src/Model/Profile.php:924 src/Module/Contact.php:871
msgid "Profile Details"
msgstr ""
-#: src/Model/Profile.php:978
+#: src/Model/Profile.php:974
msgid "Only You Can See This"
msgstr ""
-#: src/Model/Profile.php:986 src/Model/Profile.php:989
+#: src/Model/Profile.php:982 src/Model/Profile.php:985
msgid "Tips for New Members"
msgstr ""
-#: src/Model/Profile.php:1186
+#: src/Model/Profile.php:1180
+#, php-format
+msgid "OpenWebAuth: %1$s welcomes %2$s"
+msgstr ""
+
+#: src/Model/User.php:357
+msgid "Login failed"
+msgstr ""
+
+#: src/Model/User.php:389
+msgid "Not enough information to authenticate"
+msgstr ""
+
+#: src/Model/User.php:483
+msgid "Password can't be empty"
+msgstr ""
+
+#: src/Model/User.php:502
+msgid "Empty passwords are not allowed."
+msgstr ""
+
+#: src/Model/User.php:506
+msgid ""
+"The new password has been exposed in a public data dump, please choose "
+"another."
+msgstr ""
+
+#: src/Model/User.php:512
+msgid ""
+"The password can't contain accentuated letters, white spaces or colons (:)"
+msgstr ""
+
+#: src/Model/User.php:612
+msgid "Passwords do not match. Password unchanged."
+msgstr ""
+
+#: src/Model/User.php:619
+msgid "An invitation is required."
+msgstr ""
+
+#: src/Model/User.php:623
+msgid "Invitation could not be verified."
+msgstr ""
+
+#: src/Model/User.php:631
+msgid "Invalid OpenID url"
+msgstr ""
+
+#: src/Model/User.php:644 src/Module/Login.php:105
+msgid ""
+"We encountered a problem while logging in with the OpenID you provided. "
+"Please check the correct spelling of the ID."
+msgstr ""
+
+#: src/Model/User.php:644 src/Module/Login.php:105
+msgid "The error message was:"
+msgstr ""
+
+#: src/Model/User.php:650
+msgid "Please enter the required information."
+msgstr ""
+
+#: src/Model/User.php:664
+#, php-format
+msgid ""
+"system.username_min_length (%s) and system.username_max_length (%s) are "
+"excluding each other, swapping values."
+msgstr ""
+
+#: src/Model/User.php:671
+#, php-format
+msgid "Username should be at least %s character."
+msgid_plural "Username should be at least %s characters."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/Model/User.php:675
+#, php-format
+msgid "Username should be at most %s character."
+msgid_plural "Username should be at most %s characters."
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/Model/User.php:683
+msgid "That doesn't appear to be your full (First Last) name."
+msgstr ""
+
+#: src/Model/User.php:688
+msgid "Your email domain is not among those allowed on this site."
+msgstr ""
+
+#: src/Model/User.php:692
+msgid "Not a valid email address."
+msgstr ""
+
+#: src/Model/User.php:695
+msgid "The nickname was blocked from registration by the nodes admin."
+msgstr ""
+
+#: src/Model/User.php:699 src/Model/User.php:707
+msgid "Cannot use that email."
+msgstr ""
+
+#: src/Model/User.php:714
+msgid "Your nickname can only contain a-z, 0-9 and _."
+msgstr ""
+
+#: src/Model/User.php:722 src/Model/User.php:779
+msgid "Nickname is already registered. Please choose another."
+msgstr ""
+
+#: src/Model/User.php:732
+msgid "SERIOUS ERROR: Generation of security keys failed."
+msgstr ""
+
+#: src/Model/User.php:766 src/Model/User.php:770
+msgid "An error occurred during registration. Please try again."
+msgstr ""
+
+#: src/Model/User.php:795
+msgid "An error occurred creating your default profile. Please try again."
+msgstr ""
+
+#: src/Model/User.php:802
+msgid "An error occurred creating your self contact. Please try again."
+msgstr ""
+
+#: src/Model/User.php:811
+msgid ""
+"An error occurred creating your default contact group. Please try again."
+msgstr ""
+
+#: src/Model/User.php:888
+#, php-format
+msgid ""
+"\n"
+"\t\t\tDear %1$s,\n"
+"\t\t\t\tThank you for registering at %2$s. Your account is pending for "
+"approval by the administrator.\n"
+"\n"
+"\t\t\tYour login details are as follows:\n"
+"\n"
+"\t\t\tSite Location:\t%3$s\n"
+"\t\t\tLogin Name:\t\t%4$s\n"
+"\t\t\tPassword:\t\t%5$s\n"
+"\t\t"
+msgstr ""
+
+#: src/Model/User.php:909
#, php-format
-msgid "OpenWebAuth: %1$s welcomes %2$s"
-msgstr ""
-
-#: src/Model/Item.php:3313
-msgid "activity"
-msgstr ""
-
-#: src/Model/Item.php:3315 src/Object/Post.php:474
-msgid "comment"
-msgid_plural "comments"
-msgstr[0] ""
-msgstr[1] ""
-
-#: src/Model/Item.php:3318
-msgid "post"
+msgid "Registration at %s"
msgstr ""
-#: src/Model/Item.php:3417
+#: src/Model/User.php:929
#, php-format
-msgid "Content warning: %s"
+msgid ""
+"\n"
+"\t\t\t\tDear %1$s,\n"
+"\t\t\t\tThank you for registering at %2$s. Your account has been created.\n"
+"\t\t\t"
msgstr ""
-#: src/Model/Item.php:3494
-msgid "bytes"
+#: src/Model/User.php:937
+#, php-format
+msgid ""
+"\n"
+"\t\t\tThe login details are as follows:\n"
+"\n"
+"\t\t\tSite Location:\t%3$s\n"
+"\t\t\tLogin Name:\t\t%1$s\n"
+"\t\t\tPassword:\t\t%5$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\tIf you ever want to delete your account, you can do so at %3$s/"
+"removeme\n"
+"\n"
+"\t\t\tThank you and welcome to %2$s."
msgstr ""
-#: src/Model/Item.php:3541
-msgid "View on separate page"
+#: src/Model/User.php:976 src/Module/Admin/Users.php:88
+#, php-format
+msgid "Registration details for %s"
msgstr ""
-#: src/Model/Item.php:3542
-msgid "view on separate page"
+#: src/Protocol/Diaspora.php:3604
+msgid "Attachments:"
msgstr ""
-#: src/Protocol/OStatus.php:1300 src/Module/Profile.php:119
-#: src/Module/Profile.php:122
+#: src/Protocol/OStatus.php:1302 src/Module/Profile.php:117
+#: src/Module/Profile.php:120
#, php-format
msgid "%s's timeline"
msgstr ""
-#: src/Protocol/OStatus.php:1304 src/Module/Profile.php:120
+#: src/Protocol/OStatus.php:1306 src/Module/Profile.php:118
#, php-format
msgid "%s's posts"
msgstr ""
-#: src/Protocol/OStatus.php:1307 src/Module/Profile.php:121
+#: src/Protocol/OStatus.php:1309 src/Module/Profile.php:119
#, php-format
msgid "%s's comments"
msgstr ""
-#: src/Protocol/OStatus.php:1861
+#: src/Protocol/OStatus.php:1864
#, php-format
msgid "%s is now following %s."
msgstr ""
-#: src/Protocol/OStatus.php:1862
+#: src/Protocol/OStatus.php:1865
msgid "following"
msgstr ""
-#: src/Protocol/OStatus.php:1865
+#: src/Protocol/OStatus.php:1868
#, php-format
msgid "%s stopped following %s."
msgstr ""
-#: src/Protocol/OStatus.php:1866
+#: src/Protocol/OStatus.php:1869
msgid "stopped following"
msgstr ""
-#: src/Protocol/Diaspora.php:2527
-msgid "Sharing notification from Diaspora network"
-msgstr ""
-
-#: src/Protocol/Diaspora.php:3674
-msgid "Attachments:"
-msgstr ""
-
-#: src/Worker/Delivery.php:508
+#: src/Worker/Delivery.php:516
msgid "(no subject)"
msgstr ""
-#: src/Module/Tos.php:35 src/Module/Tos.php:77
-msgid ""
-"At the time of registration, and for providing communications between the "
-"user account and their contacts, the user has to provide a display name (pen "
-"name), an username (nickname) and a working email address. The names will be "
-"accessible on the profile page of the account by any visitor of the page, "
-"even if other profile details are not displayed. The email address will only "
-"be used to send the user notifications about interactions, but wont be "
-"visibly displayed. The listing of an account in the node's user directory or "
-"the global user directory is optional and can be controlled in the user "
-"settings, it is not necessary for communication."
-msgstr ""
-
-#: src/Module/Tos.php:36 src/Module/Tos.php:78
-msgid ""
-"This data is required for communication and is passed on to the nodes of the "
-"communication partners and is stored there. Users can enter additional "
-"private data that may be transmitted to the communication partners accounts."
-msgstr ""
-
-#: src/Module/Tos.php:37 src/Module/Tos.php:79
-#, php-format
-msgid ""
-"At any point in time a logged in user can export their account data from the "
-"<a href=\"%1$s/settings/uexport\">account settings</a>. If the user wants to "
-"delete their account they can do so at <a href=\"%1$s/removeme\">%1$s/"
-"removeme</a>. The deletion of the account will be permanent. Deletion of the "
-"data will also be requested from the nodes of the communication partners."
-msgstr ""
-
-#: src/Module/Tos.php:40 src/Module/Tos.php:76
-msgid "Privacy Statement"
-msgstr ""
-
#: src/Module/Apps.php:29
msgid "No installed applications."
msgstr ""
msgstr ""
#: src/Module/Admin/Addons/Details.php:99 src/Module/Admin/Addons/Index.php:50
+#: src/Module/Admin/Blocklist/Server.php:73
#: src/Module/Admin/Blocklist/Contact.php:61
-#: src/Module/Admin/Blocklist/Server.php:73 src/Module/Admin/Federation.php:187
-#: src/Module/Admin/Item/Delete.php:46 src/Module/Admin/Logs/Settings.php:63
-#: src/Module/Admin/Logs/View.php:46 src/Module/Admin/Themes/Details.php:104
-#: src/Module/Admin/Themes/Index.php:95 src/Module/Admin/Tos.php:42
-#: src/Module/Admin/Users.php:277 src/Module/Admin/Queue.php:56
-#: src/Module/Admin/Site.php:566 src/Module/Admin/Summary.php:173
+#: src/Module/Admin/Federation.php:187 src/Module/Admin/Item/Delete.php:46
+#: src/Module/Admin/Logs/View.php:46 src/Module/Admin/Logs/Settings.php:63
+#: src/Module/Admin/Themes/Details.php:104 src/Module/Admin/Themes/Index.php:95
+#: src/Module/Admin/Tos.php:42 src/Module/Admin/Queue.php:56
+#: src/Module/Admin/Site.php:566 src/Module/Admin/Summary.php:192
+#: src/Module/Admin/Users.php:277
msgid "Administration"
msgstr ""
"the open addon registry at %2$s"
msgstr ""
-#: src/Module/Admin/Blocklist/Contact.php:28
-#: src/Console/GlobalCommunityBlock.php:87
-msgid "The contact has been blocked from the node"
-msgstr ""
-
-#: src/Module/Admin/Blocklist/Contact.php:30
-#: src/Console/GlobalCommunityBlock.php:82
-#, php-format
-msgid "Could not find any contact entry for this URL (%s)"
-msgstr ""
-
-#: src/Module/Admin/Blocklist/Contact.php:38
-#, php-format
-msgid "%s contact unblocked"
-msgid_plural "%s contacts unblocked"
-msgstr[0] ""
-msgstr[1] ""
-
-#: src/Module/Admin/Blocklist/Contact.php:62
-msgid "Remote Contact Blocklist"
-msgstr ""
-
-#: src/Module/Admin/Blocklist/Contact.php:63
-msgid ""
-"This page allows you to prevent any message from a remote contact to reach "
-"your node."
-msgstr ""
-
-#: src/Module/Admin/Blocklist/Contact.php:64
-msgid "Block Remote Contact"
-msgstr ""
-
-#: src/Module/Admin/Blocklist/Contact.php:65 src/Module/Admin/Users.php:280
-msgid "select all"
-msgstr ""
-
-#: src/Module/Admin/Blocklist/Contact.php:66
-msgid "select none"
-msgstr ""
-
-#: src/Module/Admin/Blocklist/Contact.php:68 src/Module/Admin/Users.php:291
-#: src/Module/Contact.php:585 src/Module/Contact.php:802
-#: src/Module/Contact.php:1061
-msgid "Unblock"
-msgstr ""
-
-#: src/Module/Admin/Blocklist/Contact.php:69
-msgid "No remote contact is blocked from this node."
-msgstr ""
-
-#: src/Module/Admin/Blocklist/Contact.php:71
-msgid "Blocked Remote Contacts"
-msgstr ""
-
-#: src/Module/Admin/Blocklist/Contact.php:72
-msgid "Block New Remote Contact"
-msgstr ""
-
-#: src/Module/Admin/Blocklist/Contact.php:73
-msgid "Photo"
-msgstr ""
-
-#: src/Module/Admin/Blocklist/Contact.php:73
-msgid "Reason"
-msgstr ""
-
-#: src/Module/Admin/Blocklist/Contact.php:81
-#, php-format
-msgid "%s total blocked contact"
-msgid_plural "%s total blocked contacts"
-msgstr[0] ""
-msgstr[1] ""
-
-#: src/Module/Admin/Blocklist/Contact.php:83
-msgid "URL of the remote contact to block."
-msgstr ""
-
-#: src/Module/Admin/Blocklist/Contact.php:84
-msgid "Block Reason"
-msgstr ""
-
#: src/Module/Admin/Blocklist/Server.php:31
msgid "Server domain pattern added to blocklist."
msgstr ""
msgid "Add Entry"
msgstr ""
-#: src/Module/Admin/Blocklist/Server.php:87
-msgid "Save changes to the blocklist"
+#: src/Module/Admin/Blocklist/Server.php:87
+msgid "Save changes to the blocklist"
+msgstr ""
+
+#: src/Module/Admin/Blocklist/Server.php:88
+msgid "Current Entries in the Blocklist"
+msgstr ""
+
+#: src/Module/Admin/Blocklist/Server.php:91
+msgid "Delete entry from blocklist"
+msgstr ""
+
+#: src/Module/Admin/Blocklist/Server.php:94
+msgid "Delete entry from blocklist?"
+msgstr ""
+
+#: src/Module/Admin/Blocklist/Contact.php:28
+#: src/Console/GlobalCommunityBlock.php:87
+msgid "The contact has been blocked from the node"
+msgstr ""
+
+#: src/Module/Admin/Blocklist/Contact.php:30
+#: src/Console/GlobalCommunityBlock.php:82
+#, php-format
+msgid "Could not find any contact entry for this URL (%s)"
+msgstr ""
+
+#: src/Module/Admin/Blocklist/Contact.php:38
+#, php-format
+msgid "%s contact unblocked"
+msgid_plural "%s contacts unblocked"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/Module/Admin/Blocklist/Contact.php:62
+msgid "Remote Contact Blocklist"
+msgstr ""
+
+#: src/Module/Admin/Blocklist/Contact.php:63
+msgid ""
+"This page allows you to prevent any message from a remote contact to reach "
+"your node."
+msgstr ""
+
+#: src/Module/Admin/Blocklist/Contact.php:64
+msgid "Block Remote Contact"
+msgstr ""
+
+#: src/Module/Admin/Blocklist/Contact.php:65 src/Module/Admin/Users.php:280
+msgid "select all"
+msgstr ""
+
+#: src/Module/Admin/Blocklist/Contact.php:66
+msgid "select none"
+msgstr ""
+
+#: src/Module/Admin/Blocklist/Contact.php:68 src/Module/Admin/Users.php:291
+#: src/Module/Contact.php:606 src/Module/Contact.php:823
+#: src/Module/Contact.php:1082
+msgid "Unblock"
+msgstr ""
+
+#: src/Module/Admin/Blocklist/Contact.php:69
+msgid "No remote contact is blocked from this node."
+msgstr ""
+
+#: src/Module/Admin/Blocklist/Contact.php:71
+msgid "Blocked Remote Contacts"
+msgstr ""
+
+#: src/Module/Admin/Blocklist/Contact.php:72
+msgid "Block New Remote Contact"
+msgstr ""
+
+#: src/Module/Admin/Blocklist/Contact.php:73
+msgid "Photo"
msgstr ""
-#: src/Module/Admin/Blocklist/Server.php:88
-msgid "Current Entries in the Blocklist"
+#: src/Module/Admin/Blocklist/Contact.php:73
+msgid "Reason"
msgstr ""
-#: src/Module/Admin/Blocklist/Server.php:91
-msgid "Delete entry from blocklist"
+#: src/Module/Admin/Blocklist/Contact.php:81
+#, php-format
+msgid "%s total blocked contact"
+msgid_plural "%s total blocked contacts"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/Module/Admin/Blocklist/Contact.php:83
+msgid "URL of the remote contact to block."
msgstr ""
-#: src/Module/Admin/Blocklist/Server.php:94
-msgid "Delete entry from blocklist?"
+#: src/Module/Admin/Blocklist/Contact.php:84
+msgid "Block Reason"
msgstr ""
#: src/Module/Admin/DBSync.php:32
msgid "Item Guid"
msgstr ""
-#: src/Module/Admin/Logs/Settings.php:27 src/Module/Admin/Summary.php:83
-#: src/Module/Admin/Summary.php:90
+#: src/Module/Admin/Logs/View.php:22
+#, php-format
+msgid ""
+"Error trying to open <strong>%1$s</strong> log file.\\r\\n<br/>Check to see "
+"if file %1$s exist and is readable."
+msgstr ""
+
+#: src/Module/Admin/Logs/View.php:26
+#, php-format
+msgid ""
+"Couldn't open <strong>%1$s</strong> log file.\\r\\n<br/>Check to see if file "
+"%1$s is readable."
+msgstr ""
+
+#: src/Module/Admin/Logs/View.php:47 src/Module/BaseAdminModule.php:99
+msgid "View Logs"
+msgstr ""
+
+#: src/Module/Admin/Logs/Settings.php:27
#, php-format
msgid "The logfile '%s' is not writable. No logging possible"
msgstr ""
"'display_errors' is to enable these options, set to '0' to disable them."
msgstr ""
-#: src/Module/Admin/Logs/View.php:22
-#, php-format
-msgid ""
-"Error trying to open <strong>%1$s</strong> log file.\\r\\n<br/>Check to see "
-"if file %1$s exist and is readable."
-msgstr ""
-
-#: src/Module/Admin/Logs/View.php:26
-#, php-format
-msgid ""
-"Couldn't open <strong>%1$s</strong> log file.\\r\\n<br/>Check to see if file "
-"%1$s is readable."
-msgstr ""
-
-#: src/Module/Admin/Logs/View.php:47 src/Module/BaseAdminModule.php:99
-msgid "View Logs"
-msgstr ""
-
#: src/Module/Admin/Themes/Details.php:32 src/Module/Admin/Themes/Embed.php:46
msgid "Theme settings updated."
msgstr ""
msgid "Screenshot"
msgstr ""
-#: src/Module/Admin/Themes/Details.php:105 src/Module/Admin/Themes/Index.php:96
-#: src/Module/BaseAdminModule.php:83
-msgid "Themes"
-msgstr ""
-
-#: src/Module/Admin/Themes/Embed.php:67
-msgid "Unknown theme."
-msgstr ""
-
-#: src/Module/Admin/Themes/Index.php:98
-msgid "Reload active themes"
-msgstr ""
-
-#: src/Module/Admin/Themes/Index.php:103
-#, php-format
-msgid "No themes found on the system. They should be placed in %1$s"
-msgstr ""
-
-#: src/Module/Admin/Themes/Index.php:104
-msgid "[Experimental]"
-msgstr ""
-
-#: src/Module/Admin/Themes/Index.php:105
-msgid "[Unsupported]"
-msgstr ""
-
-#: src/Module/Admin/Tos.php:30
-msgid "The Terms of Service settings have been updated."
-msgstr ""
-
-#: src/Module/Admin/Tos.php:44
-msgid "Display Terms of Service"
-msgstr ""
-
-#: src/Module/Admin/Tos.php:44
-msgid ""
-"Enable the Terms of Service page. If this is enabled a link to the terms "
-"will be added to the registration form and the general information page."
-msgstr ""
-
-#: src/Module/Admin/Tos.php:45
-msgid "Display Privacy Statement"
-msgstr ""
-
-#: src/Module/Admin/Tos.php:45
-#, php-format
-msgid ""
-"Show some informations regarding the needed information to operate the node "
-"according e.g. to <a href=\"%s\" target=\"_blank\">EU-GDPR</a>."
-msgstr ""
-
-#: src/Module/Admin/Tos.php:46
-msgid "Privacy Statement Preview"
-msgstr ""
-
-#: src/Module/Admin/Tos.php:48
-msgid "The Terms of Service"
-msgstr ""
-
-#: src/Module/Admin/Tos.php:48
-msgid ""
-"Enter the Terms of Service for your node here. You can use BBCode. Headers "
-"of sections should be [h2] and below."
-msgstr ""
-
-#: src/Module/Admin/Users.php:48
-#, 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 ""
-
-#: src/Module/Admin/Users.php:51
-#, 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\tIf you ever want to delete your account, you can do so at %1$s/"
-"removeme\n"
-"\n"
-"\t\t\tThank you and welcome to %4$s."
-msgstr ""
-
-#: src/Module/Admin/Users.php:96
-#, php-format
-msgid "%s user blocked"
-msgid_plural "%s users blocked"
-msgstr[0] ""
-msgstr[1] ""
-
-#: src/Module/Admin/Users.php:102
-#, php-format
-msgid "%s user unblocked"
-msgid_plural "%s users unblocked"
-msgstr[0] ""
-msgstr[1] ""
-
-#: src/Module/Admin/Users.php:110 src/Module/Admin/Users.php:160
-msgid "You can't remove yourself"
-msgstr ""
-
-#: src/Module/Admin/Users.php:114
-#, php-format
-msgid "%s user deleted"
-msgid_plural "%s users deleted"
-msgstr[0] ""
-msgstr[1] ""
-
-#: src/Module/Admin/Users.php:158
-#, php-format
-msgid "User \"%s\" deleted"
-msgstr ""
-
-#: src/Module/Admin/Users.php:167
-#, php-format
-msgid "User \"%s\" blocked"
-msgstr ""
-
-#: src/Module/Admin/Users.php:173
-#, php-format
-msgid "User \"%s\" unblocked"
-msgstr ""
-
-#: src/Module/Admin/Users.php:226
-msgid "Private Forum"
-msgstr ""
-
-#: src/Module/Admin/Users.php:233
-msgid "Relay"
-msgstr ""
-
-#: src/Module/Admin/Users.php:272 src/Module/Admin/Users.php:297
-msgid "Register date"
-msgstr ""
-
-#: src/Module/Admin/Users.php:272 src/Module/Admin/Users.php:297
-msgid "Last login"
-msgstr ""
-
-#: src/Module/Admin/Users.php:272 src/Module/Admin/Users.php:297
-msgid "Last item"
-msgstr ""
-
-#: src/Module/Admin/Users.php:272
-msgid "Type"
-msgstr ""
-
-#: src/Module/Admin/Users.php:278 src/Module/Admin/Users.php:295
-#: src/Module/Admin/Site.php:471 src/Module/BaseAdminModule.php:81
-msgid "Users"
-msgstr ""
-
-#: src/Module/Admin/Users.php:279
-msgid "Add User"
-msgstr ""
-
-#: src/Module/Admin/Users.php:281
-msgid "User registrations waiting for confirm"
-msgstr ""
-
-#: src/Module/Admin/Users.php:282
-msgid "User waiting for permanent deletion"
-msgstr ""
-
-#: src/Module/Admin/Users.php:283
-msgid "Request date"
-msgstr ""
-
-#: src/Module/Admin/Users.php:284
-msgid "No registrations."
+#: src/Module/Admin/Themes/Details.php:105 src/Module/Admin/Themes/Index.php:96
+#: src/Module/BaseAdminModule.php:83
+msgid "Themes"
msgstr ""
-#: src/Module/Admin/Users.php:285
-msgid "Note from the user"
+#: src/Module/Admin/Themes/Embed.php:67
+msgid "Unknown theme."
msgstr ""
-#: src/Module/Admin/Users.php:287
-msgid "Deny"
+#: src/Module/Admin/Themes/Index.php:98
+msgid "Reload active themes"
msgstr ""
-#: src/Module/Admin/Users.php:290
-msgid "User blocked"
+#: src/Module/Admin/Themes/Index.php:103
+#, php-format
+msgid "No themes found on the system. They should be placed in %1$s"
msgstr ""
-#: src/Module/Admin/Users.php:292
-msgid "Site admin"
+#: src/Module/Admin/Themes/Index.php:104
+msgid "[Experimental]"
msgstr ""
-#: src/Module/Admin/Users.php:293
-msgid "Account expired"
+#: src/Module/Admin/Themes/Index.php:105
+msgid "[Unsupported]"
msgstr ""
-#: src/Module/Admin/Users.php:296
-msgid "New User"
+#: src/Module/Admin/Tos.php:30
+msgid "The Terms of Service settings have been updated."
msgstr ""
-#: src/Module/Admin/Users.php:297
-msgid "Permanent deletion"
+#: src/Module/Admin/Tos.php:44
+msgid "Display Terms of Service"
msgstr ""
-#: src/Module/Admin/Users.php:302
+#: src/Module/Admin/Tos.php:44
msgid ""
-"Selected users will be deleted!\\n\\nEverything these users had posted on "
-"this site will be permanently deleted!\\n\\nAre you sure?"
+"Enable the Terms of Service page. If this is enabled a link to the terms "
+"will be added to the registration form and the general information page."
msgstr ""
-#: src/Module/Admin/Users.php:303
-msgid ""
-"The user {0} will be deleted!\\n\\nEverything this user has posted on this "
-"site will be permanently deleted!\\n\\nAre you sure?"
+#: src/Module/Admin/Tos.php:45
+msgid "Display Privacy Statement"
msgstr ""
-#: src/Module/Admin/Users.php:313
-msgid "Name of the new user."
+#: src/Module/Admin/Tos.php:45
+#, php-format
+msgid ""
+"Show some informations regarding the needed information to operate the node "
+"according e.g. to <a href=\"%s\" target=\"_blank\">EU-GDPR</a>."
msgstr ""
-#: src/Module/Admin/Users.php:314
-msgid "Nickname"
+#: src/Module/Admin/Tos.php:46
+msgid "Privacy Statement Preview"
msgstr ""
-#: src/Module/Admin/Users.php:314
-msgid "Nickname of the new user."
+#: src/Module/Admin/Tos.php:48
+msgid "The Terms of Service"
msgstr ""
-#: src/Module/Admin/Users.php:315
-msgid "Email address of the new user."
+#: src/Module/Admin/Tos.php:48
+msgid ""
+"Enter the Terms of Service for your node here. You can use BBCode. Headers "
+"of sections should be [h2] and below."
msgstr ""
#: src/Module/Admin/Queue.php:34
#: src/Module/Admin/Site.php:470 src/Module/Admin/Site.php:665
#: src/Module/Admin/Site.php:675 src/Module/Settings/TwoFactor/Index.php:97
-#: src/Module/Contact.php:525
+#: src/Module/Contact.php:546
msgid "Disabled"
msgstr ""
+#: src/Module/Admin/Site.php:471 src/Module/Admin/Users.php:278
+#: src/Module/Admin/Users.php:295 src/Module/BaseAdminModule.php:81
+msgid "Users"
+msgstr ""
+
#: src/Module/Admin/Site.php:472
msgid "Users, Global Contacts"
msgstr ""
msgid "Republish users to directory"
msgstr ""
-#: src/Module/Admin/Site.php:570 src/Module/Register.php:121
+#: src/Module/Admin/Site.php:570 src/Module/Register.php:115
msgid "Registration"
msgstr ""
msgid "Comma separated list of tags for the \"tags\" subscription."
msgstr ""
-#: src/Module/Admin/Site.php:677
-msgid "Allow user tags"
-msgstr ""
+#: src/Module/Admin/Site.php:677
+msgid "Allow user tags"
+msgstr ""
+
+#: src/Module/Admin/Site.php:677
+msgid ""
+"If enabled, the tags from the saved searches will used for the \"tags\" "
+"subscription in addition to the \"relay_server_tags\"."
+msgstr ""
+
+#: src/Module/Admin/Site.php:680
+msgid "Start Relocation"
+msgstr ""
+
+#: src/Module/Admin/Summary.php:32
+#, 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 command <tt>php bin/"
+"console.php dbstructure toinnodb</tt> of your Friendica installation for an "
+"automatic conversion.<br />"
+msgstr ""
+
+#: src/Module/Admin/Summary.php:40
+#, php-format
+msgid ""
+"There is a new version of Friendica available for download. Your current "
+"version is %1$s, upstream version is %2$s"
+msgstr ""
+
+#: src/Module/Admin/Summary.php:49
+msgid ""
+"The database update failed. Please run \"php bin/console.php dbstructure "
+"update\" from the command line and have a look at the errors that might "
+"appear."
+msgstr ""
+
+#: src/Module/Admin/Summary.php:53
+msgid ""
+"The last update failed. Please run \"php bin/console.php dbstructure update"
+"\" from the command line and have a look at the errors that might appear. "
+"(Some of the errors are possibly inside the logfile.)"
+msgstr ""
+
+#: src/Module/Admin/Summary.php:58
+msgid "The worker was never executed. Please check your database structure!"
+msgstr ""
+
+#: src/Module/Admin/Summary.php:60
+#, php-format
+msgid ""
+"The last worker execution was on %s UTC. This is older than one hour. Please "
+"check your crontab settings."
+msgstr ""
+
+#: src/Module/Admin/Summary.php:65
+#, php-format
+msgid ""
+"Friendica's configuration now is stored in config/local.config.php, please "
+"copy config/local-sample.config.php and move your config from <code>."
+"htconfig.php</code>. See <a href=\"%s\">the Config help page</a> for help "
+"with the transition."
+msgstr ""
+
+#: src/Module/Admin/Summary.php:69
+#, php-format
+msgid ""
+"Friendica's configuration now is stored in config/local.config.php, please "
+"copy config/local-sample.config.php and move your config from <code>config/"
+"local.ini.php</code>. See <a href=\"%s\">the Config help page</a> for help "
+"with the transition."
+msgstr ""
+
+#: src/Module/Admin/Summary.php:75
+#, php-format
+msgid ""
+"<a href=\"%s\">%s</a> is not reachable on your system. This is a severe "
+"configuration issue that prevents server to server communication. See <a "
+"href=\"%s\">the installation page</a> for help."
+msgstr ""
+
+#: src/Module/Admin/Summary.php:94
+#, php-format
+msgid "The logfile '%s' is not usable. No logging possible (error: '%s')"
+msgstr ""
+
+#: src/Module/Admin/Summary.php:109
+#, php-format
+msgid "The debug logfile '%s' is not usable. No logging possible (error: '%s')"
+msgstr ""
+
+#: src/Module/Admin/Summary.php:125
+#, php-format
+msgid ""
+"Friendica's system.basepath was updated from '%s' to '%s'. Please remove the "
+"system.basepath from your db to avoid differences."
+msgstr ""
+
+#: src/Module/Admin/Summary.php:133
+#, php-format
+msgid ""
+"Friendica's current system.basepath '%s' is wrong and the config file '%s' "
+"isn't used."
+msgstr ""
+
+#: src/Module/Admin/Summary.php:141
+#, php-format
+msgid ""
+"Friendica's current system.basepath '%s' is not equal to the config file "
+"'%s'. Please fix your configuration."
+msgstr ""
+
+#: src/Module/Admin/Summary.php:148
+msgid "Normal Account"
+msgstr ""
+
+#: src/Module/Admin/Summary.php:149
+msgid "Automatic Follower Account"
+msgstr ""
+
+#: src/Module/Admin/Summary.php:150
+msgid "Public Forum Account"
+msgstr ""
+
+#: src/Module/Admin/Summary.php:151
+msgid "Automatic Friend Account"
+msgstr ""
+
+#: src/Module/Admin/Summary.php:152
+msgid "Blog Account"
+msgstr ""
+
+#: src/Module/Admin/Summary.php:153
+msgid "Private Forum Account"
+msgstr ""
+
+#: src/Module/Admin/Summary.php:173
+msgid "Message queues"
+msgstr ""
+
+#: src/Module/Admin/Summary.php:179
+msgid "Server Settings"
+msgstr ""
+
+#: src/Module/Admin/Summary.php:193
+msgid "Summary"
+msgstr ""
+
+#: src/Module/Admin/Summary.php:195
+msgid "Registered users"
+msgstr ""
+
+#: src/Module/Admin/Summary.php:197
+msgid "Pending registrations"
+msgstr ""
+
+#: src/Module/Admin/Summary.php:198
+msgid "Version"
+msgstr ""
+
+#: src/Module/Admin/Summary.php:202
+msgid "Active addons"
+msgstr ""
+
+#: src/Module/Admin/Users.php:48
+#, 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 ""
+
+#: src/Module/Admin/Users.php:51
+#, 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\tIf you ever want to delete your account, you can do so at %1$s/"
+"removeme\n"
+"\n"
+"\t\t\tThank you and welcome to %4$s."
+msgstr ""
+
+#: src/Module/Admin/Users.php:96
+#, php-format
+msgid "%s user blocked"
+msgid_plural "%s users blocked"
+msgstr[0] ""
+msgstr[1] ""
-#: src/Module/Admin/Site.php:677
-msgid ""
-"If enabled, the tags from the saved searches will used for the \"tags\" "
-"subscription in addition to the \"relay_server_tags\"."
+#: src/Module/Admin/Users.php:102
+#, php-format
+msgid "%s user unblocked"
+msgid_plural "%s users unblocked"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/Module/Admin/Users.php:110 src/Module/Admin/Users.php:160
+msgid "You can't remove yourself"
msgstr ""
-#: src/Module/Admin/Site.php:680
-msgid "Start Relocation"
+#: src/Module/Admin/Users.php:114
+#, php-format
+msgid "%s user deleted"
+msgid_plural "%s users deleted"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/Module/Admin/Users.php:158
+#, php-format
+msgid "User \"%s\" deleted"
msgstr ""
-#: src/Module/Admin/Summary.php:30
+#: src/Module/Admin/Users.php:167
#, 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 command <tt>php bin/"
-"console.php dbstructure toinnodb</tt> of your Friendica installation for an "
-"automatic conversion.<br />"
+msgid "User \"%s\" blocked"
msgstr ""
-#: src/Module/Admin/Summary.php:38
+#: src/Module/Admin/Users.php:173
#, php-format
-msgid ""
-"There is a new version of Friendica available for download. Your current "
-"version is %1$s, upstream version is %2$s"
+msgid "User \"%s\" unblocked"
msgstr ""
-#: src/Module/Admin/Summary.php:47
-msgid ""
-"The database update failed. Please run \"php bin/console.php dbstructure "
-"update\" from the command line and have a look at the errors that might "
-"appear."
+#: src/Module/Admin/Users.php:226
+msgid "Private Forum"
msgstr ""
-#: src/Module/Admin/Summary.php:51
-msgid ""
-"The last update failed. Please run \"php bin/console.php dbstructure update"
-"\" from the command line and have a look at the errors that might appear. "
-"(Some of the errors are possibly inside the logfile.)"
+#: src/Module/Admin/Users.php:233
+msgid "Relay"
msgstr ""
-#: src/Module/Admin/Summary.php:56
-msgid "The worker was never executed. Please check your database structure!"
+#: src/Module/Admin/Users.php:272 src/Module/Admin/Users.php:297
+msgid "Register date"
msgstr ""
-#: src/Module/Admin/Summary.php:58
-#, php-format
-msgid ""
-"The last worker execution was on %s UTC. This is older than one hour. Please "
-"check your crontab settings."
+#: src/Module/Admin/Users.php:272 src/Module/Admin/Users.php:297
+msgid "Last login"
msgstr ""
-#: src/Module/Admin/Summary.php:63
-#, php-format
-msgid ""
-"Friendica's configuration now is stored in config/local.config.php, please "
-"copy config/local-sample.config.php and move your config from <code>."
-"htconfig.php</code>. See <a href=\"%s\">the Config help page</a> for help "
-"with the transition."
+#: src/Module/Admin/Users.php:272 src/Module/Admin/Users.php:297
+msgid "Last item"
msgstr ""
-#: src/Module/Admin/Summary.php:67
-#, php-format
-msgid ""
-"Friendica's configuration now is stored in config/local.config.php, please "
-"copy config/local-sample.config.php and move your config from <code>config/"
-"local.ini.php</code>. See <a href=\"%s\">the Config help page</a> for help "
-"with the transition."
+#: src/Module/Admin/Users.php:272
+msgid "Type"
msgstr ""
-#: src/Module/Admin/Summary.php:73
-#, php-format
-msgid ""
-"<a href=\"%s\">%s</a> is not reachable on your system. This is a severe "
-"configuration issue that prevents server to server communication. See <a "
-"href=\"%s\">the installation page</a> for help."
+#: src/Module/Admin/Users.php:279
+msgid "Add User"
msgstr ""
-#: src/Module/Admin/Summary.php:106
-#, php-format
-msgid ""
-"Friendica's system.basepath was updated from '%s' to '%s'. Please remove the "
-"system.basepath from your db to avoid differences."
+#: src/Module/Admin/Users.php:281
+msgid "User registrations waiting for confirm"
msgstr ""
-#: src/Module/Admin/Summary.php:114
-#, php-format
-msgid ""
-"Friendica's current system.basepath '%s' is wrong and the config file '%s' "
-"isn't used."
+#: src/Module/Admin/Users.php:282
+msgid "User waiting for permanent deletion"
msgstr ""
-#: src/Module/Admin/Summary.php:122
-#, php-format
-msgid ""
-"Friendica's current system.basepath '%s' is not equal to the config file "
-"'%s'. Please fix your configuration."
+#: src/Module/Admin/Users.php:283
+msgid "Request date"
msgstr ""
-#: src/Module/Admin/Summary.php:129
-msgid "Normal Account"
+#: src/Module/Admin/Users.php:284
+msgid "No registrations."
msgstr ""
-#: src/Module/Admin/Summary.php:130
-msgid "Automatic Follower Account"
+#: src/Module/Admin/Users.php:285
+msgid "Note from the user"
msgstr ""
-#: src/Module/Admin/Summary.php:131
-msgid "Public Forum Account"
+#: src/Module/Admin/Users.php:287
+msgid "Deny"
msgstr ""
-#: src/Module/Admin/Summary.php:132
-msgid "Automatic Friend Account"
+#: src/Module/Admin/Users.php:290
+msgid "User blocked"
msgstr ""
-#: src/Module/Admin/Summary.php:133
-msgid "Blog Account"
+#: src/Module/Admin/Users.php:292
+msgid "Site admin"
msgstr ""
-#: src/Module/Admin/Summary.php:134
-msgid "Private Forum Account"
+#: src/Module/Admin/Users.php:293
+msgid "Account expired"
msgstr ""
-#: src/Module/Admin/Summary.php:154
-msgid "Message queues"
+#: src/Module/Admin/Users.php:296
+msgid "New User"
msgstr ""
-#: src/Module/Admin/Summary.php:160
-msgid "Server Settings"
+#: src/Module/Admin/Users.php:297
+msgid "Permanent deletion"
msgstr ""
-#: src/Module/Admin/Summary.php:174
-msgid "Summary"
+#: src/Module/Admin/Users.php:302
+msgid ""
+"Selected users will be deleted!\\n\\nEverything these users had posted on "
+"this site will be permanently deleted!\\n\\nAre you sure?"
msgstr ""
-#: src/Module/Admin/Summary.php:176
-msgid "Registered users"
+#: src/Module/Admin/Users.php:303
+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 ""
-#: src/Module/Admin/Summary.php:178
-msgid "Pending registrations"
+#: src/Module/Admin/Users.php:313
+msgid "Name of the new user."
msgstr ""
-#: src/Module/Admin/Summary.php:179
-msgid "Version"
+#: src/Module/Admin/Users.php:314
+msgid "Nickname"
msgstr ""
-#: src/Module/Admin/Summary.php:183
-msgid "Active addons"
+#: src/Module/Admin/Users.php:314
+msgid "Nickname of the new user."
msgstr ""
-#: src/Module/AllFriends.php:55
-msgid "No friends to display."
+#: src/Module/Admin/Users.php:315
+msgid "Email address of the new user."
msgstr ""
#: src/Module/Attach.php:36 src/Module/Attach.php:48
msgid "User registrations waiting for confirmation"
msgstr ""
-#: src/Module/BaseSearchModule.php:52
-#, php-format
-msgid "People Search - %s"
-msgstr ""
-
-#: src/Module/BaseSearchModule.php:62
-#, php-format
-msgid "Forum Search - %s"
-msgstr ""
-
-#: src/Module/Debug/Feed.php:20 src/Module/Filer/SaveTag.php:20
-msgid "You must be logged in to use this module"
-msgstr ""
-
-#: src/Module/Debug/Feed.php:49
-msgid "Source URL"
-msgstr ""
-
-#: src/Module/Debug/Localtime.php:30
-msgid "Time Conversion"
-msgstr ""
-
-#: src/Module/Debug/Localtime.php:31
-msgid ""
-"Friendica provides this service for sharing events with other networks and "
-"friends in unknown timezones."
-msgstr ""
-
-#: src/Module/Debug/Localtime.php:32
-#, php-format
-msgid "UTC time: %s"
-msgstr ""
-
-#: src/Module/Debug/Localtime.php:35
-#, php-format
-msgid "Current timezone: %s"
-msgstr ""
-
-#: src/Module/Debug/Localtime.php:39
-#, php-format
-msgid "Converted localtime: %s"
-msgstr ""
-
-#: src/Module/Debug/Localtime.php:43
-msgid "Please select your timezone:"
-msgstr ""
-
-#: src/Module/Debug/Probe.php:19 src/Module/Debug/WebFinger.php:18
-msgid "Only logged in users are permitted to perform a probing."
-msgstr ""
-
-#: src/Module/Debug/Probe.php:35
-msgid "Lookup address"
-msgstr ""
-
#: src/Module/Debug/Babel.php:32
msgid "Source input"
msgstr ""
msgid "HTML"
msgstr ""
-#: src/Module/Directory.php:61
-msgid "No entries (some entries may be hidden)."
+#: src/Module/Debug/Feed.php:20 src/Module/Filer/SaveTag.php:20
+msgid "You must be logged in to use this module"
msgstr ""
-#: src/Module/Directory.php:80
-msgid "Find on this site"
+#: src/Module/Debug/Feed.php:49
+msgid "Source URL"
msgstr ""
-#: src/Module/Directory.php:82
-msgid "Results for:"
+#: src/Module/Debug/Localtime.php:30
+msgid "Time Conversion"
msgstr ""
-#: src/Module/Directory.php:84
-msgid "Site Directory"
+#: src/Module/Debug/Localtime.php:31
+msgid ""
+"Friendica provides this service for sharing events with other networks and "
+"friends in unknown timezones."
+msgstr ""
+
+#: src/Module/Debug/Localtime.php:32
+#, php-format
+msgid "UTC time: %s"
+msgstr ""
+
+#: src/Module/Debug/Localtime.php:35
+#, php-format
+msgid "Current timezone: %s"
+msgstr ""
+
+#: src/Module/Debug/Localtime.php:39
+#, php-format
+msgid "Converted localtime: %s"
+msgstr ""
+
+#: src/Module/Debug/Localtime.php:43
+msgid "Please select your timezone:"
+msgstr ""
+
+#: src/Module/Debug/Probe.php:19 src/Module/Debug/WebFinger.php:18
+msgid "Only logged in users are permitted to perform a probing."
+msgstr ""
+
+#: src/Module/Debug/Probe.php:35
+msgid "Lookup address"
msgstr ""
#: src/Module/Filer/SaveTag.php:39
msgid "- select -"
msgstr ""
-#: src/Module/FollowConfirm.php:37
-msgid "No given contact."
-msgstr ""
-
#: src/Module/Friendica.php:40
msgid "Installed addons/apps:"
msgstr ""
msgid "Help:"
msgstr ""
-#: src/Module/Home.php:42
-#, php-format
-msgid "Welcome to %s"
-msgstr ""
-
#: src/Module/Invite.php:37
msgid "Total invitation limit exceeded."
msgstr ""
"important, please visit http://friendi.ca"
msgstr ""
-#: src/Module/Item/Compose.php:30
+#: src/Module/Item/Compose.php:31
msgid "Please enter a post body."
msgstr ""
-#: src/Module/Item/Compose.php:43
+#: src/Module/Item/Compose.php:44
msgid "This feature is only available with the frio theme."
msgstr ""
-#: src/Module/Item/Compose.php:63
+#: src/Module/Item/Compose.php:67
msgid "Compose new personal note"
msgstr ""
-#: src/Module/Item/Compose.php:70
+#: src/Module/Item/Compose.php:74
msgid "Compose new post"
msgstr ""
-#: src/Module/Item/Compose.php:190
+#: src/Module/Item/Compose.php:194
msgid "Clear the location"
msgstr ""
-#: src/Module/Item/Compose.php:191
+#: src/Module/Item/Compose.php:195
msgid "Location services are unavailable on your device"
msgstr ""
-#: src/Module/Item/Compose.php:192
+#: src/Module/Item/Compose.php:196
msgid ""
"Location services are disabled. Please check the website's permissions on "
"your device"
msgstr ""
-#: src/Module/Item/Compose.php:196
+#: src/Module/Item/Compose.php:200
msgid "Public"
msgstr ""
-#: src/Module/Item/Compose.php:197
+#: src/Module/Item/Compose.php:201
msgid ""
"This post will be sent to all your followers and can be seen in the "
"community pages and by anyone with its link."
msgstr ""
-#: src/Module/Item/Compose.php:198
+#: src/Module/Item/Compose.php:202
msgid "Limited/Private"
msgstr ""
-#: src/Module/Item/Compose.php:199
+#: src/Module/Item/Compose.php:203
msgid ""
"This post will be sent only to the people in the first box, to the exception "
"of the people mentioned in the second box. It won't appear anywhere public."
msgstr ""
-#: src/Module/Login.php:286
-msgid "Create a New Account"
-msgstr ""
-
-#: src/Module/Login.php:319
-msgid "Password: "
-msgstr ""
-
-#: src/Module/Login.php:320
-msgid "Remember me"
-msgstr ""
-
-#: src/Module/Login.php:323
-msgid "Or login using OpenID: "
-msgstr ""
-
-#: src/Module/Login.php:329
-msgid "Forgot your password?"
-msgstr ""
-
-#: src/Module/Login.php:332
-msgid "Website Terms of Service"
-msgstr ""
-
-#: src/Module/Login.php:333
-msgid "terms of service"
-msgstr ""
-
-#: src/Module/Login.php:335
-msgid "Website Privacy Policy"
-msgstr ""
-
-#: src/Module/Login.php:336
-msgid "privacy policy"
-msgstr ""
-
-#: src/Module/Logout.php:38
-msgid "Logged out."
-msgstr ""
-
#: src/Module/Maintenance.php:29
msgid "System down for maintenance"
msgstr ""
-#: src/Module/PageNotFound.php:13
-msgid "Page not found."
-msgstr ""
-
#: src/Module/Photo.php:87
#, php-format
msgid "Invalid photo with id %s."
msgstr ""
-#: src/Module/Profile/Contacts.php:23 src/Module/Profile/Contacts.php:36
+#: src/Module/Profile/Contacts.php:24 src/Module/Profile/Contacts.php:37
msgid "User not found."
msgstr ""
msgid "No contacts."
msgstr ""
-#: src/Module/Profile/Contacts.php:93 src/Module/Contact.php:569
-#: src/Module/Contact.php:1008
+#: src/Module/Profile/Contacts.php:93 src/Module/Contact.php:590
+#: src/Module/Contact.php:1029
#, php-format
msgid "Visit %s's profile [%s]"
msgstr ""
msgid "All contacts"
msgstr ""
-#: src/Module/Register.php:83
-msgid ""
-"You may (optionally) fill in this form via OpenID by supplying your OpenID "
-"and clicking \"Register\"."
-msgstr ""
-
-#: src/Module/Register.php:84
-msgid ""
-"If you are not familiar with OpenID, please leave that field blank and fill "
-"in the rest of the items."
-msgstr ""
-
-#: src/Module/Register.php:85
-msgid "Your OpenID (optional): "
-msgstr ""
-
-#: src/Module/Register.php:94
-msgid "Include your profile in member directory?"
-msgstr ""
-
-#: src/Module/Register.php:117
-msgid "Note for the admin"
-msgstr ""
-
-#: src/Module/Register.php:117
-msgid "Leave a message for the admin, why you want to join this node"
-msgstr ""
-
-#: src/Module/Register.php:118
-msgid "Membership on this site is by invitation only."
-msgstr ""
-
-#: src/Module/Register.php:119
-msgid "Your invitation code: "
-msgstr ""
-
-#: src/Module/Register.php:127
-msgid "Your Full Name (e.g. Joe Smith, real or real-looking): "
+#: src/Module/Search/Acl.php:37
+msgid "You must be logged in to use this module."
msgstr ""
-#: src/Module/Register.php:128
-msgid ""
-"Your Email Address: (Initial information will be send there, so this has to "
-"be an existing address.)"
+#: src/Module/Search/Index.php:35
+msgid "Only logged in users are permitted to perform a search."
msgstr ""
-#: src/Module/Register.php:130
-msgid "Leave empty for an auto generated password."
+#: src/Module/Search/Index.php:57
+msgid "Only one search per minute is permitted for not logged in users."
msgstr ""
-#: src/Module/Register.php:132
+#: src/Module/Search/Index.php:183
#, php-format
-msgid ""
-"Choose a profile nickname. This must begin with a text character. Your "
-"profile address on this site will then be \"<strong>nickname@%s</strong>\"."
-msgstr ""
-
-#: src/Module/Register.php:133
-msgid "Choose a nickname: "
-msgstr ""
-
-#: src/Module/Register.php:142
-msgid "Import your profile to this friendica instance"
-msgstr ""
-
-#: src/Module/Register.php:149
-msgid "Note: This node explicitly contains adult content"
-msgstr ""
-
-#: src/Module/Register.php:242
-msgid ""
-"Registration successful. Please check your email for further instructions."
+msgid "Items tagged with: %s"
msgstr ""
-#: src/Module/Register.php:246
+#: src/Module/Search/Index.php:185 src/Module/Contact.php:815
#, 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."
+msgid "Results for: %s"
msgstr ""
-#: src/Module/Register.php:253
-msgid "Registration successful."
+#: src/Module/Search/Saved.php:29
+msgid "Search term successfully saved."
msgstr ""
-#: src/Module/Register.php:258
-msgid "Your registration can not be processed."
+#: src/Module/Search/Saved.php:31
+msgid "Search term already saved."
msgstr ""
-#: src/Module/Register.php:304
-msgid "Your registration is pending approval by the site owner."
+#: src/Module/Search/Saved.php:37
+msgid "Search term successfully removed."
msgstr ""
#: src/Module/Settings/TwoFactor/AppSpecific.php:36
msgid "Generate"
msgstr ""
+#: src/Module/Settings/TwoFactor/Recovery.php:50
+msgid "New recovery codes successfully generated."
+msgstr ""
+
+#: src/Module/Settings/TwoFactor/Recovery.php:76
+msgid "Two-factor recovery codes"
+msgstr ""
+
+#: src/Module/Settings/TwoFactor/Recovery.php:78
+msgid ""
+"<p>Recovery codes can be used to access your account in the event you lose "
+"access to your device and cannot receive two-factor authentication codes.</"
+"p><p><strong>Put these in a safe spot!</strong> If you lose your device and "
+"don’t have the recovery codes you will lose access to your account.</p>"
+msgstr ""
+
+#: src/Module/Settings/TwoFactor/Recovery.php:80
+msgid ""
+"When you generate new recovery codes, you must copy the new codes. Your old "
+"codes won’t work anymore."
+msgstr ""
+
+#: src/Module/Settings/TwoFactor/Recovery.php:81
+msgid "Generate new recovery codes"
+msgstr ""
+
+#: src/Module/Settings/TwoFactor/Recovery.php:83
+msgid "Next: Verification"
+msgstr ""
+
#: src/Module/Settings/TwoFactor/Index.php:51
msgid "Two-factor authentication successfully disabled."
msgstr ""
"supporting two-factor authentication.</p>"
msgstr ""
-#: src/Module/Settings/TwoFactor/Index.php:111 src/Module/Contact.php:614
+#: src/Module/Settings/TwoFactor/Index.php:111 src/Module/Contact.php:635
msgid "Actions"
msgstr ""
msgid "Finish app configuration"
msgstr ""
-#: src/Module/Settings/TwoFactor/Recovery.php:50
-msgid "New recovery codes successfully generated."
-msgstr ""
-
-#: src/Module/Settings/TwoFactor/Recovery.php:76
-msgid "Two-factor recovery codes"
-msgstr ""
-
-#: src/Module/Settings/TwoFactor/Recovery.php:78
-msgid ""
-"<p>Recovery codes can be used to access your account in the event you lose "
-"access to your device and cannot receive two-factor authentication codes.</"
-"p><p><strong>Put these in a safe spot!</strong> If you lose your device and "
-"don’t have the recovery codes you will lose access to your account.</p>"
-msgstr ""
-
-#: src/Module/Settings/TwoFactor/Recovery.php:80
-msgid ""
-"When you generate new recovery codes, you must copy the new codes. Your old "
-"codes won’t work anymore."
-msgstr ""
-
-#: src/Module/Settings/TwoFactor/Recovery.php:81
-msgid "Generate new recovery codes"
-msgstr ""
-
-#: src/Module/Settings/TwoFactor/Recovery.php:83
-msgid "Next: Verification"
-msgstr ""
-
#: src/Module/Settings/TwoFactor/Verify.php:63
msgid "Two-factor authentication successfully activated."
msgstr ""
#: src/Module/Settings/TwoFactor/Verify.php:67
-#: src/Module/TwoFactor/Recovery.php:46 src/Module/TwoFactor/Verify.php:43
+#: src/Module/TwoFactor/Verify.php:43 src/Module/TwoFactor/Recovery.php:46
msgid "Invalid code, please retry."
msgstr ""
msgid "Verify code and enable two-factor authentication"
msgstr ""
+#: src/Module/Settings/Delegation.php:37
+msgid "Delegation successfully granted."
+msgstr ""
+
+#: src/Module/Settings/Delegation.php:39
+msgid "Parent user not found, unavailable or password doesn't match."
+msgstr ""
+
+#: src/Module/Settings/Delegation.php:43
+msgid "Delegation successfully revoked."
+msgstr ""
+
+#: src/Module/Settings/Delegation.php:66 src/Module/Settings/Delegation.php:88
+msgid ""
+"Delegated administrators can view but not change delegation permissions."
+msgstr ""
+
+#: src/Module/Settings/Delegation.php:80
+msgid "Delegate user not found."
+msgstr ""
+
+#: src/Module/Settings/Delegation.php:137
+msgid "No parent user"
+msgstr ""
+
+#: src/Module/Settings/Delegation.php:149
+msgid "Parent Password:"
+msgstr ""
+
+#: src/Module/Settings/Delegation.php:149
+msgid ""
+"Please enter the password of the parent account to legitimize your request."
+msgstr ""
+
+#: src/Module/Settings/Delegation.php:154
+msgid "Parent User"
+msgstr ""
+
+#: src/Module/Settings/Delegation.php:157
+msgid ""
+"Parent users have total control about this account, including the account "
+"settings. Please double check whom you give this access."
+msgstr ""
+
+#: src/Module/Settings/Delegation.php:159
+msgid "Delegate Page Management"
+msgstr ""
+
+#: src/Module/Settings/Delegation.php:160
+msgid "Delegates"
+msgstr ""
+
+#: src/Module/Settings/Delegation.php:162
+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 ""
+
+#: src/Module/Settings/Delegation.php:163
+msgid "Existing Page Delegates"
+msgstr ""
+
+#: src/Module/Settings/Delegation.php:165
+msgid "Potential Delegates"
+msgstr ""
+
+#: src/Module/Settings/Delegation.php:168
+msgid "Add"
+msgstr ""
+
+#: src/Module/Settings/Delegation.php:169
+msgid "No entries."
+msgstr ""
+
+#: src/Module/Settings/UserExport.php:44
+msgid "Export account"
+msgstr ""
+
+#: src/Module/Settings/UserExport.php:44
+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 ""
+
+#: src/Module/Settings/UserExport.php:45
+msgid "Export all"
+msgstr ""
+
+#: src/Module/Settings/UserExport.php:45
+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 ""
+
+#: src/Module/Settings/UserExport.php:46
+msgid "Export Contacts to CSV"
+msgstr ""
+
+#: src/Module/Settings/UserExport.php:46
+msgid ""
+"Export the list of the accounts you are following as CSV file. Compatible to "
+"e.g. Mastodon."
+msgstr ""
+
#: src/Module/Special/HTTPException.php:32
msgid "Bad Request"
msgstr ""
msgid "Go back"
msgstr ""
+#: src/Module/TwoFactor/Verify.php:63
+msgid ""
+"<p>Open the two-factor authentication app on your device to get an "
+"authentication code and verify your identity.</p>"
+msgstr ""
+
+#: src/Module/TwoFactor/Verify.php:66 src/Module/TwoFactor/Recovery.php:67
+#, php-format
+msgid ""
+"Don’t have your phone? <a href=\"%s\">Enter a two-factor recovery code</a>"
+msgstr ""
+
+#: src/Module/TwoFactor/Verify.php:68
+msgid "Verify code and complete login"
+msgstr ""
+
#: src/Module/TwoFactor/Recovery.php:41
#, php-format
msgid "Remaining recovery codes: %d"
"to your mobile device.</p>"
msgstr ""
-#: src/Module/TwoFactor/Recovery.php:67 src/Module/TwoFactor/Verify.php:66
-#, php-format
-msgid ""
-"Don’t have your phone? <a href=\"%s\">Enter a two-factor recovery code</a>"
-msgstr ""
-
#: src/Module/TwoFactor/Recovery.php:68
msgid "Please enter a recovery code"
msgstr ""
msgid "Submit recovery code and complete login"
msgstr ""
-#: src/Module/TwoFactor/Verify.php:63
-msgid ""
-"<p>Open the two-factor authentication app on your device to get an "
-"authentication code and verify your identity.</p>"
-msgstr ""
-
-#: src/Module/TwoFactor/Verify.php:68
-msgid "Verify code and complete login"
-msgstr ""
-
#: src/Module/Welcome.php:25
msgid "Welcome to Friendica"
msgstr ""
"features and resources."
msgstr ""
+#: src/Module/AllFriends.php:55
+msgid "No friends to display."
+msgstr ""
+
+#: src/Module/BaseSearchModule.php:54
+#, php-format
+msgid "People Search - %s"
+msgstr ""
+
+#: src/Module/BaseSearchModule.php:64
+#, php-format
+msgid "Forum Search - %s"
+msgstr ""
+
#: src/Module/Bookmarklet.php:35
msgid "This page is missing a url parameter."
msgstr ""
msgid "Contact updated."
msgstr ""
-#: src/Module/Contact.php:355
+#: src/Module/Contact.php:376
msgid "Contact not found"
msgstr ""
-#: src/Module/Contact.php:374
+#: src/Module/Contact.php:395
msgid "Contact has been blocked"
msgstr ""
-#: src/Module/Contact.php:374
+#: src/Module/Contact.php:395
msgid "Contact has been unblocked"
msgstr ""
-#: src/Module/Contact.php:384
+#: src/Module/Contact.php:405
msgid "Contact has been ignored"
msgstr ""
-#: src/Module/Contact.php:384
+#: src/Module/Contact.php:405
msgid "Contact has been unignored"
msgstr ""
-#: src/Module/Contact.php:394
+#: src/Module/Contact.php:415
msgid "Contact has been archived"
msgstr ""
-#: src/Module/Contact.php:394
+#: src/Module/Contact.php:415
msgid "Contact has been unarchived"
msgstr ""
-#: src/Module/Contact.php:418
+#: src/Module/Contact.php:439
msgid "Drop contact"
msgstr ""
-#: src/Module/Contact.php:421 src/Module/Contact.php:798
+#: src/Module/Contact.php:442 src/Module/Contact.php:819
msgid "Do you really want to delete this contact?"
msgstr ""
-#: src/Module/Contact.php:435
+#: src/Module/Contact.php:456
msgid "Contact has been removed."
msgstr ""
-#: src/Module/Contact.php:465
+#: src/Module/Contact.php:486
#, php-format
msgid "You are mutual friends with %s"
msgstr ""
-#: src/Module/Contact.php:470
+#: src/Module/Contact.php:491
#, php-format
msgid "You are sharing with %s"
msgstr ""
-#: src/Module/Contact.php:475
+#: src/Module/Contact.php:496
#, php-format
msgid "%s is sharing with you"
msgstr ""
-#: src/Module/Contact.php:499
+#: src/Module/Contact.php:520
msgid "Private communications are not available for this contact."
msgstr ""
-#: src/Module/Contact.php:501
+#: src/Module/Contact.php:522
msgid "Never"
msgstr ""
-#: src/Module/Contact.php:504
+#: src/Module/Contact.php:525
msgid "(Update was successful)"
msgstr ""
-#: src/Module/Contact.php:504
+#: src/Module/Contact.php:525
msgid "(Update was not successful)"
msgstr ""
-#: src/Module/Contact.php:506 src/Module/Contact.php:1042
+#: src/Module/Contact.php:527 src/Module/Contact.php:1063
msgid "Suggest friends"
msgstr ""
-#: src/Module/Contact.php:510
+#: src/Module/Contact.php:531
#, php-format
msgid "Network type: %s"
msgstr ""
-#: src/Module/Contact.php:515
+#: src/Module/Contact.php:536
msgid "Communications lost with this contact!"
msgstr ""
-#: src/Module/Contact.php:521
+#: src/Module/Contact.php:542
msgid "Fetch further information for feeds"
msgstr ""
-#: src/Module/Contact.php:523
+#: src/Module/Contact.php:544
msgid ""
"Fetch information like preview pictures, title and teaser from the feed "
"item. You can activate this if the feed doesn't contain much text. Keywords "
"are taken from the meta header in the feed item and are posted as hash tags."
msgstr ""
-#: src/Module/Contact.php:526
+#: src/Module/Contact.php:547
msgid "Fetch information"
msgstr ""
-#: src/Module/Contact.php:527
+#: src/Module/Contact.php:548
msgid "Fetch keywords"
msgstr ""
-#: src/Module/Contact.php:528
+#: src/Module/Contact.php:549
msgid "Fetch information and keywords"
msgstr ""
-#: src/Module/Contact.php:547
+#: src/Module/Contact.php:568
msgid "Profile Visibility"
msgstr ""
-#: src/Module/Contact.php:548
+#: src/Module/Contact.php:569
msgid "Contact Information / Notes"
msgstr ""
-#: src/Module/Contact.php:549
+#: src/Module/Contact.php:570
msgid "Contact Settings"
msgstr ""
-#: src/Module/Contact.php:558
+#: src/Module/Contact.php:579
msgid "Contact"
msgstr ""
-#: src/Module/Contact.php:562
+#: src/Module/Contact.php:583
#, php-format
msgid ""
"Please choose the profile you would like to display to %s when viewing your "
"profile securely."
msgstr ""
-#: src/Module/Contact.php:564
+#: src/Module/Contact.php:585
msgid "Their personal note"
msgstr ""
-#: src/Module/Contact.php:566
+#: src/Module/Contact.php:587
msgid "Edit contact notes"
msgstr ""
-#: src/Module/Contact.php:570
+#: src/Module/Contact.php:591
msgid "Block/Unblock contact"
msgstr ""
-#: src/Module/Contact.php:571
+#: src/Module/Contact.php:592
msgid "Ignore contact"
msgstr ""
-#: src/Module/Contact.php:572
+#: src/Module/Contact.php:593
msgid "Repair URL settings"
msgstr ""
-#: src/Module/Contact.php:573
+#: src/Module/Contact.php:594
msgid "View conversations"
msgstr ""
-#: src/Module/Contact.php:578
+#: src/Module/Contact.php:599
msgid "Last update:"
msgstr ""
-#: src/Module/Contact.php:580
+#: src/Module/Contact.php:601
msgid "Update public posts"
msgstr ""
-#: src/Module/Contact.php:582 src/Module/Contact.php:1052
+#: src/Module/Contact.php:603 src/Module/Contact.php:1073
msgid "Update now"
msgstr ""
-#: src/Module/Contact.php:586 src/Module/Contact.php:803
-#: src/Module/Contact.php:1069
+#: src/Module/Contact.php:607 src/Module/Contact.php:824
+#: src/Module/Contact.php:1090
msgid "Unignore"
msgstr ""
-#: src/Module/Contact.php:590
+#: src/Module/Contact.php:611
msgid "Currently blocked"
msgstr ""
-#: src/Module/Contact.php:591
+#: src/Module/Contact.php:612
msgid "Currently ignored"
msgstr ""
-#: src/Module/Contact.php:592
+#: src/Module/Contact.php:613
msgid "Currently archived"
msgstr ""
-#: src/Module/Contact.php:593
+#: src/Module/Contact.php:614
msgid "Awaiting connection acknowledge"
msgstr ""
-#: src/Module/Contact.php:594
+#: src/Module/Contact.php:615
msgid ""
"Replies/likes to your public posts <strong>may</strong> still be visible"
msgstr ""
-#: src/Module/Contact.php:595
+#: src/Module/Contact.php:616
msgid "Notification for new posts"
msgstr ""
-#: src/Module/Contact.php:595
+#: src/Module/Contact.php:616
msgid "Send a notification of every new post of this contact"
msgstr ""
-#: src/Module/Contact.php:597
+#: src/Module/Contact.php:618
msgid "Blacklisted keywords"
msgstr ""
-#: src/Module/Contact.php:597
+#: src/Module/Contact.php:618
msgid ""
"Comma separated list of keywords that should not be converted to hashtags, "
"when \"Fetch information and keywords\" is selected"
msgstr ""
-#: src/Module/Contact.php:663
+#: src/Module/Contact.php:684
msgid "Show all contacts"
msgstr ""
-#: src/Module/Contact.php:668 src/Module/Contact.php:778
+#: src/Module/Contact.php:689 src/Module/Contact.php:799
msgid "Pending"
msgstr ""
-#: src/Module/Contact.php:671
+#: src/Module/Contact.php:692
msgid "Only show pending contacts"
msgstr ""
-#: src/Module/Contact.php:676 src/Module/Contact.php:779
+#: src/Module/Contact.php:697 src/Module/Contact.php:800
msgid "Blocked"
msgstr ""
-#: src/Module/Contact.php:679
+#: src/Module/Contact.php:700
msgid "Only show blocked contacts"
msgstr ""
-#: src/Module/Contact.php:684 src/Module/Contact.php:781
+#: src/Module/Contact.php:705 src/Module/Contact.php:802
msgid "Ignored"
msgstr ""
-#: src/Module/Contact.php:687
+#: src/Module/Contact.php:708
msgid "Only show ignored contacts"
msgstr ""
-#: src/Module/Contact.php:692 src/Module/Contact.php:782
+#: src/Module/Contact.php:713 src/Module/Contact.php:803
msgid "Archived"
msgstr ""
-#: src/Module/Contact.php:695
+#: src/Module/Contact.php:716
msgid "Only show archived contacts"
msgstr ""
-#: src/Module/Contact.php:700 src/Module/Contact.php:780
+#: src/Module/Contact.php:721 src/Module/Contact.php:801
msgid "Hidden"
msgstr ""
-#: src/Module/Contact.php:703
+#: src/Module/Contact.php:724
msgid "Only show hidden contacts"
msgstr ""
-#: src/Module/Contact.php:711
+#: src/Module/Contact.php:732
msgid "Organize your contact groups"
msgstr ""
-#: src/Module/Contact.php:793
+#: src/Module/Contact.php:814
msgid "Search your contacts"
msgstr ""
-#: src/Module/Contact.php:804 src/Module/Contact.php:1078
+#: src/Module/Contact.php:825 src/Module/Contact.php:1099
msgid "Archive"
msgstr ""
-#: src/Module/Contact.php:804 src/Module/Contact.php:1078
+#: src/Module/Contact.php:825 src/Module/Contact.php:1099
msgid "Unarchive"
msgstr ""
-#: src/Module/Contact.php:807
+#: src/Module/Contact.php:828
msgid "Batch Actions"
msgstr ""
-#: src/Module/Contact.php:834
+#: src/Module/Contact.php:855
msgid "Conversations started by this contact"
msgstr ""
-#: src/Module/Contact.php:839
+#: src/Module/Contact.php:860
msgid "Posts and Comments"
msgstr ""
-#: src/Module/Contact.php:862
+#: src/Module/Contact.php:883
msgid "View all contacts"
msgstr ""
-#: src/Module/Contact.php:873
+#: src/Module/Contact.php:894
msgid "View all common friends"
msgstr ""
-#: src/Module/Contact.php:883
+#: src/Module/Contact.php:904
msgid "Advanced Contact Settings"
msgstr ""
-#: src/Module/Contact.php:966
+#: src/Module/Contact.php:987
msgid "Mutual Friendship"
msgstr ""
-#: src/Module/Contact.php:971
+#: src/Module/Contact.php:992
msgid "is a fan of yours"
msgstr ""
-#: src/Module/Contact.php:976
+#: src/Module/Contact.php:997
msgid "you are a fan of"
msgstr ""
-#: src/Module/Contact.php:994
+#: src/Module/Contact.php:1015
msgid "Pending outgoing contact request"
msgstr ""
-#: src/Module/Contact.php:996
+#: src/Module/Contact.php:1017
msgid "Pending incoming contact request"
msgstr ""
-#: src/Module/Contact.php:1009
+#: src/Module/Contact.php:1030
msgid "Edit contact"
msgstr ""
-#: src/Module/Contact.php:1063
+#: src/Module/Contact.php:1084
msgid "Toggle Blocked status"
msgstr ""
-#: src/Module/Contact.php:1071
+#: src/Module/Contact.php:1092
msgid "Toggle Ignored status"
msgstr ""
-#: src/Module/Contact.php:1080
+#: src/Module/Contact.php:1101
msgid "Toggle Archive status"
msgstr ""
-#: src/Module/Contact.php:1088
+#: src/Module/Contact.php:1109
msgid "Delete contact"
msgstr ""
+#: src/Module/Delegation.php:127
+msgid "Manage Identities and/or Pages"
+msgstr ""
+
+#: src/Module/Delegation.php:128
+msgid ""
+"Toggle between different identities or community/group pages which share "
+"your account details or which you have been granted \"manage\" permissions"
+msgstr ""
+
+#: src/Module/Delegation.php:129
+msgid "Select an identity to manage: "
+msgstr ""
+
+#: src/Module/Directory.php:59
+msgid "No entries (some entries may be hidden)."
+msgstr ""
+
+#: src/Module/Directory.php:78
+msgid "Find on this site"
+msgstr ""
+
+#: src/Module/Directory.php:80
+msgid "Results for:"
+msgstr ""
+
+#: src/Module/Directory.php:82
+msgid "Site Directory"
+msgstr ""
+
+#: src/Module/FollowConfirm.php:37
+msgid "No given contact."
+msgstr ""
+
+#: src/Module/HTTPException/MethodNotAllowed.php:13
+msgid "Method Not Allowed."
+msgstr ""
+
+#: src/Module/HTTPException/PageNotFound.php:13 src/App/Router.php:182
+msgid "Page not found."
+msgstr ""
+
+#: src/Module/Home.php:34
+#, php-format
+msgid "Welcome to %s"
+msgstr ""
+
#: src/Module/Install.php:159
msgid "Friendica Communications Server - Setup"
msgstr ""
"administrator email. This will allow you to enter the site admin panel."
msgstr ""
-#: src/Object/Post.php:138
+#: src/Module/Login.php:312
+msgid "Create a New Account"
+msgstr ""
+
+#: src/Module/Login.php:337
+msgid "Your OpenID: "
+msgstr ""
+
+#: src/Module/Login.php:340
+msgid ""
+"Please enter your username and password to add the OpenID to your existing "
+"account."
+msgstr ""
+
+#: src/Module/Login.php:342
+msgid "Or login using OpenID: "
+msgstr ""
+
+#: src/Module/Login.php:356
+msgid "Password: "
+msgstr ""
+
+#: src/Module/Login.php:357
+msgid "Remember me"
+msgstr ""
+
+#: src/Module/Login.php:366
+msgid "Forgot your password?"
+msgstr ""
+
+#: src/Module/Login.php:369
+msgid "Website Terms of Service"
+msgstr ""
+
+#: src/Module/Login.php:370
+msgid "terms of service"
+msgstr ""
+
+#: src/Module/Login.php:372
+msgid "Website Privacy Policy"
+msgstr ""
+
+#: src/Module/Login.php:373
+msgid "privacy policy"
+msgstr ""
+
+#: src/Module/Logout.php:40
+msgid "Logged out."
+msgstr ""
+
+#: src/Module/Register.php:77
+msgid ""
+"You may (optionally) fill in this form via OpenID by supplying your OpenID "
+"and clicking \"Register\"."
+msgstr ""
+
+#: src/Module/Register.php:78
+msgid ""
+"If you are not familiar with OpenID, please leave that field blank and fill "
+"in the rest of the items."
+msgstr ""
+
+#: src/Module/Register.php:79
+msgid "Your OpenID (optional): "
+msgstr ""
+
+#: src/Module/Register.php:88
+msgid "Include your profile in member directory?"
+msgstr ""
+
+#: src/Module/Register.php:111
+msgid "Note for the admin"
+msgstr ""
+
+#: src/Module/Register.php:111
+msgid "Leave a message for the admin, why you want to join this node"
+msgstr ""
+
+#: src/Module/Register.php:112
+msgid "Membership on this site is by invitation only."
+msgstr ""
+
+#: src/Module/Register.php:113
+msgid "Your invitation code: "
+msgstr ""
+
+#: src/Module/Register.php:121
+msgid "Your Full Name (e.g. Joe Smith, real or real-looking): "
+msgstr ""
+
+#: src/Module/Register.php:122
+msgid ""
+"Your Email Address: (Initial information will be send there, so this has to "
+"be an existing address.)"
+msgstr ""
+
+#: src/Module/Register.php:124
+msgid "Leave empty for an auto generated password."
+msgstr ""
+
+#: src/Module/Register.php:126
+#, php-format
+msgid ""
+"Choose a profile nickname. This must begin with a text character. Your "
+"profile address on this site will then be \"<strong>nickname@%s</strong>\"."
+msgstr ""
+
+#: src/Module/Register.php:127
+msgid "Choose a nickname: "
+msgstr ""
+
+#: src/Module/Register.php:136
+msgid "Import your profile to this friendica instance"
+msgstr ""
+
+#: src/Module/Register.php:143
+msgid "Note: This node explicitly contains adult content"
+msgstr ""
+
+#: src/Module/Register.php:238
+msgid ""
+"Registration successful. Please check your email for further instructions."
+msgstr ""
+
+#: src/Module/Register.php:242
+#, 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 ""
+
+#: src/Module/Register.php:248
+msgid "Registration successful."
+msgstr ""
+
+#: src/Module/Register.php:253 src/Module/Register.php:260
+msgid "Your registration can not be processed."
+msgstr ""
+
+#: src/Module/Register.php:259
+msgid "You have to leave a request note for the admin."
+msgstr ""
+
+#: src/Module/Register.php:307
+msgid "Your registration is pending approval by the site owner."
+msgstr ""
+
+#: src/Module/Tos.php:35 src/Module/Tos.php:77
+msgid ""
+"At the time of registration, and for providing communications between the "
+"user account and their contacts, the user has to provide a display name (pen "
+"name), an username (nickname) and a working email address. The names will be "
+"accessible on the profile page of the account by any visitor of the page, "
+"even if other profile details are not displayed. The email address will only "
+"be used to send the user notifications about interactions, but wont be "
+"visibly displayed. The listing of an account in the node's user directory or "
+"the global user directory is optional and can be controlled in the user "
+"settings, it is not necessary for communication."
+msgstr ""
+
+#: src/Module/Tos.php:36 src/Module/Tos.php:78
+msgid ""
+"This data is required for communication and is passed on to the nodes of the "
+"communication partners and is stored there. Users can enter additional "
+"private data that may be transmitted to the communication partners accounts."
+msgstr ""
+
+#: src/Module/Tos.php:37 src/Module/Tos.php:79
+#, php-format
+msgid ""
+"At any point in time a logged in user can export their account data from the "
+"<a href=\"%1$s/settings/userexport\">account settings</a>. If the user wants "
+"to delete their account they can do so at <a href=\"%1$s/removeme\">%1$s/"
+"removeme</a>. The deletion of the account will be permanent. Deletion of the "
+"data will also be requested from the nodes of the communication partners."
+msgstr ""
+
+#: src/Module/Tos.php:40 src/Module/Tos.php:76
+msgid "Privacy Statement"
+msgstr ""
+
+#: src/Object/Post.php:135
msgid "This entry was edited"
msgstr ""
-#: src/Object/Post.php:158
+#: src/Object/Post.php:155
msgid "Private Message"
msgstr ""
-#: src/Object/Post.php:200
+#: src/Object/Post.php:197
msgid "Delete locally"
msgstr ""
-#: src/Object/Post.php:203
+#: src/Object/Post.php:200
msgid "Delete globally"
msgstr ""
-#: src/Object/Post.php:203
+#: src/Object/Post.php:200
msgid "Remove locally"
msgstr ""
-#: src/Object/Post.php:217
+#: src/Object/Post.php:214
msgid "save to folder"
msgstr ""
-#: src/Object/Post.php:252
+#: src/Object/Post.php:249
msgid "I will attend"
msgstr ""
-#: src/Object/Post.php:252
+#: src/Object/Post.php:249
msgid "I will not attend"
msgstr ""
-#: src/Object/Post.php:252
+#: src/Object/Post.php:249
msgid "I might attend"
msgstr ""
-#: src/Object/Post.php:280
+#: src/Object/Post.php:277
msgid "ignore thread"
msgstr ""
-#: src/Object/Post.php:281
+#: src/Object/Post.php:278
msgid "unignore thread"
msgstr ""
-#: src/Object/Post.php:282
+#: src/Object/Post.php:279
msgid "toggle ignore status"
msgstr ""
-#: src/Object/Post.php:293
+#: src/Object/Post.php:290
msgid "add star"
msgstr ""
-#: src/Object/Post.php:294
+#: src/Object/Post.php:291
msgid "remove star"
msgstr ""
-#: src/Object/Post.php:295
+#: src/Object/Post.php:292
msgid "toggle star status"
msgstr ""
-#: src/Object/Post.php:298
+#: src/Object/Post.php:295
msgid "starred"
msgstr ""
-#: src/Object/Post.php:302
+#: src/Object/Post.php:299
msgid "add tag"
msgstr ""
-#: src/Object/Post.php:313
+#: src/Object/Post.php:310
msgid "like"
msgstr ""
-#: src/Object/Post.php:314
+#: src/Object/Post.php:311
msgid "dislike"
msgstr ""
-#: src/Object/Post.php:317
+#: src/Object/Post.php:314
msgid "Share this"
msgstr ""
-#: src/Object/Post.php:317
+#: src/Object/Post.php:314
msgid "share"
msgstr ""
msgid "toggle mobile"
msgstr ""
-#: src/LegacyModule.php:30
+#: src/App/Router.php:180
#, php-format
-msgid "Legacy module file not found: %s"
+msgid "Method not allowed for this module. Allowed method(s): %s"
msgstr ""
-#: src/BaseModule.php:135
-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."
+#: src/LegacyModule.php:30
+#, php-format
+msgid "Legacy module file not found: %s"
msgstr ""
#: src/Console/ArchiveContact.php:86
msgid "All pending post updates are done."
msgstr ""
-#: src/App.php:485
+#: src/App.php:519
msgid "No system theme config value set."
msgstr ""
+#: src/BaseModule.php:134
+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 ""
+
#: update.php:218
#, php-format
msgid "%s: Updating author-id and owner-id in item and thread table. "
{{if $profile.actions.network}}<a class="btn btn-labeled btn-primary btn-sm" href="{{$profile.actions.network.1}}" aria-label="{{$profile.actions.network.0}}" title="{{$profile.actions.network.0}}"><i class="fa fa-cloud" aria-hidden="true"></i></a>{{/if}}
{{if $profile.actions.edit}}<a class="btn btn-labeled btn-primary btn-sm" href="{{$profile.actions.edit.1}}" aria-label="{{$profile.actions.edit.0}}" title="{{$profile.actions.edit.0}}"><i class="fa fa-user" aria-hidden="true"></i></a>{{/if}}
{{if $profile.actions.follow}}<a class="btn btn-labeled btn-primary btn-sm" href="{{$profile.actions.follow.1}}" aria-label="{{$profile.actions.follow.0}}" title="{{$profile.actions.follow.0}}"><i class="fa fa-user-plus" aria-hidden="true"></i></a>{{/if}}
+ {{if $profile.actions.unfollow}}<a class="btn btn-labeled btn-primary btn-sm" href="{{$profile.actions.unfollow.1}}" aria-label="{{$profile.actions.unfollow.0}}" title="{{$profile.actions.unfollow.0}}"><i class="fa fa-user-times" aria-hidden="true"></i></a>{{/if}}
</div>
</div>
</div>
{{if $permonly}}
{{include file="field_textarea.tpl" field=$permonlybox}}
+ <input type="input" id="registertarpit" style="display: none;" placeholder="Don't enter anything here" />
{{/if}}
{{$publish nofilter}}
{{$nickname_block nofilter}}
-<form action="settings" id="settings-form" method="post" autocomplete="off" >
+<form action="settings" id="settings-form" method="post" autocomplete="off" enctype="multipart/form-data" >
<input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
<h3 class="settings-heading"><a href="javascript:;">{{$h_pass}}</a></h3>
</div>
</div>
+<h3 class="settings-heading"><a href="javascript:;">{{$importcontact}}</a></h3>
+<div class="settings-content-block">
+<input type="hidden" name="MAX_FILE_SIZE" value="{{$importcontact_maxsize}}" />
+<div id="settings-pagetype-desc">{{$importcontact_text}}</div>
+<input type="file" name="importcontact-filename" />
+
+<div class="settings-submit-wrapper" >
+<input type="submit" name="importcontact-submit" class="importcontact-submit" value="{{$importcontact_button}}" />
+</div>
+</div>
+
<h3 class="settings-heading"><a href="javascript:;">{{$relocate}}</a></h3>
<div class="settings-content-block">
<div id="settings-pagetype-desc">{{$relocate_text}}</div>
--- /dev/null
+
+<h3>{{$title}}</h3>
+
+
+{{foreach $options as $o}}
+<dl>
+ <dt><a href="{{$o.0}}">{{$o.1}}</a></dt>
+ <dd>{{$o.2}}</dd>
+</dl>
+{{/foreach}}
</div>
<div class="wall-item-author">
<a href="{{$item.profile_url}}" target="redir" title="{{$item.linktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.sparkle}}" id="wall-item-name-{{$item.id}}" >{{$item.name}}</span></a>{{if $item.owner_url}} {{$item.to}} <a href="{{$item.owner_url}}" target="redir" title="{{$item.olinktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}">{{$item.owner_name}}</span></a> {{$item.vwall}}{{/if}}<br />
- <div class="wall-item-ago" id="wall-item-ago-{{$item.id}}" title="{{$item.localtime}}"><time class="dt-published" datetime="{{$item.localtime}}">{{$item.ago}}</time></div>
+ <div class="wall-item-ago" id="wall-item-ago-{{$item.id}}" title="{{$item.localtime}}"><time class="dt-published" datetime="{{$item.localtime}}">{{$item.ago}}</time><span class="pinned">{{$item.pinned}}</span></div>
</div>
<div class="wall-item-content" id="wall-item-content-{{$item.id}}" >
<div class="wall-item-title p-name" id="wall-item-title-{{$item.id}}">{{$item.title}}</div>
{{/if}}
</div>
{{if $item.has_cats}}
- <div class="categorytags"><span>{{$item.txt_cats}} {{foreach $item.categories as $cat}}<span class="p-category">{{$cat.name}}</span>{{if $cat.removeurl}} <a href="{{$cat.removeurl}}" title="{{$remove}}">[{{$remove}}]</a>{{/if}} {{if $cat.last}}{{else}}, {{/if}}{{/foreach}}
+ <div class="categorytags"><span>{{$item.txt_cats}} {{foreach $item.categories as $cat}}<span class="p-category"><a href="{{$cat.url}}">{{$cat.name}}</a></span>{{if $cat.removeurl}} <a href="{{$cat.removeurl}}" title="{{$remove}}">[{{$remove}}]</a>{{/if}} {{if $cat.last}}{{else}}, {{/if}}{{/foreach}}
</div>
{{/if}}
<a class="editpost icon pencil" href="{{$item.edpost.0}}" title="{{$item.edpost.1}}"></a>
{{/if}}
+ {{if $item.pin}}
+ <a href="#" id="pinned-{{$item.id}}" onclick="dopin({{$item.id}}); return false;" class="pin-item icon {{$item.ispinned}}" title="{{$item.pin.toggle}}"></a>
+ {{/if}}
{{if $item.star}}
<a href="#" id="starred-{{$item.id}}" onclick="dostar({{$item.id}}); return false;" class="star-item icon {{$item.isstarred}}" title="{{$item.star.toggle}}"></a>
{{/if}}
margin-left: 10px;
float: left;
}
+.pin-item {
+ margin-left: 10px;
+ float: left;
+}
.star-item {
margin-left: 10px;
float: left;
.on { background-position: -144px -32px; }
.off { background-position: 0px -48px; }
+.pinned { background-position: -16px -48px; }
+.unpinned { background-position: -32px -48px; }
.starred { background-position: -16px -48px; }
.unstarred { background-position: -32px -48px; }
.tagged { background-position: -48px -48px; }
font-size: 14px;
}
+/* Contact avatar click card */
+.userinfo.click-card {
+ position: relative;
+}
+
+.userinfo.click-card > *:hover:after {
+ content: '⌄';
+ color: #bebebe;
+ font-size: 1em;
+ font-weight: bold;
+ background-color: #ffffff;
+ text-align: center;
+ line-height: 40%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 33%;
+ height: 33%;
+ opacity: .8;
+ border-radius: 0 0 40% 0;
+}
+
/* The lock symbol popup */
#panel {
position: absolute;
+++ /dev/null
-/*!
- * jSmart Javascript template engine
- * https://github.com/umakantp/jsmart
- *
- * Copyright 2011-2015, Max Miroshnikov <miroshnikov at gmail dot com>
- * Umakant Patil <me at umakantpatil dot.com>
- * jSmart is licensed under the GNU Lesser General Public License
- * http://opensource.org/licenses/LGPL-3.0
- */
-
-
-(function() {
-
- /**
- merges two or more objects into one
- shallow copy for objects
- */
- function obMerge(ob1, ob2 /*, ...*/)
- {
- for (var i=1; i<arguments.length; ++i)
- {
- for (var nm in arguments[i])
- {
- ob1[nm] = arguments[i][nm];
- }
- }
- return ob1;
- }
-
- /**
- @return number of own properties in ob
- */
- function countProperties(ob)
- {
- var count = 0;
- for (var nm in ob)
- {
- if (ob.hasOwnProperty(nm))
- {
- count++;
- }
- }
- return count;
- }
-
- /**
- IE workaround
- */
- function findInArray(a, v)
- {
- if (Array.prototype.indexOf) {
- return a.indexOf(v);
- }
- for (var i=0; i < a.length; ++i)
- {
- if (a[i] === v)
- {
- return i;
- }
- }
- return -1;
- }
-
- function evalString(s)
- {
- return s.replace(/\\t/,'\t').replace(/\\n/,'\n').replace(/\\(['"\\])/g,'$1');
- }
-
- /**
- @return s trimmed and without quotes
- */
- function trimQuotes(s)
- {
- return evalString(s.replace(/^['"](.*)['"]$/,'$1')).replace(/^\s+|\s+$/g,'');
- }
-
- /**
- finds first {tag} in string
- @param re string with regular expression or an empty string to find any tag
- @return null or s.match(re) result object where
- [0] - full tag matched with delimiters (and whitespaces at the begin and the end): { tag }
- [1] - found part from passed re
- [index] - position of tag starting { in s
- */
- function findTag(re,s)
- {
- var openCount = 0;
- var offset = 0;
- var ldelim = jSmart.prototype.left_delimiter;
- var rdelim = jSmart.prototype.right_delimiter;
- var skipInWS = jSmart.prototype.auto_literal;
-
- var reAny = /^\s*(.+)\s*$/i;
- var reTag = re ? new RegExp('^\\s*('+re+')\\s*$','i') : reAny;
-
- for (var i=0; i<s.length; ++i)
- {
- if (s.substr(i,ldelim.length) == ldelim)
- {
- if (skipInWS && i+1 < s.length && s.substr(i+1,1).match(/\s/))
- {
- continue;
- }
- if (!openCount)
- {
- s = s.slice(i);
- offset += parseInt(i);
- i = 0;
- }
- ++openCount;
- }
- else if (s.substr(i,rdelim.length) == rdelim)
- {
- if (skipInWS && i-1 >= 0 && s.substr(i-1,1).match(/\s/))
- {
- continue;
- }
- if (!--openCount)
- {
- var sTag = s.slice(ldelim.length,i).replace(/[\r\n]/g, ' ');
- var found = sTag.match(reTag);
- if (found)
- {
- found.index = offset;
- found[0] = s.slice(0,i+rdelim.length);
- return found;
- }
- }
- if (openCount < 0) //ignore any number of unmatched right delimiters
- {
- openCount = 0;
- }
- }
- }
- return null;
- }
-
- function findCloseTag(reClose,reOpen,s)
- {
- var sInner = '';
- var closeTag = null;
- var openTag = null;
- var findIndex = 0;
-
- do
- {
- if (closeTag)
- {
- findIndex += closeTag[0].length;
- }
- closeTag = findTag(reClose,s);
- if (!closeTag)
- {
- throw new Error('Unclosed {'+reOpen+'}');
- }
- sInner += s.slice(0,closeTag.index);
- findIndex += closeTag.index;
- s = s.slice(closeTag.index+closeTag[0].length);
-
- openTag = findTag(reOpen,sInner);
- if (openTag)
- {
- sInner = sInner.slice(openTag.index+openTag[0].length);
- }
- }
- while (openTag);
-
- closeTag.index = findIndex;
- return closeTag;
- }
-
- function findElseTag(reOpen, reClose, reElse, s)
- {
- var offset = 0;
- for (var elseTag=findTag(reElse,s); elseTag; elseTag=findTag(reElse,s))
- {
- var openTag = findTag(reOpen,s);
- if (!openTag || openTag.index > elseTag.index)
- {
- elseTag.index += offset;
- return elseTag;
- }
- else
- {
- s = s.slice(openTag.index+openTag[0].length);
- offset += openTag.index+openTag[0].length;
- var closeTag = findCloseTag(reClose,reOpen,s);
- s = s.slice(closeTag.index + closeTag[0].length);
- offset += closeTag.index + closeTag[0].length;
- }
- }
- return null;
- }
-
- function execute(code, data)
- {
- if (typeof(code) == 'string')
- {
- with ({'__code':code})
- {
- with (modifiers)
- {
- with (data)
- {
- try {
- return eval(__code);
- }
- catch(e)
- {
- throw new Error(e.message + ' in \n' + code);
- }
- }
- }
- }
- }
- return code;
- }
-
- /**
- * Execute function when we have a object.
- *
- * @param object obj Object of the function to be called.
- * @param array args Arguments to pass to a function.
- *
- * @return
- * @throws Error If function obj does not exists.
- */
- function executeByFuncObject(obj, args) {
- try {
- return obj.apply(this, args);
- } catch (e) {
- throw new Error(e.message);
- }
- }
-
- function assignVar(nm, val, data)
- {
- if (nm.match(/\[\]$/)) //ar[] =
- {
- data[ nm.replace(/\[\]$/,'') ].push(val);
- }
- else
- {
- data[nm] = val;
- }
- }
-
- var buildInFunctions =
- {
- expression:
- {
- parse: function(s, tree)
- {
- var e = parseExpression(s);
-
- tree.push({
- type: 'build-in',
- name: 'expression',
- expression: e.tree,
- params: parseParams(s.slice(e.value.length).replace(/^\s+|\s+$/g,''))
- });
-
- return e.tree;
-
- },
- process: function(node, data)
- {
- var params = getActualParamValues(node.params, data);
- var res = process([node.expression],data);
-
- if (findInArray(params, 'nofilter') < 0)
- {
- for (var i=0; i<default_modifiers.length; ++i)
- {
- var m = default_modifiers[i];
- m.params.__parsed[0] = {type:'text', data:res};
- res = process([m],data);
- }
- if (escape_html)
- {
- res = modifiers.escape(res);
- }
- res = applyFilters(varFilters,res);
-
- if (tpl_modifiers.length) {
- __t = function(){ return res; }
- res = process(tpl_modifiers,data);
- }
- }
- return res;
- }
- },
-
- operator:
- {
- process: function(node, data)
- {
- var params = getActualParamValues(node.params, data);
- var arg1 = params[0];
-
- if (node.optype == 'binary')
- {
- var arg2 = params[1];
- if (node.op == '=')
- {
- getVarValue(node.params.__parsed[0], data, arg2);
- return '';
- }
- else if (node.op.match(/(\+=|-=|\*=|\/=|%=)/))
- {
- arg1 = getVarValue(node.params.__parsed[0], data);
- switch (node.op)
- {
- case '+=': arg1+=arg2; break;
- case '-=': arg1-=arg2; break;
- case '*=': arg1*=arg2; break;
- case '/=': arg1/=arg2; break;
- case '%=': arg1%=arg2; break;
- }
- return getVarValue(node.params.__parsed[0], data, arg1);
- }
- else if (node.op.match(/div/))
- {
- return (node.op!='div')^(arg1%arg2==0);
- }
- else if (node.op.match(/even/))
- {
- return (node.op!='even')^((arg1/arg2)%2==0);
- }
- else if (node.op.match(/xor/))
- {
- return (arg1||arg2) && !(arg1&&arg2);
- }
-
- switch (node.op)
- {
- case '==': return arg1==arg2;
- case '!=': return arg1!=arg2;
- case '+': return Number(arg1)+Number(arg2);
- case '-': return Number(arg1)-Number(arg2);
- case '*': return Number(arg1)*Number(arg2);
- case '/': return Number(arg1)/Number(arg2);
- case '%': return Number(arg1)%Number(arg2);
- case '&&': return arg1&&arg2;
- case '||': return arg1||arg2;
- case '<': return arg1<arg2;
- case '<=': return arg1<=arg2;
- case '>': return arg1>arg2;
- case '>=': return arg1>=arg2;
- case '===': return arg1===arg2;
- case '!==': return arg1!==arg2;
- }
- }
- else if (node.op == '!')
- {
- return !arg1;
- }
- else
- {
- var isVar = node.params.__parsed[0].type == 'var';
- if (isVar)
- {
- arg1 = getVarValue(node.params.__parsed[0], data);
- }
- var v = arg1;
- if (node.optype == 'pre-unary')
- {
- switch (node.op)
- {
- case '-': v=-arg1; break;
- case '++': v=++arg1; break;
- case '--': v=--arg1; break;
- }
- if (isVar)
- {
- getVarValue(node.params.__parsed[0], data, arg1);
- }
- }
- else
- {
- switch (node.op)
- {
- case '++': arg1++; break;
- case '--': arg1--; break;
- }
- getVarValue(node.params.__parsed[0], data, arg1);
- }
- return v;
- }
- }
- },
-
- section:
- {
- type: 'block',
- parse: function(params, tree, content)
- {
- var subTree = [];
- var subTreeElse = [];
- tree.push({
- type: 'build-in',
- name: 'section',
- params: params,
- subTree: subTree,
- subTreeElse: subTreeElse
- });
-
- var findElse = findElseTag('section [^}]+', '\/section', 'sectionelse', content);
- if (findElse)
- {
- parse(content.slice(0,findElse.index),subTree);
- parse(content.slice(findElse.index+findElse[0].length).replace(/^[\r\n]/,''), subTreeElse);
- }
- else
- {
- parse(content, subTree);
- }
- },
-
- process: function(node, data)
- {
- var params = getActualParamValues(node.params, data);
-
- var props = {};
- data.smarty.section[params.__get('name',null,0)] = props;
-
- var show = params.__get('show',true);
- props.show = show;
- if (!show)
- {
- return process(node.subTreeElse, data);
- }
-
- var from = parseInt(params.__get('start',0));
- var to = (params.loop instanceof Object) ? countProperties(params.loop) : isNaN(params.loop) ? 0 : parseInt(params.loop);
- var step = parseInt(params.__get('step',1));
- var max = parseInt(params.__get('max'));
- if (isNaN(max))
- {
- max = Number.MAX_VALUE;
- }
-
- if (from < 0)
- {
- from += to;
- if (from < 0)
- {
- from = 0;
- }
- }
- else if (from >= to)
- {
- from = to ? to-1 : 0;
- }
-
- var count = 0;
- var loop = 0;
- var i = from;
- for (; i>=0 && i<to && count<max; i+=step,++count)
- {
- loop = i;
- }
- props.total = count;
- props.loop = count; //? - because it is so in Smarty
-
- count = 0;
- var s = '';
- for (i=from; i>=0 && i<to && count<max; i+=step,++count)
- {
- if (data.smarty['break'])
- {
- break;
- }
-
- props.first = (i==from);
- props.last = ((i+step)<0 || (i+step)>=to);
- props.index = i;
- props.index_prev = i-step;
- props.index_next = i+step;
- props.iteration = props.rownum = count+1;
-
- s += process(node.subTree, data);
- data.smarty['continue'] = false;
- }
- data.smarty['break'] = false;
-
- if (count)
- {
- return s;
- }
- return process(node.subTreeElse, data);
- }
- },
-
- setfilter:
- {
- type: 'block',
- parseParams: function(paramStr)
- {
- return [parseExpression('__t()|' + paramStr).tree];
- },
-
- parse: function(params, tree, content)
- {
- tree.push({
- type: 'build-in',
- name: 'setfilter',
- params: params,
- subTree: parse(content,[])
- });
- },
-
- process: function(node, data)
- {
- tpl_modifiers = node.params;
- var s = process(node.subTree, data);
- tpl_modifiers = [];
- return s;
- }
- },
-
- 'for':
- {
- type: 'block',
- parseParams: function(paramStr)
- {
- var res = paramStr.match(/^\s*\$(\w+)\s*=\s*([^\s]+)\s*to\s*([^\s]+)\s*(?:step\s*([^\s]+))?\s*(.*)$/);
- if (!res)
- {
- throw new Error('Invalid {for} parameters: '+paramStr);
- }
- return parseParams("varName='"+res[1]+"' from="+res[2]+" to="+res[3]+" step="+(res[4]?res[4]:'1')+" "+res[5]);
- },
-
- parse: function(params, tree, content)
- {
- var subTree = [];
- var subTreeElse = [];
- tree.push({
- type: 'build-in',
- name: 'for',
- params: params,
- subTree: subTree,
- subTreeElse: subTreeElse
- });
-
- var findElse = findElseTag('for\\s[^}]+', '\/for', 'forelse', content);
- if (findElse)
- {
- parse(content.slice(0,findElse.index),subTree);
- parse(content.slice(findElse.index+findElse[0].length), subTreeElse);
- }
- else
- {
- parse(content, subTree);
- }
- },
-
- process: function(node, data)
- {
- var params = getActualParamValues(node.params, data);
- var from = parseInt(params.__get('from'));
- var to = parseInt(params.__get('to'));
- var step = parseInt(params.__get('step'));
- if (isNaN(step))
- {
- step = 1;
- }
- var max = parseInt(params.__get('max'));
- if (isNaN(max))
- {
- max = Number.MAX_VALUE;
- }
-
- var count = 0;
- var s = '';
- var total = Math.min( Math.ceil( ((step > 0 ? to-from : from-to)+1) / Math.abs(step) ), max);
-
- for (var i=parseInt(params.from); count<total; i+=step,++count)
- {
- if (data.smarty['break'])
- {
- break;
- }
- data[params.varName] = i;
- s += process(node.subTree, data);
- data.smarty['continue'] = false;
- }
- data.smarty['break'] = false;
-
- if (!count)
- {
- s = process(node.subTreeElse, data);
- }
- return s;
- }
- },
-
- 'if':
- {
- type: 'block',
- parse: function(params, tree, content)
- {
- var subTreeIf = [];
- var subTreeElse = [];
- tree.push({
- type: 'build-in',
- name: 'if',
- params: params,
- subTreeIf: subTreeIf,
- subTreeElse: subTreeElse
- });
-
- var findElse = findElseTag('if\\s+[^}]+', '\/if', 'else[^}]*', content);
- if (findElse)
- {
- parse(content.slice(0,findElse.index),subTreeIf);
-
- content = content.slice(findElse.index+findElse[0].length);
- var findElseIf = findElse[1].match(/^else\s*if(.*)/);
- if (findElseIf)
- {
- buildInFunctions['if'].parse(parseParams(findElseIf[1]), subTreeElse, content.replace(/^\n/,''));
- }
- else
- {
- parse(content.replace(/^\n/,''), subTreeElse);
- }
- }
- else
- {
- parse(content, subTreeIf);
- }
- },
-
- process: function(node, data) {
- var value = getActualParamValues(node.params,data)[0];
- // Zero length arrays or empty associative arrays are false in PHP.
- if (value && !((value instanceof Array && value.length == 0)
- || (typeof value == 'object' && isEmptyObject(value)))
- ) {
- return process(node.subTreeIf, data);
- } else {
- return process(node.subTreeElse, data);
- }
- }
- },
-
- foreach:
- {
- type: 'block',
- parseParams: function(paramStr)
- {
- var params = {};
- var res = paramStr.match(/^\s*([$].+)\s*as\s*[$](\w+)\s*(=>\s*[$](\w+))?\s*$/i);
- if (res) //Smarty 3.x syntax => Smarty 2.x syntax
- {
- paramStr = 'from='+res[1] + ' item='+(res[4]||res[2]);
- if (res[4])
- {
- paramStr += ' key='+res[2];
- }
- }
- return parseParams(paramStr);
- },
-
- parse: function(params, tree, content)
- {
- var subTree = [];
- var subTreeElse = [];
- tree.push({
- type: 'build-in',
- name: 'foreach',
- params: params,
- subTree: subTree,
- subTreeElse: subTreeElse
- });
-
- var findElse = findElseTag('foreach\\s[^}]+', '\/foreach', 'foreachelse', content);
- if (findElse)
- {
- parse(content.slice(0,findElse.index),subTree);
- parse(content.slice(findElse.index+findElse[0].length).replace(/^[\r\n]/,''), subTreeElse);
- }
- else
- {
- parse(content, subTree);
- }
- },
-
- process: function(node, data)
- {
- var params = getActualParamValues(node.params, data);
- var a = params.from;
- if (typeof a == 'undefined')
- {
- a = [];
- }
- if (typeof a != 'object')
- {
- a = [a];
- }
-
- var total = countProperties(a);
-
- data[params.item+'__total'] = total;
- if ('name' in params)
- {
- data.smarty.foreach[params.name] = {};
- data.smarty.foreach[params.name].total = total;
- }
-
- var s = '';
- var i=0;
- for (var key in a)
- {
- if (!a.hasOwnProperty(key))
- {
- continue;
- }
-
- if (data.smarty['break'])
- {
- break;
- }
-
- data[params.item+'__key'] = isNaN(key) ? key : parseInt(key);
- if ('key' in params)
- {
- data[params.key] = data[params.item+'__key'];
- }
- data[params.item] = a[key];
- data[params.item+'__index'] = parseInt(i);
- data[params.item+'__iteration'] = parseInt(i+1);
- data[params.item+'__first'] = (i===0);
- data[params.item+'__last'] = (i==total-1);
-
- if ('name' in params)
- {
- data.smarty.foreach[params.name].index = parseInt(i);
- data.smarty.foreach[params.name].iteration = parseInt(i+1);
- data.smarty.foreach[params.name].first = (i===0) ? 1 : '';
- data.smarty.foreach[params.name].last = (i==total-1) ? 1 : '';
- }
-
- ++i;
-
- s += process(node.subTree, data);
- data.smarty['continue'] = false;
- }
- data.smarty['break'] = false;
-
- data[params.item+'__show'] = (i>0);
- if (params.name)
- {
- data.smarty.foreach[params.name].show = (i>0) ? 1 : '';
- }
- if (i>0)
- {
- return s;
- }
- return process(node.subTreeElse, data);
- }
- },
-
- 'function':
- {
- type: 'block',
- parse: function(params, tree, content)
- {
- var subTree = [];
- plugins[trimQuotes(params.name?params.name:params[0])] =
- {
- type: 'function',
- subTree: subTree,
- defautParams: params,
- process: function(params, data)
- {
- var defaults = getActualParamValues(this.defautParams,data);
- delete defaults.name;
- return process(this.subTree, obMerge({},data,defaults,params));
- }
- };
- parse(content, subTree);
- }
- },
-
- php:
- {
- type: 'block',
- parse: function(params, tree, content) {}
- },
-
- 'extends':
- {
- type: 'function',
- parse: function(params, tree)
- {
- tree.splice(0,tree.length);
- getTemplate(trimQuotes(params.file?params.file:params[0]),tree);
- }
- },
-
- block:
- {
- type: 'block',
- parse: function(params, tree, content)
- {
- tree.push({
- type: 'build-in',
- name: 'block',
- params: params
- });
- params.append = findInArray(params,'append') >= 0;
- params.prepend = findInArray(params,'prepend') >= 0;
- params.hide = findInArray(params,'hide') >= 0;
- params.hasChild = params.hasParent = false;
-
- onParseVar = function(nm)
- {
- if (nm.match(/^\s*[$]smarty.block.child\s*$/))
- {
- params.hasChild = true;
- }
- if (nm.match(/^\s*[$]smarty.block.parent\s*$/))
- {
- params.hasParent = true;
- }
- }
- var tree = parse(content, []);
- onParseVar = function(nm) {}
-
- var blockName = trimQuotes(params.name?params.name:params[0]);
- if (!(blockName in blocks))
- {
- blocks[blockName] = [];
- }
- blocks[blockName].push({tree:tree, params:params});
- },
-
- process: function(node, data)
- {
- data.smarty.block.parent = data.smarty.block.child = '';
- var blockName = trimQuotes(node.params.name?node.params.name:node.params[0]);
- this.processBlocks(blocks[blockName], blocks[blockName].length-1, data);
- return data.smarty.block.child;
- },
-
- processBlocks: function(blockAncestry, i, data)
- {
- if (!i && blockAncestry[i].params.hide) {
- data.smarty.block.child = '';
- return;
- }
- var append = true;
- var prepend = false;
- for (; i>=0; --i)
- {
- if (blockAncestry[i].params.hasParent)
- {
- var tmpChild = data.smarty.block.child;
- data.smarty.block.child = '';
- this.processBlocks(blockAncestry, i-1, data);
- data.smarty.block.parent = data.smarty.block.child;
- data.smarty.block.child = tmpChild;
- }
-
- var tmpChild = data.smarty.block.child;
- var s = process(blockAncestry[i].tree, data);
- data.smarty.block.child = tmpChild;
-
- if (blockAncestry[i].params.hasChild)
- {
- data.smarty.block.child = s;
- }
- else if (append)
- {
- data.smarty.block.child = s + data.smarty.block.child;
- }
- else if (prepend)
- {
- data.smarty.block.child += s;
- }
- append = blockAncestry[i].params.append;
- prepend = blockAncestry[i].params.prepend;
- }
- }
- },
-
- strip:
- {
- type: 'block',
- parse: function(params, tree, content)
- {
- parse(content.replace(/[ \t]*[\r\n]+[ \t]*/g, ''), tree);
- }
- },
-
- literal:
- {
- type: 'block',
- parse: function(params, tree, content)
- {
- parseText(content, tree);
- }
- },
-
- ldelim:
- {
- type: 'function',
- parse: function(params, tree)
- {
- parseText(jSmart.prototype.left_delimiter, tree);
- }
- },
-
- rdelim:
- {
- type: 'function',
- parse: function(params, tree)
- {
- parseText(jSmart.prototype.right_delimiter, tree);
- }
- },
-
- 'while':
- {
- type: 'block',
- parse: function(params, tree, content)
- {
- tree.push({
- type: 'build-in',
- name: 'while',
- params: params,
- subTree: parse(content, [])
- });
- },
-
- process: function(node, data)
- {
- var s = '';
- while (getActualParamValues(node.params,data)[0])
- {
- if (data.smarty['break'])
- {
- break;
- }
- s += process(node.subTree, data);
- data.smarty['continue'] = false;
- }
- data.smarty['break'] = false;
- return s;
- }
- }
- };
-
- var plugins = {};
- var modifiers = {};
- var files = {};
- var blocks = null;
- var scripts = null;
- var tpl_modifiers = [];
-
- function parse(s, tree)
- {
- for (var openTag=findTag('',s); openTag; openTag=findTag('',s))
- {
- if (openTag.index)
- {
- parseText(s.slice(0,openTag.index),tree);
- }
- s = s.slice(openTag.index + openTag[0].length);
-
- var res = openTag[1].match(/^\s*(\w+)(.*)$/);
- if (res) //function
- {
- var nm = res[1];
- var paramStr = (res.length>2) ? res[2].replace(/^\s+|\s+$/g,'') : '';
-
- if (nm in buildInFunctions)
- {
- var buildIn = buildInFunctions[nm];
- var params = ('parseParams' in buildIn ? buildIn.parseParams : parseParams)(paramStr);
- if (buildIn.type == 'block')
- {
- s = s.replace(/^\n/,''); //remove new line after block open tag (like in Smarty)
- var closeTag = findCloseTag('\/'+nm, nm+' +[^}]*', s);
- buildIn.parse(params, tree, s.slice(0,closeTag.index));
- s = s.slice(closeTag.index+closeTag[0].length);
- }
- else
- {
- buildIn.parse(params, tree);
- if (nm == 'extends')
- {
- tree = []; //throw away further parsing except for {block}
- }
- }
- s = s.replace(/^\n/,'');
- }
- else if (nm in plugins)
- {
- var plugin = plugins[nm];
- if (plugin.type == 'block')
- {
- var closeTag = findCloseTag('\/'+nm, nm+' +[^}]*', s);
- parsePluginBlock(nm, parseParams(paramStr), tree, s.slice(0,closeTag.index));
- s = s.slice(closeTag.index+closeTag[0].length);
- }
- else if (plugin.type == 'function')
- {
- parsePluginFunc(nm, parseParams(paramStr), tree);
- }
- if (nm=='append' || nm=='assign' || nm=='capture' || nm=='eval' || nm=='include')
- {
- s = s.replace(/^\n/,'');
- }
- }
- else //variable
- {
- buildInFunctions.expression.parse(openTag[1],tree);
- }
- }
- else //variable
- {
- var node = buildInFunctions.expression.parse(openTag[1],tree);
- if (node.type=='build-in' && node.name=='operator' && node.op == '=')
- {
- s = s.replace(/^\n/,'');
- }
- }
- }
- if (s)
- {
- parseText(s, tree);
- }
- return tree;
- }
-
- function parseText(text, tree)
- {
- if (parseText.parseEmbeddedVars)
- {
- var re = /([$][\w@]+)|`([^`]*)`/;
- for (var found=re.exec(text); found; found=re.exec(text))
- {
- tree.push({type: 'text', data: text.slice(0,found.index)});
- tree.push( parseExpression(found[1] ? found[1] : found[2]).tree );
- text = text.slice(found.index + found[0].length);
- }
- }
- tree.push({type: 'text', data: text});
- return tree;
- }
-
- function parseFunc(name, params, tree)
- {
- params.__parsed.name = parseText(name,[])[0];
- tree.push({
- type: 'plugin',
- name: '__func',
- params: params
- });
- return tree;
- }
-
- function parseOperator(op, type, precedence, tree)
- {
- tree.push({
- type: 'build-in',
- name: 'operator',
- op: op,
- optype: type,
- precedence: precedence,
- params: {}
- });
- }
-
- function parseVar(s, e, nm)
- {
- var rootName = e.token;
- var parts = [{type:'text', data:nm.replace(/^(\w+)@(key|index|iteration|first|last|show|total)/gi, "$1__$2")}];
-
- var re = /^(?:\.|\s*->\s*|\[\s*)/;
- for (var op=s.match(re); op; op=s.match(re))
- {
- e.token += op[0];
- s = s.slice(op[0].length);
-
- var eProp = {value:'', tree:[]};
- if (op[0].match(/\[/))
- {
- eProp = parseExpression(s);
- if (eProp)
- {
- e.token += eProp.value;
- parts.push( eProp.tree );
- s = s.slice(eProp.value.length);
- }
-
- var closeOp = s.match(/\s*\]/);
- if (closeOp)
- {
- e.token += closeOp[0];
- s = s.slice(closeOp[0].length);
- }
- }
- else
- {
- var parseMod = parseModifiers.stop;
- parseModifiers.stop = true;
- if (lookUp(s,eProp))
- {
- e.token += eProp.value;
- var part = eProp.tree[0];
- if (part.type == 'plugin' && part.name == '__func')
- {
- part.hasOwner = true;
- }
- parts.push( part );
- s = s.slice(eProp.value.length);
- }
- else
- {
- eProp = false;
- }
- parseModifiers.stop = parseMod;
- }
-
- if (!eProp)
- {
- parts.push({type:'text', data:''});
- }
- }
-
- e.tree.push({type: 'var', parts: parts});
-
- e.value += e.token.substr(rootName.length);
-
- onParseVar(e.token);
-
- return s;
- }
-
- function onParseVar(nm) {}
-
-
- var tokens =
- [
- {
- re: /^\$([\w@]+)/, //var
- parse: function(e, s)
- {
- parseModifiers(parseVar(s, e, RegExp.$1), e);
- }
- },
- {
- re: /^(true|false)/i, //bool
- parse: function(e, s)
- {
- parseText(e.token.match(/true/i) ? '1' : '', e.tree);
- }
- },
- {
- re: /^'([^'\\]*(?:\\.[^'\\]*)*)'/, //single quotes
- parse: function(e, s)
- {
- parseText(evalString(RegExp.$1), e.tree);
- parseModifiers(s, e);
- }
- },
- {
- re: /^"([^"\\]*(?:\\.[^"\\]*)*)"/, //double quotes
- parse: function(e, s)
- {
- var v = evalString(RegExp.$1);
- var isVar = v.match(tokens[0].re);
- if (isVar)
- {
- var eVar = {token:isVar[0], tree:[]};
- parseVar(v, eVar, isVar[1]);
- if (eVar.token.length == v.length)
- {
- e.tree.push( eVar.tree[0] );
- return;
- }
- }
- parseText.parseEmbeddedVars = true;
- e.tree.push({
- type: 'plugin',
- name: '__quoted',
- params: {__parsed: parse(v,[])}
- });
- parseText.parseEmbeddedVars = false;
- parseModifiers(s, e);
- }
- },
- {
- re: /^(\w+)\s*[(]([)]?)/, //func()
- parse: function(e, s)
- {
- var fnm = RegExp.$1;
- var noArgs = RegExp.$2;
- var params = parseParams(noArgs?'':s,/^\s*,\s*/);
- parseFunc(fnm, params, e.tree);
- e.value += params.toString();
- parseModifiers(s.slice(params.toString().length), e);
- }
- },
- {
- re: /^\s*\(\s*/, //expression in parentheses
- parse: function(e, s)
- {
- var parens = [];
- e.tree.push(parens);
- parens.parent = e.tree;
- e.tree = parens;
- }
- },
- {
- re: /^\s*\)\s*/,
- parse: function(e, s)
- {
- if (e.tree.parent) //it may be the end of func() or (expr)
- {
- e.tree = e.tree.parent;
- }
- }
- },
- {
- re: /^\s*(\+\+|--)\s*/,
- parse: function(e, s)
- {
- if (e.tree.length && e.tree[e.tree.length-1].type == 'var')
- {
- parseOperator(RegExp.$1, 'post-unary', 1, e.tree);
- }
- else
- {
- parseOperator(RegExp.$1, 'pre-unary', 1, e.tree);
- }
- }
- },
- {
- re: /^\s*(===|!==|==|!=)\s*/,
- parse: function(e, s)
- {
- parseOperator(RegExp.$1, 'binary', 6, e.tree);
- }
- },
- {
- re: /^\s+(eq|ne|neq)\s+/i,
- parse: function(e, s)
- {
- var op = RegExp.$1.replace(/ne(q)?/,'!=').replace(/eq/,'==');
- parseOperator(op, 'binary', 6, e.tree);
- }
- },
- {
- re: /^\s*!\s*/,
- parse: function(e, s)
- {
- parseOperator('!', 'pre-unary', 2, e.tree);
- }
- },
- {
- re: /^\s+not\s+/i,
- parse: function(e, s)
- {
- parseOperator('!', 'pre-unary', 2, e.tree);
- }
- },
- {
- re: /^\s*(=|\+=|-=|\*=|\/=|%=)\s*/,
- parse: function(e, s)
- {
- parseOperator(RegExp.$1, 'binary', 10, e.tree);
- }
- },
- {
- re: /^\s*(\*|\/|%)\s*/,
- parse: function(e, s)
- {
- parseOperator(RegExp.$1, 'binary', 3, e.tree);
- }
- },
- {
- re: /^\s+mod\s+/i,
- parse: function(e, s)
- {
- parseOperator('%', 'binary', 3, e.tree);
- }
- },
- {
- re: /^\s*(\+|-)\s*/,
- parse: function(e, s)
- {
- if (!e.tree.length || e.tree[e.tree.length-1].name == 'operator')
- {
- parseOperator(RegExp.$1, 'pre-unary', 4, e.tree);
- }
- else
- {
- parseOperator(RegExp.$1, 'binary', 4, e.tree);
- }
- }
- },
- {
- re: /^\s*(<=|>=|<>|<|>)\s*/,
- parse: function(e, s)
- {
- parseOperator(RegExp.$1.replace(/<>/,'!='), 'binary', 5, e.tree);
- }
- },
- {
- re: /^\s+(lt|lte|le|gt|gte|ge)\s+/i,
- parse: function(e, s)
- {
- var op = RegExp.$1.replace(/lt/,'<').replace(/l(t)?e/,'<=').replace(/gt/,'>').replace(/g(t)?e/,'>=');
- parseOperator(op, 'binary', 5, e.tree);
- }
- },
- {
- re: /^\s+(is\s+(not\s+)?div\s+by)\s+/i,
- parse: function(e, s)
- {
- parseOperator(RegExp.$2?'div_not':'div', 'binary', 7, e.tree);
- }
- },
- {
- re: /^\s+is\s+(not\s+)?(even|odd)(\s+by\s+)?\s*/i,
- parse: function(e, s)
- {
- var op = RegExp.$1 ? ((RegExp.$2=='odd')?'even':'even_not') : ((RegExp.$2=='odd')?'even_not':'even');
- parseOperator(op, 'binary', 7, e.tree);
- if (!RegExp.$3)
- {
- parseText('1', e.tree);
- }
- }
- },
- {
- re: /^\s*(&&)\s*/,
- parse: function(e, s)
- {
- parseOperator(RegExp.$1, 'binary', 8, e.tree);
- }
- },
- {
- re: /^\s*(\|\|)\s*/,
- parse: function(e, s)
- {
- parseOperator(RegExp.$1, 'binary', 9, e.tree);
- }
- },
- {
- re: /^\s+and\s+/i,
- parse: function(e, s)
- {
- parseOperator('&&', 'binary', 11, e.tree);
- }
- },
- {
- re: /^\s+xor\s+/i,
- parse: function(e, s)
- {
- parseOperator('xor', 'binary', 12, e.tree);
- }
- },
- {
- re: /^\s+or\s+/i,
- parse: function(e, s)
- {
- parseOperator('||', 'binary', 13, e.tree);
- }
- },
- {
- re: /^#(\w+)#/, //config variable
- parse: function(e, s)
- {
- var eVar = {token:'$smarty',tree:[]};
- parseVar('.config.'+RegExp.$1, eVar, 'smarty');
- e.tree.push( eVar.tree[0] );
- parseModifiers(s, e);
- }
- },
- {
- re: /^\s*\[\s*/, //array
- parse: function(e, s)
- {
- var params = parseParams(s, /^\s*,\s*/, /^('[^'\\]*(?:\\.[^'\\]*)*'|"[^"\\]*(?:\\.[^"\\]*)*"|\w+)\s*=>\s*/);
- parsePluginFunc('__array',params,e.tree);
- e.value += params.toString();
- var paren = s.slice(params.toString().length).match(/\s*\]/);
- if (paren)
- {
- e.value += paren[0];
- }
- }
- },
- {
- re: /^[\d.]+/, //number
- parse: function(e, s)
- {
- if (e.token.indexOf('.') > -1) {
- e.token = parseFloat(e.token);
- } else {
- e.token = parseInt(e.token, 10);
- }
- parseText(e.token, e.tree);
- parseModifiers(s, e);
- }
- },
- {
- re: /^\w+/, //static
- parse: function(e, s)
- {
- parseText(e.token, e.tree);
- parseModifiers(s, e);
- }
- }
- ];
-
- function parseModifiers(s, e)
- {
- if (parseModifiers.stop)
- {
- return;
- }
-
- var modifier = s.match(/^\|(\w+)/);
- if (!modifier)
- {
- return;
- }
-
- e.value += modifier[0];
-
- var fnm = modifier[1]=='default' ? 'defaultValue' : modifier[1];
- s = s.slice(modifier[0].length).replace(/^\s+/,'');
-
- parseModifiers.stop = true;
- var params = [];
- for (var colon=s.match(/^\s*:\s*/); colon; colon=s.match(/^\s*:\s*/))
- {
- e.value += s.slice(0,colon[0].length);
- s = s.slice(colon[0].length);
-
- var param = {value:'', tree:[]};
- if (lookUp(s, param))
- {
- e.value += param.value;
- params.push(param.tree[0]);
- s = s.slice(param.value.length);
- }
- else
- {
- parseText('',params);
- }
- }
- parseModifiers.stop = false;
-
- params.unshift(e.tree.pop()); //modifiers have the highest priority
- e.tree.push(parseFunc(fnm,{__parsed:params},[])[0]);
-
- parseModifiers(s, e); //modifiers can be combined
- }
-
- function lookUp(s,e)
- {
- if (!s)
- {
- return false;
- }
-
- if (s.substr(0,jSmart.prototype.left_delimiter.length)==jSmart.prototype.left_delimiter)
- {
- var tag = findTag('',s);
- if (tag)
- {
- e.token = tag[0];
- e.value += tag[0];
- parse(tag[0], e.tree);
- parseModifiers(s.slice(e.value.length), e);
- return true;
- }
- }
-
- for (var i=0; i<tokens.length; ++i)
- {
- if (s.match(tokens[i].re))
- {
- e.token = RegExp.lastMatch;
- e.value += RegExp.lastMatch;
- tokens[i].parse(e, s.slice(e.token.length));
- return true;
- }
- }
- return false;
- }
-
- function bundleOp(i, tree, precedence)
- {
- var op = tree[i];
- if (op.name == 'operator' && op.precedence == precedence && !op.params.__parsed)
- {
- if (op.optype == 'binary')
- {
- op.params.__parsed = [tree[i-1],tree[i+1]];
- tree.splice(i-1,3,op);
- return true;
- }
- else if (op.optype == 'post-unary')
- {
- op.params.__parsed = [tree[i-1]];
- tree.splice(i-1,2,op);
- return true;
- }
-
- op.params.__parsed = [tree[i+1]];
- tree.splice(i,2,op);
- }
- return false;
- }
-
- function composeExpression(tree)
- {
- var i = 0;
- for (i=0; i<tree.length; ++i)
- {
- if (tree[i] instanceof Array)
- {
- tree[i] = composeExpression(tree[i])
- }
- }
-
- for (var precedence=1; precedence<14; ++precedence)
- {
- if (precedence==2 || precedence==10)
- {
- for (i=tree.length; i>0; --i)
- {
- i -= bundleOp(i-1, tree, precedence);
- }
- }
- else
- {
- for (i=0; i<tree.length; ++i)
- {
- i -= bundleOp(i, tree, precedence);
- }
- }
- }
- return tree[0]; //only one node must be left
- }
-
- function parseExpression(s)
- {
- var e = { value:'', tree:[] };
- while (lookUp(s.slice(e.value.length), e)){}
- if (!e.tree.length)
- {
- return false;
- }
- e.tree = composeExpression(e.tree);
- return e;
- }
-
- function parseParams(paramsStr, reDelim, reName)
- {
- var s = paramsStr.replace(/\n/g,' ').replace(/^\s+|\s+$/g,'');
- var params = [];
- params.__parsed = [];
- var paramsStr = '';
-
- if (!s)
- {
- return params;
- }
-
- if (!reDelim)
- {
- reDelim = /^\s+/;
- reName = /^(\w+)\s*=\s*/;
- }
-
- while (s)
- {
- var nm = null;
- if (reName)
- {
- var foundName = s.match(reName);
- if (foundName)
- {
- nm = trimQuotes(foundName[1]);
- paramsStr += s.slice(0,foundName[0].length);
- s = s.slice(foundName[0].length);
- }
- }
-
- var param = parseExpression(s);
- if (!param)
- {
- break;
- }
-
- if (nm)
- {
- params[nm] = param.value;
- params.__parsed[nm] = param.tree;
- }
- else
- {
- params.push(param.value);
- params.__parsed.push(param.tree);
- }
-
- paramsStr += s.slice(0,param.value.length);
- s = s.slice(param.value.length);
-
- var foundDelim = s.match(reDelim);
- if (foundDelim)
- {
- paramsStr += s.slice(0,foundDelim[0].length);
- s = s.slice(foundDelim[0].length);
- }
- else
- {
- break;
- }
- }
- params.toString = function() { return paramsStr; }
- return params;
- }
-
- function parsePluginBlock(name, params, tree, content)
- {
- tree.push({
- type: 'plugin',
- name: name,
- params: params,
- subTree: parse(content,[])
- });
- }
-
- function parsePluginFunc(name, params, tree)
- {
- tree.push({
- type: 'plugin',
- name: name,
- params: params
- });
- }
-
- function getActualParamValues(params,data)
- {
- var actualParams = [];
- for (var nm in params.__parsed)
- {
- if (params.__parsed.hasOwnProperty(nm))
- {
- var v = process([params.__parsed[nm]], data);
- actualParams[nm] = v;
- }
- }
-
- actualParams.__get = function(nm,defVal,id)
- {
- if (nm in actualParams && typeof(actualParams[nm]) != 'undefined')
- {
- return actualParams[nm];
- }
- if (typeof(id)!='undefined' && typeof(actualParams[id]) != 'undefined')
- {
- return actualParams[id];
- }
- if (defVal === null)
- {
- throw new Error("The required attribute '"+nm+"' is missing");
- }
- return defVal;
- };
- return actualParams;
- }
-
- /**
- * Returns boolean true if object is empty otherwise false.
- *
- * @param object hash Object you are testing against.
- *
- * @return boolean
- */
- function isEmptyObject(hash) {
- for (var i in hash) {
- if (hash.hasOwnProperty(i)) {
- return false;
- }
- }
- return true;
- }
-
- function getVarValue(node, data, val)
- {
- var v = data;
- var nm = '';
- for (var i=0; i<node.parts.length; ++i)
- {
- var part = node.parts[i];
- if (part.type == 'plugin' && part.name == '__func' && part.hasOwner)
- {
- data.__owner = v;
- v = process([node.parts[i]],data);
- delete data.__owner;
- }
- else
- {
- nm = process([part],data);
-
- //section name
- if (nm in data.smarty.section && part.type=='text' && process([node.parts[0]],data)!='smarty')
- {
- nm = data.smarty.section[nm].index;
- }
-
- //add to array
- if (!nm && typeof val != 'undefined' && v instanceof Array)
- {
- nm = v.length;
- }
-
- //set new value
- if (typeof val != 'undefined' && i==node.parts.length-1)
- {
- v[nm] = val;
- }
-
- if (typeof v == 'object' && v !== null && nm in v)
- {
- v = v[nm];
- }
- else
- {
- if (typeof val == 'undefined')
- {
- return val;
- }
- v[nm] = {};
- v = v[nm];
- }
- }
- }
- return v;
- }
-
- function process(tree, data)
- {
- var res = '';
- for (var i=0; i<tree.length; ++i)
- {
- var s = '';
- var node = tree[i];
- if (node.type == 'text')
- {
- s = node.data;
- }
- else if (node.type == 'var')
- {
- s = getVarValue(node,data);
- }
- else if (node.type == 'build-in')
- {
- s = buildInFunctions[node.name].process(node,data);
- }
- else if (node.type == 'plugin')
- {
- var plugin = plugins[node.name];
- if (plugin.type == 'block')
- {
- var repeat = {value:true};
- plugin.process(getActualParamValues(node.params,data), '', data, repeat);
- while (repeat.value)
- {
- repeat.value = false;
- s += plugin.process(
- getActualParamValues(node.params,data),
- process(node.subTree, data),
- data,
- repeat
- );
- }
- }
- else if (plugin.type == 'function')
- {
- s = plugin.process(getActualParamValues(node.params,data), data);
- }
- }
- if (typeof s == 'boolean')
- {
- s = s ? '1' : '';
- }
- if (s == null) {
- s = '';
- }
- if (tree.length == 1)
- {
- return s;
- }
- res += s!==null ? s : '';
-
- if (data.smarty['continue'] || data.smarty['break'])
- {
- return res;
- }
- }
- return res;
- }
-
- function getTemplate(name, tree, nocache)
- {
- if (nocache || !(name in files))
- {
- var tpl = jSmart.prototype.getTemplate(name);
- if (typeof(tpl) != 'string')
- {
- throw new Error('No template for '+ name);
- }
- parse(applyFilters(jSmart.prototype.filters_global.pre, stripComments(tpl.replace(/\r\n/g,'\n'))), tree);
- files[name] = tree;
- }
- else
- {
- tree = files[name];
- }
- return tree;
- }
-
- function stripComments(s)
- {
- var sRes = '';
- for (var openTag=s.match(/{{\*/); openTag; openTag=s.match(/{{\*/))
- {
- sRes += s.slice(0,openTag.index);
- s = s.slice(openTag.index+openTag[0].length);
- var closeTag = s.match(/\*}}/);
- if (!closeTag)
- {
- throw new Error('Unclosed {*');
- }
- s = s.slice(closeTag.index+closeTag[0].length);
- }
- return sRes + s;
- }
-
- function applyFilters(filters, s)
- {
- for (var i=0; i<filters.length; ++i)
- {
- s = filters[i](s);
- }
- return s;
- }
-
-
- jSmart = function(tpl)
- {
- this.tree = [];
- this.tree.blocks = {};
- this.scripts = {};
- this.default_modifiers = [];
- this.filters = {'variable':[], 'post':[]};
- this.smarty = {
- 'smarty': {
- block: {},
- 'break': false,
- capture: {},
- 'continue': false,
- counter: {},
- cycle: {},
- foreach: {},
- section: {},
- now: Math.floor( (new Date()).getTime()/1000 ),
- 'const': {},
- config: {},
- current_dir: '/',
- template: '',
- ldelim: jSmart.prototype.left_delimiter,
- rdelim: jSmart.prototype.right_delimiter,
- version: '2.15.0'
- }
- };
- blocks = this.tree.blocks;
- parse(
- applyFilters(jSmart.prototype.filters_global.pre, stripComments((new String(tpl?tpl:'')).replace(/\r\n/g,'\n'))),
- this.tree
- );
- };
-
- jSmart.prototype.fetch = function(data)
- {
- blocks = this.tree.blocks;
- scripts = this.scripts;
- escape_html = this.escape_html;
- default_modifiers = jSmart.prototype.default_modifiers_global.concat(this.default_modifiers);
- this.data = obMerge((typeof data == 'object') ? data : {}, this.smarty);
- varFilters = jSmart.prototype.filters_global.variable.concat(this.filters.variable);
- var res = process(this.tree, this.data);
- if (jSmart.prototype.debugging)
- {
- plugins.debug.process([],this.data);
- }
- return applyFilters(jSmart.prototype.filters_global.post.concat(this.filters.post), res);
- };
-
- jSmart.prototype.escape_html = false;
-
- /**
- @param type valid values are 'function', 'block', 'modifier'
- @param callback func(params,data) or block(params,content,data,repeat)
- */
- jSmart.prototype.registerPlugin = function(type, name, callback)
- {
- if (type == 'modifier')
- {
- modifiers[name] = callback;
- }
- else
- {
- plugins[name] = {'type': type, 'process': callback};
- }
- };
-
- /**
- @param type valid values are 'pre', 'variable', 'post'
- @param callback function(textValue) { ... }
- */
- jSmart.prototype.registerFilter = function(type, callback)
- {
- (this.tree ? this.filters : jSmart.prototype.filters_global)[type=='output'?'post':type].push(callback);
- }
-
- jSmart.prototype.filters_global = {'pre':[],'variable':[],'post':[]};
-
- jSmart.prototype.configLoad = function(confValues, section, data)
- {
- data = data ? data : this.data;
- var s = confValues.replace(/\r\n/g,'\n').replace(/^\s+|\s+$/g,'');
- var re = /^\s*(?:\[([^\]]+)\]|(?:(\w+)[ \t]*=[ \t]*("""|'[^'\\\n]*(?:\\.[^'\\\n]*)*'|"[^"\\\n]*(?:\\.[^"\\\n]*)*"|[^\n]*)))/m;
- var currSect = '';
- for (var f=s.match(re); f; f=s.match(re))
- {
- s = s.slice(f.index+f[0].length);
- if (f[1])
- {
- currSect = f[1];
- }
- else if ((!currSect || currSect == section) && currSect.substr(0,1) != '.')
- {
- if (f[3] == '"""')
- {
- var triple = s.match(/"""/);
- if (triple)
- {
- data.smarty.config[f[2]] = s.slice(0,triple.index);
- s = s.slice(triple.index + triple[0].length);
- }
- }
- else
- {
- data.smarty.config[f[2]] = trimQuotes(f[3]);
- }
- }
- var newln = s.match(/\n+/);
- if (newln)
- {
- s = s.slice(newln.index + newln[0].length);
- }
- else
- {
- break;
- }
- }
- }
-
- jSmart.prototype.clearConfig = function(varName)
- {
- if (varName)
- {
- delete this.data.smarty.config[varName];
- }
- else
- {
- this.data.smarty.config = {};
- }
- }
-
- /**
- add modifier to implicitly apply to every variable in a template
- @param modifiers single string (e.g. "replace:'from':'to'")
- or array of strings (e.g. ['escape:"htmlall"', "replace:'from':'to'"])
- */
- jSmart.prototype.addDefaultModifier = function(modifiers)
- {
- if (!(modifiers instanceof Array))
- {
- modifiers = [modifiers];
- }
-
- for (var i=0; i<modifiers.length; ++i)
- {
- var e = { value:'', tree:[0] };
- parseModifiers('|'+modifiers[i], e);
- (this.tree ? this.default_modifiers : this.default_modifiers_global).push( e.tree[0] );
- }
- }
-
- jSmart.prototype.default_modifiers_global = [];
-
- /**
- override this function
- @param name value of 'file' parameter in {include} and {extends}
- @return template text
- */
- jSmart.prototype.getTemplate = function(name)
- {
- throw new Error('No template for ' + name);
- }
-
- /**
- override this function
- @param name value of 'file' parameter in {fetch}
- @return file content
- */
- jSmart.prototype.getFile = function(name)
- {
- throw new Error('No file for ' + name);
- }
-
- /**
- override this function
- @param name value of 'file' parameter in {include_php} and {include_javascript}
- or value of 'script' parameter in {insert}
- @return Javascript script
- */
- jSmart.prototype.getJavascript = function(name)
- {
- throw new Error('No Javascript for ' + name);
- }
-
- /**
- override this function
- @param name value of 'file' parameter in {config_load}
- @return config file content
- */
- jSmart.prototype.getConfig = function(name)
- {
- throw new Error('No config for ' + name);
- }
-
-
-
- /**
- whether to skip tags in open brace { followed by white space(s) and close brace } with white space(s) before
- */
- jSmart.prototype.auto_literal = true;
-
- jSmart.prototype.left_delimiter = '{';
- jSmart.prototype.right_delimiter = '}';
-
- /** enables the debugging console */
- jSmart.prototype.debugging = false;
-
-
- jSmart.prototype.PHPJS = function(fnm, modifier)
- {
- if (eval('typeof '+fnm) == 'function')
- {
- return (typeof window == 'object') ? window : global;
- }
- else if (typeof(PHP_JS) == 'function')
- {
- return new PHP_JS();
- }
- throw new Error("Modifier '" + modifier + "' uses JavaScript port of PHP function '" + fnm + "'. You can find one at http://phpjs.org");
- }
-
- jSmart.prototype.makeTimeStamp = function(s)
- {
- if (!s)
- {
- return Math.floor( (new Date()).getTime()/1000 );
- }
- if (isNaN(s))
- {
- var tm = jSmart.prototype.PHPJS('strtotime','date_format').strtotime(s);
- if (tm == -1 || tm === false) {
- return Math.floor( (new Date()).getTime()/1000 );
- }
- return tm;
- }
- s = new String(s);
- if (s.length == 14) //mysql timestamp format of YYYYMMDDHHMMSS
- {
- return Math.floor( (new Date(s.substr(0,4),s.substr(4,2)-1,s.substr(6,2),s.substr(8,2),s.substr(10,2)).getTime()/1000 ) );
- }
- return parseInt(s);
- }
-
-
-
- /**
- register custom functions
- */
- jSmart.prototype.registerPlugin(
- 'function',
- '__array',
- function(params, data)
- {
- var a = [];
- for (var nm in params)
- {
- if (params.hasOwnProperty(nm) && params[nm] && typeof params[nm] != 'function')
- {
- a[nm] = params[nm];
- }
- }
- return a;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- '__func',
- function(params, data) {
- var paramNames = [], paramValues = {}, paramData = [];
- for (var i=0; i<params.length; ++i) {
- paramNames.push(params.name+'__p'+i);
- paramData.push(params[i]);
- paramValues[params.name+'__p'+i] = params[i];
- }
- var fname, mergedParams = obMerge({}, data, paramValues);
- if (('__owner' in data && params.name in data.__owner)) {
- fname = '__owner.'+params.name;
- return execute(fname + '(' + paramNames.join(',') + ')', mergedParams);
- } else if (modifiers.hasOwnProperty(params.name)) {
- fname = modifiers[params.name]
- return executeByFuncObject(fname, paramData, mergedParams);
- } else {
- fname = params.name;
- return execute(fname + '(' + paramNames.join(',') + ')', mergedParams);
- }
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- '__quoted',
- function(params, data)
- {
- return params.join('');
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'append',
- function(params, data)
- {
- var varName = params.__get('var',null,0);
- if (!(varName in data) || !(data[varName] instanceof Array))
- {
- data[varName] = [];
- }
- var index = params.__get('index',false);
- var val = params.__get('value',null,1);
- if (index === false)
- {
- data[varName].push(val);
- }
- else
- {
- data[varName][index] = val;
- }
- return '';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'assign',
- function(params, data)
- {
- assignVar(params.__get('var',null,0), params.__get('value',null,1), data);
- return '';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'break',
- function(params, data)
- {
- data.smarty['break'] = true;
- return '';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'call',
- function(params, data)
- {
- var fname = params.__get('name',null,0);
- delete params.name;
- var assignTo = params.__get('assign',false);
- delete params.assign;
- var s = plugins[fname].process(params, data);
- if (assignTo)
- {
- assignVar(assignTo, s, data);
- return '';
- }
- return s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'block',
- 'capture',
- function(params, content, data, repeat)
- {
- if (content)
- {
- content = content.replace(/^\n/,'');
- data.smarty.capture[params.__get('name','default',0)] = content;
-
- if ('assign' in params)
- {
- assignVar(params.assign, content, data);
- }
-
- var append = params.__get('append',false);
- if (append)
- {
- if (append in data)
- {
- if (data[append] instanceof Array)
- {
- data[append].push(content);
- }
- }
- else
- {
- data[append] = [content];
- }
- }
- }
- return '';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'continue',
- function(params, data)
- {
- data.smarty['continue'] = true;
- return '';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'counter',
- function(params, data)
- {
- var name = params.__get('name','default');
- if (name in data.smarty.counter)
- {
- var counter = data.smarty.counter[name];
- if ('start' in params)
- {
- counter.value = parseInt(params['start']);
- }
- else
- {
- counter.value = parseInt(counter.value);
- counter.skip = parseInt(counter.skip);
- if ('down' == counter.direction)
- {
- counter.value -= counter.skip;
- }
- else
- {
- counter.value += counter.skip;
- }
- }
- counter.skip = params.__get('skip',counter.skip);
- counter.direction = params.__get('direction',counter.direction);
- counter.assign = params.__get('assign',counter.assign);
- }
- else
- {
- data.smarty.counter[name] = {
- value: parseInt(params.__get('start',1)),
- skip: parseInt(params.__get('skip',1)),
- direction: params.__get('direction','up'),
- assign: params.__get('assign',false)
- };
- }
-
- if (data.smarty.counter[name].assign)
- {
- data[data.smarty.counter[name].assign] = data.smarty.counter[name].value;
- return '';
- }
-
- if (params.__get('print',true))
- {
- return data.smarty.counter[name].value;
- }
-
- return '';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'cycle',
- function(params, data)
- {
- var name = params.__get('name','default');
- var reset = params.__get('reset',false);
- if (!(name in data.smarty.cycle))
- {
- data.smarty.cycle[name] = {arr: [''], delimiter: params.__get('delimiter',','), index: 0};
- reset = true;
- }
-
- if (params.__get('delimiter',false))
- {
- data.smarty.cycle[name].delimiter = params.delimiter;
- }
- var values = params.__get('values',false);
- if (values)
- {
- var arr = [];
- if (values instanceof Object)
- {
- for (nm in values)
- {
- arr.push(values[nm]);
- }
- }
- else
- {
- arr = values.split(data.smarty.cycle[name].delimiter);
- }
-
- if (arr.length != data.smarty.cycle[name].arr.length || arr[0] != data.smarty.cycle[name].arr[0])
- {
- data.smarty.cycle[name].arr = arr;
- data.smarty.cycle[name].index = 0;
- reset = true;
- }
- }
-
- if (params.__get('advance','true'))
- {
- data.smarty.cycle[name].index += 1;
- }
- if (data.smarty.cycle[name].index >= data.smarty.cycle[name].arr.length || reset)
- {
- data.smarty.cycle[name].index = 0;
- }
-
- if (params.__get('assign',false))
- {
- assignVar(params.assign, data.smarty.cycle[name].arr[ data.smarty.cycle[name].index ], data);
- return '';
- }
-
- if (params.__get('print',true))
- {
- return data.smarty.cycle[name].arr[ data.smarty.cycle[name].index ];
- }
-
- return '';
- }
- );
-
- jSmart.prototype.print_r = function(v,indent)
- {
- if (v instanceof Object)
- {
- var s = ((v instanceof Array) ? 'Array['+v.length+']' : 'Object') + '<br>';
- for (var nm in v)
- {
- if (v.hasOwnProperty(nm))
- {
- s += indent + ' <strong>' + nm + '</strong> : ' + jSmart.prototype.print_r(v[nm],indent+' ') + '<br>';
- }
- }
- return s;
- }
- return v;
- }
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'debug',
- function(params, data)
- {
- if (typeof dbgWnd != 'undefined')
- {
- dbgWnd.close();
- }
- dbgWnd = window.open('','','width=680,height=600,resizable,scrollbars=yes');
- var sVars = '';
- var i=0;
- for (var nm in data)
- {
- sVars += '<tr class=' + (++i%2?'odd':'even') + '><td><strong>' + nm + '</strong></td><td>' + jSmart.prototype.print_r(data[nm],'') + '</td></tr>';
- }
- dbgWnd.document.write(" \
- <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en'> \
- <head> \
- <title>jSmart Debug Console</title> \
- <style type='text/css'> \
- table {width: 100%;} \
- td {vertical-align:top;width: 50%;} \
- .even td {background-color: #fafafa;} \
- </style> \
- </head> \
- <body> \
- <h1>jSmart Debug Console</h1> \
- <h2>assigned template variables</h2> \
- <table>" + sVars + "</table> \
- </body> \
- </html> \
- ");
- return '';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'eval',
- function(params, data)
- {
- var tree = [];
- parse(params.__get('var','',0), tree);
- var s = process(tree, data);
- if ('assign' in params)
- {
- assignVar(params.assign, s, data);
- return '';
- }
- return s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'fetch',
- function(params, data)
- {
- var s = jSmart.prototype.getFile(params.__get('file',null,0));
- if ('assign' in params)
- {
- assignVar(params.assign, s, data);
- return '';
- }
- return s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'html_checkboxes',
- function (params, data) {
- var type = params.__get('type','checkbox'),
- name = params.__get('name',type),
- realName = params.__get('name',type),
- values = params.__get('values',params.options),
- output = params.__get('options',[]),
- useName = ('options' in params),
- selected = params.__get('selected',false),
- separator = params.__get('separator',''),
- labels = Boolean(params.__get('labels',true)),
- label_ids = Boolean(params.__get('label_ids',false)),
- p,
- res = [],
- i = 0,
- s = '',
- value,
- id;
-
- if (type == 'checkbox') {
- name += '[]';
- }
- if (!useName) {
- for (p in params.output) {
- output.push(params.output[p]);
- }
- }
-
- for (p in values) {
- if (values.hasOwnProperty(p)) {
- value = (useName ? p : values[p]);
- id = realName + '_' + value;
- s = (labels ? ( label_ids ? '<label for="'+id+'">' : '<label>') : '');
-
- s += '<input type="' + type + '" name="' + name + '" value="' + value + '" ';
- if (label_ids) {
- s += 'id="'+id+'" ';
- }
- if (selected == (useName ? p : values[p])) {
- s += 'checked="checked" ';
- }
- s += '/>' + output[useName?p:i++];
- s += (labels ? '</label>' : '');
- s += separator;
- res.push(s);
- }
- }
- if ('assign' in params) {
- assignVar(params.assign, res, data);
- return '';
- }
- return res.join('\n');
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'html_image',
- function (params, data) {
- var url = params.__get('file', null),
- width = params.__get('width', false),
- height = params.__get('height', false),
- alt = params.__get('alt', ''),
- href = params.__get('href', params.__get('link', false)),
- path_prefix = params.__get('path_prefix', ''),
- paramNames = {file:1, width:1, height:1, alt:1, href:1, basedir:1, path_prefix:1, link:1},
- s = '<img src="' + path_prefix + url + '"' + ' alt="'+alt+'"' + (width ? ' width="'+width+'"':'') + (height ? ' height="'+height+'"':''),
- p;
-
- for (p in params) {
- if (params.hasOwnProperty(p) && typeof(params[p]) == 'string') {
- if (!(p in paramNames)) {
- s += ' ' + p + '="' + params[p] + '"';
- }
- }
- }
- s += ' />';
- return href ? '<a href="'+href+'">'+s+'</a>' : s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'html_options',
- function(params, data)
- {
- var values = params.__get('values',params.options);
- var output = params.__get('options',[]);
- var useName = ('options' in params);
- var p;
- if (!useName)
- {
- for (p in params.output)
- {
- output.push(params.output[p]);
- }
- }
- var selected = params.__get('selected',false);
-
- var res = [];
- var s = '';
- var i = 0;
- for (p in values)
- {
- if (values.hasOwnProperty(p))
- {
- s = '<option value="' + (useName ? p : values[p]) + '"';
- if (selected == (useName ? p : values[p]))
- {
- s += ' selected="selected"';
- }
- s += '>' + output[useName ? p : i++] + '</option>';
- res.push(s);
- }
- }
- var name = params.__get('name',false);
- return (name ? ('<select name="' + name + '">\n' + res.join('\n') + '\n</select>') : res.join('\n')) + '\n';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'html_radios',
- function(params, data)
- {
- params.type = 'radio';
- return plugins.html_checkboxes.process(params,data);
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'html_select_date',
- function(params, data)
- {
- var prefix = params.__get('prefix','Date_');
- var months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
-
- var s = '';
- s += '<select name="'+prefix+'Month">\n';
- var i=0;
- for (i=0; i<months.length; ++i)
- {
- s += '<option value="' + i + '">' + months[i] + '</option>\n';
- }
- s += '</select>\n'
-
- s += '<select name="'+prefix+'Day">\n';
- for (i=0; i<31; ++i)
- {
- s += '<option value="' + i + '">' + i + '</option>\n';
- }
- s += '</select>\n'
- return s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'html_table',
- function(params, data)
- {
- var loop = [];
- var p;
- if (params.loop instanceof Array)
- {
- loop = params.loop
- }
- else
- {
- for (p in params.loop)
- {
- if (params.loop.hasOwnProperty(p))
- {
- loop.push( params.loop[p] );
- }
- }
- }
- var rows = params.__get('rows',false);
- var cols = params.__get('cols',false);
- if (!cols)
- {
- cols = rows ? Math.ceil(loop.length/rows) : 3;
- }
- var colNames = [];
- if (isNaN(cols))
- {
- if (typeof cols == 'object')
- {
- for (p in cols)
- {
- if (cols.hasOwnProperty(p))
- {
- colNames.push(cols[p]);
- }
- }
- }
- else
- {
- colNames = cols.split(/\s*,\s*/);
- }
- cols = colNames.length;
- }
- rows = rows ? rows : Math.ceil(loop.length/cols);
-
- var inner = params.__get('inner','cols');
- var caption = params.__get('caption','');
- var table_attr = params.__get('table_attr','border="1"');
- var th_attr = params.__get('th_attr',false);
- if (th_attr && typeof th_attr != 'object')
- {
- th_attr = [th_attr];
- }
- var tr_attr = params.__get('tr_attr',false);
- if (tr_attr && typeof tr_attr != 'object')
- {
- tr_attr = [tr_attr];
- }
- var td_attr = params.__get('td_attr',false);
- if (td_attr && typeof td_attr != 'object')
- {
- td_attr = [td_attr];
- }
- var trailpad = params.__get('trailpad',' ');
- var hdir = params.__get('hdir','right');
- var vdir = params.__get('vdir','down');
-
- var s = '';
- for (var row=0; row<rows; ++row)
- {
- s += '<tr' + (tr_attr ? ' '+tr_attr[row%tr_attr.length] : '') + '>\n';
- for (var col=0; col<cols; ++col)
- {
- var idx = (inner=='cols') ? ((vdir=='down'?row:rows-1-row) * cols + (hdir=='right'?col:cols-1-col)) : ((hdir=='right'?col:cols-1-col) * rows + (vdir=='down'?row:rows-1-row));
-
- s += '<td' + (td_attr ? ' '+td_attr[col%td_attr.length] : '') + '>' + (idx < loop.length ? loop[idx] : trailpad) + '</td>\n';
- }
- s += '</tr>\n';
- }
-
- var sHead = '';
- if (colNames.length)
- {
- sHead = '\n<thead><tr>';
- for (var i=0; i<colNames.length; ++i)
- {
- sHead += '\n<th' + (th_attr ? ' '+th_attr[i%th_attr.length] : '') + '>' + colNames[hdir=='right'?i:colNames.length-1-i] + '</th>';
- }
- sHead += '\n</tr></thead>';
- }
-
- return '<table ' + table_attr + '>' + (caption?'\n<caption>'+caption+'</caption>':'') + sHead + '\n<tbody>\n' + s + '</tbody>\n</table>\n';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'include',
- function(params, data)
- {
- var file = params.__get('file',null,0);
- var incData = obMerge({},data,params);
- incData.smarty.template = file;
- var s = process(getTemplate(file,[],findInArray(params,'nocache')>=0), incData);
- if ('assign' in params)
- {
- assignVar(params.assign, s, data);
- return '';
- }
- return s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'include_javascript',
- function(params, data)
- {
- var file = params.__get('file',null,0);
- if (params.__get('once',true) && file in scripts)
- {
- return '';
- }
- scripts[file] = true;
- var s = execute(jSmart.prototype.getJavascript(file), {'$this':data});
- if ('assign' in params)
- {
- assignVar(params.assign, s, data);
- return '';
- }
- return s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'include_php',
- function(params, data)
- {
- return plugins['include_javascript'].process(params,data);
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'insert',
- function(params, data)
- {
- var fparams = {};
- for (var nm in params)
- {
- if (params.hasOwnProperty(nm) && isNaN(nm) && params[nm] && typeof params[nm] == 'string' && nm != 'name' && nm != 'assign' && nm != 'script')
- {
- fparams[nm] = params[nm];
- }
- }
- var prefix = 'insert_';
- if ('script' in params)
- {
- eval(jSmart.prototype.getJavascript(params.script));
- prefix = 'smarty_insert_';
- }
- var func = eval(prefix+params.__get('name',null,0));
- var s = func(fparams, data);
- if ('assign' in params)
- {
- assignVar(params.assign, s, data);
- return '';
- }
- return s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'block',
- 'javascript',
- function(params, content, data, repeat)
- {
- data['$this'] = data;
- execute(content,data);
- delete data['$this'];
- return '';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'config_load',
- function(params, data)
- {
- jSmart.prototype.configLoad(jSmart.prototype.getConfig(params.__get('file',null,0)), params.__get('section','',1), data);
- return '';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'mailto',
- function(params, data)
- {
- var address = params.__get('address',null);
- var encode = params.__get('encode','none');
- var text = params.__get('text',address);
- var cc = jSmart.prototype.PHPJS('rawurlencode','mailto').rawurlencode(params.__get('cc','')).replace('%40','@');
- var bcc = jSmart.prototype.PHPJS('rawurlencode','mailto').rawurlencode(params.__get('bcc','')).replace('%40','@');
- var followupto = jSmart.prototype.PHPJS('rawurlencode','mailto').rawurlencode(params.__get('followupto','')).replace('%40','@');
- var subject = jSmart.prototype.PHPJS('rawurlencode','mailto').rawurlencode( params.__get('subject','') );
- var newsgroups = jSmart.prototype.PHPJS('rawurlencode','mailto').rawurlencode(params.__get('newsgroups',''));
- var extra = params.__get('extra','');
-
- address += (cc?'?cc='+cc:'');
- address += (bcc?(cc?'&':'?')+'bcc='+bcc:'');
- address += (subject ? ((cc||bcc)?'&':'?') + 'subject='+subject : '');
- address += (newsgroups ? ((cc||bcc||subject)?'&':'?') + 'newsgroups='+newsgroups : '');
- address += (followupto ? ((cc||bcc||subject||newsgroups)?'&':'?') + 'followupto='+followupto : '');
-
- s = '<a href="mailto:' + address + '" ' + extra + '>' + text + '</a>';
-
- if (encode == 'javascript')
- {
- s = "document.write('" + s + "');";
- var sEncoded = '';
- for (var i=0; i<s.length; ++i)
- {
- sEncoded += '%' + jSmart.prototype.PHPJS('bin2hex','mailto').bin2hex(s.substr(i,1));
- }
- return '<script type="text/javascript">eval(unescape(\'' + sEncoded + "'))</script>";
- }
- else if (encode == 'javascript_charcode')
- {
- var codes = [];
- for (var i=0; i<s.length; ++i)
- {
- codes.push(jSmart.prototype.PHPJS('ord','mailto').ord(s.substr(i,1)));
- }
- return '<script type="text/javascript" language="javascript">\n<!--\n{document.write(String.fromCharCode('
- + codes.join(',') + '))}\n//-->\n</script>\n';
- }
- else if (encode == 'hex')
- {
- if (address.match(/^.+\?.+$/))
- {
- throw new Error('mailto: hex encoding does not work with extra attributes. Try javascript.');
- }
- var aEncoded = '';
- for (var i=0; i<address.length; ++i)
- {
- if (address.substr(i,1).match(/\w/))
- {
- aEncoded += '%' + jSmart.prototype.PHPJS('bin2hex','mailto').bin2hex(address.substr(i,1));
- }
- else
- {
- aEncoded += address.substr(i,1);
- }
- }
- aEncoded = aEncoded.toLowerCase();
- var tEncoded = '';
- for (var i=0; i<text.length; ++i)
- {
- tEncoded += '&#x' + jSmart.prototype.PHPJS('bin2hex','mailto').bin2hex(text.substr(i,1)) + ';';
- }
- tEncoded = tEncoded.toLowerCase();
- return '<a href="mailto:' + aEncoded + '" ' + extra + '>' + tEncoded + '</a>';
- }
- return s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'math',
- function(params, data)
- {
- with (Math)
- {
- with (params)
- {
- var res = eval(params.__get('equation',null).replace(/pi\(\s*\)/g,'PI'));
- }
- }
-
- if ('format' in params)
- {
- res = jSmart.prototype.PHPJS('sprintf','math').sprintf(params.format,res);
- }
-
- if ('assign' in params)
- {
- assignVar(params.assign, res, data);
- return '';
- }
- return res;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'block',
- 'nocache',
- function(params, content, data, repeat)
- {
- return content;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'block',
- 'textformat',
- function(params, content, data, repeat)
- {
- if (!content) {
- return '';
- }
-
- content = new String(content);
-
- var wrap = params.__get('wrap',80);
- var wrap_char = params.__get('wrap_char','\n');
- var wrap_cut = params.__get('wrap_cut',false);
- var indent_char = params.__get('indent_char',' ');
- var indent = params.__get('indent',0);
- var indentStr = (new Array(indent+1)).join(indent_char);
- var indent_first = params.__get('indent_first',0);
- var indentFirstStr = (new Array(indent_first+1)).join(indent_char);
-
- var style = params.__get('style','');
-
- if (style == 'email') {
- wrap = 72;
- }
-
- var paragraphs = content.split(/[\r\n]{2}/);
- for (var i=0; i<paragraphs.length; ++i) {
- var p = paragraphs[i];
- if (!p) {
- continue;
- }
- p = p.replace(/^\s+|\s+$/,'').replace(/\s+/g,' ');
- if (indent_first> 0 ) {
- p = indentFirstStr + p;
- }
- p = modifiers.wordwrap(p, wrap-indent, wrap_char, wrap_cut);
- if (indent > 0) {
- p = p.replace(/^/mg, indentStr);
- }
- paragraphs[i] = p;
- }
- var s = paragraphs.join(wrap_char+wrap_char);
- if ('assign' in params)
- {
- assignVar(params.assign, s, data);
- return '';
- }
- return s;
- }
- );
-
-
- /**
- register modifiers
- */
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'capitalize',
- function(s, upDigits, lcRest) {
- if (typeof s != 'string') {
- return s;
- }
- var re = new RegExp(upDigits ? '[^a-zA-Z_\u00E0-\u00FC]+' : '[^a-zA-Z0-9_\u00E0-\u00FC]');
- var found = null;
- var res = '';
- if (lcRest) {
- s = s.toLowerCase();
- }
- for (found=s.match(re); found; found=s.match(re))
- {
- var word = s.slice(0,found.index);
- if (word.match(/\d/))
- {
- res += word;
- }
- else
- {
- res += word.charAt(0).toUpperCase() + word.slice(1);
- }
- res += s.slice(found.index, found.index+found[0].length);
- s = s.slice(found.index+found[0].length);
- }
- if (s.match(/\d/))
- {
- return res + s;
- }
- return res + s.charAt(0).toUpperCase() + s.slice(1);
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'cat',
- function(s, value)
- {
- value = value ? value : '';
- return new String(s) + value;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'count',
- function(v, recursive)
- {
- if (v === null || typeof v === 'undefined') {
- return 0;
- } else if (v.constructor !== Array && v.constructor !== Object) {
- return 1;
- }
-
- recursive = Boolean(recursive);
- var k, cnt = 0;
- for (k in v)
- {
- if (v.hasOwnProperty(k))
- {
- cnt++;
- if (recursive && v[k] && (v[k].constructor === Array || v[k].constructor === Object)) {
- cnt += modifiers.count(v[k], true);
- }
- }
- }
- return cnt;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'count_characters',
- function(s, includeWhitespaces)
- {
- s = new String(s);
- return includeWhitespaces ? s.length : s.replace(/\s/g,'').length;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'count_paragraphs',
- function(s)
- {
- var found = (new String(s)).match(/\n+/g);
- if (found)
- {
- return found.length+1;
- }
- return 1;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'count_sentences',
- function(s)
- {
- if (typeof s == 'string')
- {
- var found = s.match(/[^\s]\.(?!\w)/g);
- if (found)
- {
- return found.length;
- }
- }
- return 0;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'count_words',
- function(s)
- {
- if (typeof s == 'string')
- {
- var found = s.match(/\w+/g);
- if (found)
- {
- return found.length;
- }
- }
- return 0;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'date_format',
- function(s, fmt, defaultDate)
- {
- return jSmart.prototype.PHPJS('strftime','date_format').strftime(fmt?fmt:'%b %e, %Y', jSmart.prototype.makeTimeStamp(s?s:defaultDate));
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'defaultValue',
- function(s, value)
- {
- return (s && s!='null' && s!='undefined') ? s : (value ? value : '');
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'unescape',
- function(s, esc_type, char_set)
- {
- s = new String(s);
- esc_type = esc_type || 'html';
- char_set = char_set || 'UTF-8';
-
- switch (esc_type)
- {
- case 'html':
- return s.replace(/</g, '<').replace(/>/g,'>').replace(/'/g,"'").replace(/"/g,'"');
- case 'entity':
- case 'htmlall':
- return jSmart.prototype.PHPJS('html_entity_decode','unescape').html_entity_decode(s, 1);
- case 'url':
- return jSmart.prototype.PHPJS('rawurldecode','unescape').rawurldecode(s);
- };
- return s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'escape',
- function(s, esc_type, char_set, double_encode)
- {
- s = new String(s);
- esc_type = esc_type || 'html';
- char_set = char_set || 'UTF-8';
- double_encode = (typeof double_encode != 'undefined') ? Boolean(double_encode) : true;
-
- switch (esc_type)
- {
- case 'html':
- if (double_encode) {
- s = s.replace(/&/g, '&');
- }
- return s.replace(/</g,'<').replace(/>/g,'>').replace(/'/g,''').replace(/"/g,'"');
- case 'htmlall':
- return jSmart.prototype.PHPJS('htmlentities','escape').htmlentities(s, 3, char_set);
- case 'url':
- return jSmart.prototype.PHPJS('rawurlencode','escape').rawurlencode(s);
- case 'urlpathinfo':
- return jSmart.prototype.PHPJS('rawurlencode','escape').rawurlencode(s).replace(/%2F/g, '/');
- case 'quotes':
- return s.replace(/(^|[^\\])'/g, "$1\\'");
- case 'hex':
- var res = '';
- for (var i=0; i<s.length; ++i)
- {
- res += '%' + jSmart.prototype.PHPJS('bin2hex','escape').bin2hex(s.substr(i,1)).toLowerCase();
- }
- return res;
- case 'hexentity':
- var res = '';
- for (var i=0; i<s.length; ++i) {
- res += '&#x' + jSmart.prototype.PHPJS('bin2hex','escape').bin2hex(s.substr(i,1)) + ';';
- }
- return res;
- case 'decentity':
- var res = '';
- for (var i=0; i<s.length; ++i) {
- res += '&#' + jSmart.prototype.PHPJS('ord','escape').ord(s.substr(i,1)) + ';';
- }
- return res;
- case 'mail':
- return s.replace(/@/g,' [AT] ').replace(/[.]/g,' [DOT] ');
- case 'nonstd':
- var res = '';
- for (var i=0; i<s.length; ++i)
- {
- var _ord = jSmart.prototype.PHPJS('ord','escape').ord(s.substr(i,1));
- if (_ord >= 126) {
- res += '&#' + _ord + ';';
- } else {
- res += s.substr(i, 1);
- }
-
- }
- return res;
- case 'javascript':
- return s.replace(/\\/g,'\\\\').replace(/'/g,"\\'").replace(/"/g,'\\"').replace(/\r/g,'\\r').replace(/\n/g,'\\n').replace(/<\//g,'<\/');
- };
- return s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'indent',
- function(s, repeat, indentWith)
- {
- s = new String(s);
- repeat = repeat ? repeat : 4;
- indentWith = indentWith ? indentWith : ' ';
-
- var indentStr = '';
- while (repeat--)
- {
- indentStr += indentWith;
- }
-
- var tail = s.match(/\n+$/);
- return indentStr + s.replace(/\n+$/,'').replace(/\n/g,'\n'+indentStr) + (tail ? tail[0] : '');
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'lower',
- function(s)
- {
- return new String(s).toLowerCase();
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'nl2br',
- function(s)
- {
- return new String(s).replace(/\n/g,'<br />\n');
- }
- );
-
- /**
- only modifiers (flags) 'i' and 'm' are supported
- backslashes should be escaped e.g. \\s
- */
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'regex_replace',
- function(s, re, replaceWith)
- {
- var pattern = re.match(/^ *\/(.*)\/(.*) *$/);
- return (new String(s)).replace(new RegExp(pattern[1],'g'+(pattern.length>1?pattern[2]:'')), replaceWith);
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'replace',
- function(s, search, replaceWith)
- {
- if (!search)
- {
- return s;
- }
- s = new String(s);
- search = new String(search);
- replaceWith = new String(replaceWith);
- var res = '';
- var pos = -1;
- for (pos=s.indexOf(search); pos>=0; pos=s.indexOf(search))
- {
- res += s.slice(0,pos) + replaceWith;
- pos += search.length;
- s = s.slice(pos);
- }
- return res + s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'spacify',
- function(s, space)
- {
- if (!space)
- {
- space = ' ';
- }
- return (new String(s)).replace(/(\n|.)(?!$)/g,'$1'+space);
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'noprint',
- function(s)
- {
- return '';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'string_format',
- function(s, fmt)
- {
- return jSmart.prototype.PHPJS('sprintf','string_format').sprintf(fmt,s);
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'strip',
- function(s, replaceWith)
- {
- replaceWith = replaceWith ? replaceWith : ' ';
- return (new String(s)).replace(/[\s]+/g, replaceWith);
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'strip_tags',
- function(s, addSpace)
- {
- addSpace = (addSpace==null) ? true : addSpace;
- return (new String(s)).replace(/<[^>]*?>/g, addSpace ? ' ' : '');
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'truncate',
- function(s, length, etc, breakWords, middle)
- {
- s = new String(s);
- length = length ? length : 80;
- etc = (etc!=null) ? etc : '...';
-
- if (s.length <= length)
- {
- return s;
- }
-
- length -= Math.min(length,etc.length);
- if (middle)
- {
- //one of floor()'s should be replaced with ceil() but it so in Smarty
- return s.slice(0,Math.floor(length/2)) + etc + s.slice(s.length-Math.floor(length/2));
- }
-
- if (!breakWords)
- {
- s = s.slice(0,length+1).replace(/\s+?(\S+)?$/,'');
- }
-
- return s.slice(0,length) + etc;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'upper',
- function(s)
- {
- return (new String(s)).toUpperCase();
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'wordwrap',
- function(s, width, wrapWith, breakWords)
- {
- width = width || 80;
- wrapWith = wrapWith || '\n';
-
- var lines = (new String(s)).split('\n');
- for (var i=0; i<lines.length; ++i)
- {
- var line = lines[i];
- var parts = ''
- while (line.length > width)
- {
- var pos = 0;
- var found = line.slice(pos).match(/\s+/);
- for (;found && (pos+found.index)<=width; found=line.slice(pos).match(/\s+/))
- {
- pos += found.index + found[0].length;
- }
- pos = pos || (breakWords ? width : (found ? found.index+found[0].length : line.length));
- parts += line.slice(0,pos).replace(/\s+$/,'');// + wrapWith;
- if (pos < line.length)
- {
- parts += wrapWith;
- }
- line = line.slice(pos);
- }
- lines[i] = parts + line;
- }
- return lines.join('\n');
- }
- );
-
-
- String.prototype.fetch = function(data)
- {
- var tpl = new jSmart(this);
- return tpl.fetch(data);
- };
-
- if (typeof module === "object" && module && typeof module.exports === "object") {
- module.exports = jSmart;
- } else {
- if (typeof global !== "undefined") {
- global.jSmart = jSmart;
- }
-
- if (typeof define === "function" && define.amd) {
- define("jSmart", [], function () { return jSmart; });
- }
- }
-})();
+++ /dev/null
-/*!
- * jSmart Javascript template engine
- * https://github.com/umakantp/jsmart
- *
- * Copyright 2011-2015, Max Miroshnikov <miroshnikov at gmail dot com>
- * Umakant Patil <me at umakantpatil dot.com>
- * jSmart is licensed under the GNU Lesser General Public License
- * http://opensource.org/licenses/LGPL-3.0
- */
-
-
-(function() {
-
- /**
- merges two or more objects into one
- shallow copy for objects
- */
- function obMerge(ob1, ob2 /*, ...*/)
- {
- for (var i=1; i<arguments.length; ++i)
- {
- for (var nm in arguments[i])
- {
- ob1[nm] = arguments[i][nm];
- }
- }
- return ob1;
- }
-
- /**
- @return number of own properties in ob
- */
- function countProperties(ob)
- {
- var count = 0;
- for (var nm in ob)
- {
- if (ob.hasOwnProperty(nm))
- {
- count++;
- }
- }
- return count;
- }
-
- /**
- IE workaround
- */
- function findInArray(a, v)
- {
- if (Array.prototype.indexOf) {
- return a.indexOf(v);
- }
- for (var i=0; i < a.length; ++i)
- {
- if (a[i] === v)
- {
- return i;
- }
- }
- return -1;
- }
-
- function evalString(s)
- {
- return s.replace(/\\t/,'\t').replace(/\\n/,'\n').replace(/\\(['"\\])/g,'$1');
- }
-
- /**
- @return s trimmed and without quotes
- */
- function trimQuotes(s)
- {
- return evalString(s.replace(/^['"](.*)['"]$/,'$1')).replace(/^\s+|\s+$/g,'');
- }
-
- /**
- finds first {tag} in string
- @param re string with regular expression or an empty string to find any tag
- @return null or s.match(re) result object where
- [0] - full tag matched with delimiters (and whitespaces at the begin and the end): { tag }
- [1] - found part from passed re
- [index] - position of tag starting { in s
- */
- function findTag(re,s)
- {
- var openCount = 0;
- var offset = 0;
- var ldelim = jSmart.prototype.left_delimiter;
- var rdelim = jSmart.prototype.right_delimiter;
- var skipInWS = jSmart.prototype.auto_literal;
-
- var reAny = /^\s*(.+)\s*$/i;
- var reTag = re ? new RegExp('^\\s*('+re+')\\s*$','i') : reAny;
-
- for (var i=0; i<s.length; ++i)
- {
- if (s.substr(i,ldelim.length) == ldelim)
- {
- if (skipInWS && i+1 < s.length && s.substr(i+1,1).match(/\s/))
- {
- continue;
- }
- if (!openCount)
- {
- s = s.slice(i);
- offset += parseInt(i);
- i = 0;
- }
- ++openCount;
- }
- else if (s.substr(i,rdelim.length) == rdelim)
- {
- if (skipInWS && i-1 >= 0 && s.substr(i-1,1).match(/\s/))
- {
- continue;
- }
- if (!--openCount)
- {
- var sTag = s.slice(ldelim.length,i).replace(/[\r\n]/g, ' ');
- var found = sTag.match(reTag);
- if (found)
- {
- found.index = offset;
- found[0] = s.slice(0,i+rdelim.length);
- return found;
- }
- }
- if (openCount < 0) //ignore any number of unmatched right delimiters
- {
- openCount = 0;
- }
- }
- }
- return null;
- }
-
- function findCloseTag(reClose,reOpen,s)
- {
- var sInner = '';
- var closeTag = null;
- var openTag = null;
- var findIndex = 0;
-
- do
- {
- if (closeTag)
- {
- findIndex += closeTag[0].length;
- }
- closeTag = findTag(reClose,s);
- if (!closeTag)
- {
- throw new Error('Unclosed {'+reOpen+'}');
- }
- sInner += s.slice(0,closeTag.index);
- findIndex += closeTag.index;
- s = s.slice(closeTag.index+closeTag[0].length);
-
- openTag = findTag(reOpen,sInner);
- if (openTag)
- {
- sInner = sInner.slice(openTag.index+openTag[0].length);
- }
- }
- while (openTag);
-
- closeTag.index = findIndex;
- return closeTag;
- }
-
- function findElseTag(reOpen, reClose, reElse, s)
- {
- var offset = 0;
- for (var elseTag=findTag(reElse,s); elseTag; elseTag=findTag(reElse,s))
- {
- var openTag = findTag(reOpen,s);
- if (!openTag || openTag.index > elseTag.index)
- {
- elseTag.index += offset;
- return elseTag;
- }
- else
- {
- s = s.slice(openTag.index+openTag[0].length);
- offset += openTag.index+openTag[0].length;
- var closeTag = findCloseTag(reClose,reOpen,s);
- s = s.slice(closeTag.index + closeTag[0].length);
- offset += closeTag.index + closeTag[0].length;
- }
- }
- return null;
- }
-
- function execute(code, data)
- {
- if (typeof(code) == 'string')
- {
- with ({'__code':code})
- {
- with (modifiers)
- {
- with (data)
- {
- try {
- return eval(__code);
- }
- catch(e)
- {
- throw new Error(e.message + ' in \n' + code);
- }
- }
- }
- }
- }
- return code;
- }
-
- /**
- * Execute function when we have a object.
- *
- * @param object obj Object of the function to be called.
- * @param array args Arguments to pass to a function.
- *
- * @return
- * @throws Error If function obj does not exists.
- */
- function executeByFuncObject(obj, args) {
- try {
- return obj.apply(this, args);
- } catch (e) {
- throw new Error(e.message);
- }
- }
-
- function assignVar(nm, val, data)
- {
- if (nm.match(/\[\]$/)) //ar[] =
- {
- data[ nm.replace(/\[\]$/,'') ].push(val);
- }
- else
- {
- data[nm] = val;
- }
- }
-
- var buildInFunctions =
- {
- expression:
- {
- parse: function(s, tree)
- {
- var e = parseExpression(s);
-
- tree.push({
- type: 'build-in',
- name: 'expression',
- expression: e.tree,
- params: parseParams(s.slice(e.value.length).replace(/^\s+|\s+$/g,''))
- });
-
- return e.tree;
-
- },
- process: function(node, data)
- {
- var params = getActualParamValues(node.params, data);
- var res = process([node.expression],data);
-
- if (findInArray(params, 'nofilter') < 0)
- {
- for (var i=0; i<default_modifiers.length; ++i)
- {
- var m = default_modifiers[i];
- m.params.__parsed[0] = {type:'text', data:res};
- res = process([m],data);
- }
- if (escape_html)
- {
- res = modifiers.escape(res);
- }
- res = applyFilters(varFilters,res);
-
- if (tpl_modifiers.length) {
- __t = function(){ return res; }
- res = process(tpl_modifiers,data);
- }
- }
- return res;
- }
- },
-
- operator:
- {
- process: function(node, data)
- {
- var params = getActualParamValues(node.params, data);
- var arg1 = params[0];
-
- if (node.optype == 'binary')
- {
- var arg2 = params[1];
- if (node.op == '=')
- {
- getVarValue(node.params.__parsed[0], data, arg2);
- return '';
- }
- else if (node.op.match(/(\+=|-=|\*=|\/=|%=)/))
- {
- arg1 = getVarValue(node.params.__parsed[0], data);
- switch (node.op)
- {
- case '+=': arg1+=arg2; break;
- case '-=': arg1-=arg2; break;
- case '*=': arg1*=arg2; break;
- case '/=': arg1/=arg2; break;
- case '%=': arg1%=arg2; break;
- }
- return getVarValue(node.params.__parsed[0], data, arg1);
- }
- else if (node.op.match(/div/))
- {
- return (node.op!='div')^(arg1%arg2==0);
- }
- else if (node.op.match(/even/))
- {
- return (node.op!='even')^((arg1/arg2)%2==0);
- }
- else if (node.op.match(/xor/))
- {
- return (arg1||arg2) && !(arg1&&arg2);
- }
-
- switch (node.op)
- {
- case '==': return arg1==arg2;
- case '!=': return arg1!=arg2;
- case '+': return Number(arg1)+Number(arg2);
- case '-': return Number(arg1)-Number(arg2);
- case '*': return Number(arg1)*Number(arg2);
- case '/': return Number(arg1)/Number(arg2);
- case '%': return Number(arg1)%Number(arg2);
- case '&&': return arg1&&arg2;
- case '||': return arg1||arg2;
- case '<': return arg1<arg2;
- case '<=': return arg1<=arg2;
- case '>': return arg1>arg2;
- case '>=': return arg1>=arg2;
- case '===': return arg1===arg2;
- case '!==': return arg1!==arg2;
- }
- }
- else if (node.op == '!')
- {
- return !arg1;
- }
- else
- {
- var isVar = node.params.__parsed[0].type == 'var';
- if (isVar)
- {
- arg1 = getVarValue(node.params.__parsed[0], data);
- }
- var v = arg1;
- if (node.optype == 'pre-unary')
- {
- switch (node.op)
- {
- case '-': v=-arg1; break;
- case '++': v=++arg1; break;
- case '--': v=--arg1; break;
- }
- if (isVar)
- {
- getVarValue(node.params.__parsed[0], data, arg1);
- }
- }
- else
- {
- switch (node.op)
- {
- case '++': arg1++; break;
- case '--': arg1--; break;
- }
- getVarValue(node.params.__parsed[0], data, arg1);
- }
- return v;
- }
- }
- },
-
- section:
- {
- type: 'block',
- parse: function(params, tree, content)
- {
- var subTree = [];
- var subTreeElse = [];
- tree.push({
- type: 'build-in',
- name: 'section',
- params: params,
- subTree: subTree,
- subTreeElse: subTreeElse
- });
-
- var findElse = findElseTag('section [^}]+', '\/section', 'sectionelse', content);
- if (findElse)
- {
- parse(content.slice(0,findElse.index),subTree);
- parse(content.slice(findElse.index+findElse[0].length).replace(/^[\r\n]/,''), subTreeElse);
- }
- else
- {
- parse(content, subTree);
- }
- },
-
- process: function(node, data)
- {
- var params = getActualParamValues(node.params, data);
-
- var props = {};
- data.smarty.section[params.__get('name',null,0)] = props;
-
- var show = params.__get('show',true);
- props.show = show;
- if (!show)
- {
- return process(node.subTreeElse, data);
- }
-
- var from = parseInt(params.__get('start',0));
- var to = (params.loop instanceof Object) ? countProperties(params.loop) : isNaN(params.loop) ? 0 : parseInt(params.loop);
- var step = parseInt(params.__get('step',1));
- var max = parseInt(params.__get('max'));
- if (isNaN(max))
- {
- max = Number.MAX_VALUE;
- }
-
- if (from < 0)
- {
- from += to;
- if (from < 0)
- {
- from = 0;
- }
- }
- else if (from >= to)
- {
- from = to ? to-1 : 0;
- }
-
- var count = 0;
- var loop = 0;
- var i = from;
- for (; i>=0 && i<to && count<max; i+=step,++count)
- {
- loop = i;
- }
- props.total = count;
- props.loop = count; //? - because it is so in Smarty
-
- count = 0;
- var s = '';
- for (i=from; i>=0 && i<to && count<max; i+=step,++count)
- {
- if (data.smarty['break'])
- {
- break;
- }
-
- props.first = (i==from);
- props.last = ((i+step)<0 || (i+step)>=to);
- props.index = i;
- props.index_prev = i-step;
- props.index_next = i+step;
- props.iteration = props.rownum = count+1;
-
- s += process(node.subTree, data);
- data.smarty['continue'] = false;
- }
- data.smarty['break'] = false;
-
- if (count)
- {
- return s;
- }
- return process(node.subTreeElse, data);
- }
- },
-
- setfilter:
- {
- type: 'block',
- parseParams: function(paramStr)
- {
- return [parseExpression('__t()|' + paramStr).tree];
- },
-
- parse: function(params, tree, content)
- {
- tree.push({
- type: 'build-in',
- name: 'setfilter',
- params: params,
- subTree: parse(content,[])
- });
- },
-
- process: function(node, data)
- {
- tpl_modifiers = node.params;
- var s = process(node.subTree, data);
- tpl_modifiers = [];
- return s;
- }
- },
-
- 'for':
- {
- type: 'block',
- parseParams: function(paramStr)
- {
- var res = paramStr.match(/^\s*\$(\w+)\s*=\s*([^\s]+)\s*to\s*([^\s]+)\s*(?:step\s*([^\s]+))?\s*(.*)$/);
- if (!res)
- {
- throw new Error('Invalid {for} parameters: '+paramStr);
- }
- return parseParams("varName='"+res[1]+"' from="+res[2]+" to="+res[3]+" step="+(res[4]?res[4]:'1')+" "+res[5]);
- },
-
- parse: function(params, tree, content)
- {
- var subTree = [];
- var subTreeElse = [];
- tree.push({
- type: 'build-in',
- name: 'for',
- params: params,
- subTree: subTree,
- subTreeElse: subTreeElse
- });
-
- var findElse = findElseTag('for\\s[^}]+', '\/for', 'forelse', content);
- if (findElse)
- {
- parse(content.slice(0,findElse.index),subTree);
- parse(content.slice(findElse.index+findElse[0].length), subTreeElse);
- }
- else
- {
- parse(content, subTree);
- }
- },
-
- process: function(node, data)
- {
- var params = getActualParamValues(node.params, data);
- var from = parseInt(params.__get('from'));
- var to = parseInt(params.__get('to'));
- var step = parseInt(params.__get('step'));
- if (isNaN(step))
- {
- step = 1;
- }
- var max = parseInt(params.__get('max'));
- if (isNaN(max))
- {
- max = Number.MAX_VALUE;
- }
-
- var count = 0;
- var s = '';
- var total = Math.min( Math.ceil( ((step > 0 ? to-from : from-to)+1) / Math.abs(step) ), max);
-
- for (var i=parseInt(params.from); count<total; i+=step,++count)
- {
- if (data.smarty['break'])
- {
- break;
- }
- data[params.varName] = i;
- s += process(node.subTree, data);
- data.smarty['continue'] = false;
- }
- data.smarty['break'] = false;
-
- if (!count)
- {
- s = process(node.subTreeElse, data);
- }
- return s;
- }
- },
-
- 'if':
- {
- type: 'block',
- parse: function(params, tree, content)
- {
- var subTreeIf = [];
- var subTreeElse = [];
- tree.push({
- type: 'build-in',
- name: 'if',
- params: params,
- subTreeIf: subTreeIf,
- subTreeElse: subTreeElse
- });
-
- var findElse = findElseTag('if\\s+[^}]+', '\/if', 'else[^}]*', content);
- if (findElse)
- {
- parse(content.slice(0,findElse.index),subTreeIf);
-
- content = content.slice(findElse.index+findElse[0].length);
- var findElseIf = findElse[1].match(/^else\s*if(.*)/);
- if (findElseIf)
- {
- buildInFunctions['if'].parse(parseParams(findElseIf[1]), subTreeElse, content.replace(/^\n/,''));
- }
- else
- {
- parse(content.replace(/^\n/,''), subTreeElse);
- }
- }
- else
- {
- parse(content, subTreeIf);
- }
- },
-
- process: function(node, data) {
- var value = getActualParamValues(node.params,data)[0];
- // Zero length arrays or empty associative arrays are false in PHP.
- if (value && !((value instanceof Array && value.length == 0)
- || (typeof value == 'object' && isEmptyObject(value)))
- ) {
- return process(node.subTreeIf, data);
- } else {
- return process(node.subTreeElse, data);
- }
- }
- },
-
- foreach:
- {
- type: 'block',
- parseParams: function(paramStr)
- {
- var params = {};
- var res = paramStr.match(/^\s*([$].+)\s*as\s*[$](\w+)\s*(=>\s*[$](\w+))?\s*$/i);
- if (res) //Smarty 3.x syntax => Smarty 2.x syntax
- {
- paramStr = 'from='+res[1] + ' item='+(res[4]||res[2]);
- if (res[4])
- {
- paramStr += ' key='+res[2];
- }
- }
- return parseParams(paramStr);
- },
-
- parse: function(params, tree, content)
- {
- var subTree = [];
- var subTreeElse = [];
- tree.push({
- type: 'build-in',
- name: 'foreach',
- params: params,
- subTree: subTree,
- subTreeElse: subTreeElse
- });
-
- var findElse = findElseTag('foreach\\s[^}]+', '\/foreach', 'foreachelse', content);
- if (findElse)
- {
- parse(content.slice(0,findElse.index),subTree);
- parse(content.slice(findElse.index+findElse[0].length).replace(/^[\r\n]/,''), subTreeElse);
- }
- else
- {
- parse(content, subTree);
- }
- },
-
- process: function(node, data)
- {
- var params = getActualParamValues(node.params, data);
- var a = params.from;
- if (typeof a == 'undefined')
- {
- a = [];
- }
- if (typeof a != 'object')
- {
- a = [a];
- }
-
- var total = countProperties(a);
-
- data[params.item+'__total'] = total;
- if ('name' in params)
- {
- data.smarty.foreach[params.name] = {};
- data.smarty.foreach[params.name].total = total;
- }
-
- var s = '';
- var i=0;
- for (var key in a)
- {
- if (!a.hasOwnProperty(key))
- {
- continue;
- }
-
- if (data.smarty['break'])
- {
- break;
- }
-
- data[params.item+'__key'] = isNaN(key) ? key : parseInt(key);
- if ('key' in params)
- {
- data[params.key] = data[params.item+'__key'];
- }
- data[params.item] = a[key];
- data[params.item+'__index'] = parseInt(i);
- data[params.item+'__iteration'] = parseInt(i+1);
- data[params.item+'__first'] = (i===0);
- data[params.item+'__last'] = (i==total-1);
-
- if ('name' in params)
- {
- data.smarty.foreach[params.name].index = parseInt(i);
- data.smarty.foreach[params.name].iteration = parseInt(i+1);
- data.smarty.foreach[params.name].first = (i===0) ? 1 : '';
- data.smarty.foreach[params.name].last = (i==total-1) ? 1 : '';
- }
-
- ++i;
-
- s += process(node.subTree, data);
- data.smarty['continue'] = false;
- }
- data.smarty['break'] = false;
-
- data[params.item+'__show'] = (i>0);
- if (params.name)
- {
- data.smarty.foreach[params.name].show = (i>0) ? 1 : '';
- }
- if (i>0)
- {
- return s;
- }
- return process(node.subTreeElse, data);
- }
- },
-
- 'function':
- {
- type: 'block',
- parse: function(params, tree, content)
- {
- var subTree = [];
- plugins[trimQuotes(params.name?params.name:params[0])] =
- {
- type: 'function',
- subTree: subTree,
- defautParams: params,
- process: function(params, data)
- {
- var defaults = getActualParamValues(this.defautParams,data);
- delete defaults.name;
- return process(this.subTree, obMerge({},data,defaults,params));
- }
- };
- parse(content, subTree);
- }
- },
-
- php:
- {
- type: 'block',
- parse: function(params, tree, content) {}
- },
-
- 'extends':
- {
- type: 'function',
- parse: function(params, tree)
- {
- tree.splice(0,tree.length);
- getTemplate(trimQuotes(params.file?params.file:params[0]),tree);
- }
- },
-
- block:
- {
- type: 'block',
- parse: function(params, tree, content)
- {
- tree.push({
- type: 'build-in',
- name: 'block',
- params: params
- });
- params.append = findInArray(params,'append') >= 0;
- params.prepend = findInArray(params,'prepend') >= 0;
- params.hide = findInArray(params,'hide') >= 0;
- params.hasChild = params.hasParent = false;
-
- onParseVar = function(nm)
- {
- if (nm.match(/^\s*[$]smarty.block.child\s*$/))
- {
- params.hasChild = true;
- }
- if (nm.match(/^\s*[$]smarty.block.parent\s*$/))
- {
- params.hasParent = true;
- }
- }
- var tree = parse(content, []);
- onParseVar = function(nm) {}
-
- var blockName = trimQuotes(params.name?params.name:params[0]);
- if (!(blockName in blocks))
- {
- blocks[blockName] = [];
- }
- blocks[blockName].push({tree:tree, params:params});
- },
-
- process: function(node, data)
- {
- data.smarty.block.parent = data.smarty.block.child = '';
- var blockName = trimQuotes(node.params.name?node.params.name:node.params[0]);
- this.processBlocks(blocks[blockName], blocks[blockName].length-1, data);
- return data.smarty.block.child;
- },
-
- processBlocks: function(blockAncestry, i, data)
- {
- if (!i && blockAncestry[i].params.hide) {
- data.smarty.block.child = '';
- return;
- }
- var append = true;
- var prepend = false;
- for (; i>=0; --i)
- {
- if (blockAncestry[i].params.hasParent)
- {
- var tmpChild = data.smarty.block.child;
- data.smarty.block.child = '';
- this.processBlocks(blockAncestry, i-1, data);
- data.smarty.block.parent = data.smarty.block.child;
- data.smarty.block.child = tmpChild;
- }
-
- var tmpChild = data.smarty.block.child;
- var s = process(blockAncestry[i].tree, data);
- data.smarty.block.child = tmpChild;
-
- if (blockAncestry[i].params.hasChild)
- {
- data.smarty.block.child = s;
- }
- else if (append)
- {
- data.smarty.block.child = s + data.smarty.block.child;
- }
- else if (prepend)
- {
- data.smarty.block.child += s;
- }
- append = blockAncestry[i].params.append;
- prepend = blockAncestry[i].params.prepend;
- }
- }
- },
-
- strip:
- {
- type: 'block',
- parse: function(params, tree, content)
- {
- parse(content.replace(/[ \t]*[\r\n]+[ \t]*/g, ''), tree);
- }
- },
-
- literal:
- {
- type: 'block',
- parse: function(params, tree, content)
- {
- parseText(content, tree);
- }
- },
-
- ldelim:
- {
- type: 'function',
- parse: function(params, tree)
- {
- parseText(jSmart.prototype.left_delimiter, tree);
- }
- },
-
- rdelim:
- {
- type: 'function',
- parse: function(params, tree)
- {
- parseText(jSmart.prototype.right_delimiter, tree);
- }
- },
-
- 'while':
- {
- type: 'block',
- parse: function(params, tree, content)
- {
- tree.push({
- type: 'build-in',
- name: 'while',
- params: params,
- subTree: parse(content, [])
- });
- },
-
- process: function(node, data)
- {
- var s = '';
- while (getActualParamValues(node.params,data)[0])
- {
- if (data.smarty['break'])
- {
- break;
- }
- s += process(node.subTree, data);
- data.smarty['continue'] = false;
- }
- data.smarty['break'] = false;
- return s;
- }
- }
- };
-
- var plugins = {};
- var modifiers = {};
- var files = {};
- var blocks = null;
- var scripts = null;
- var tpl_modifiers = [];
-
- function parse(s, tree)
- {
- for (var openTag=findTag('',s); openTag; openTag=findTag('',s))
- {
- if (openTag.index)
- {
- parseText(s.slice(0,openTag.index),tree);
- }
- s = s.slice(openTag.index + openTag[0].length);
-
- var res = openTag[1].match(/^\s*(\w+)(.*)$/);
- if (res) //function
- {
- var nm = res[1];
- var paramStr = (res.length>2) ? res[2].replace(/^\s+|\s+$/g,'') : '';
-
- if (nm in buildInFunctions)
- {
- var buildIn = buildInFunctions[nm];
- var params = ('parseParams' in buildIn ? buildIn.parseParams : parseParams)(paramStr);
- if (buildIn.type == 'block')
- {
- s = s.replace(/^\n/,''); //remove new line after block open tag (like in Smarty)
- var closeTag = findCloseTag('\/'+nm, nm+' +[^}]*', s);
- buildIn.parse(params, tree, s.slice(0,closeTag.index));
- s = s.slice(closeTag.index+closeTag[0].length);
- }
- else
- {
- buildIn.parse(params, tree);
- if (nm == 'extends')
- {
- tree = []; //throw away further parsing except for {block}
- }
- }
- s = s.replace(/^\n/,'');
- }
- else if (nm in plugins)
- {
- var plugin = plugins[nm];
- if (plugin.type == 'block')
- {
- var closeTag = findCloseTag('\/'+nm, nm+' +[^}]*', s);
- parsePluginBlock(nm, parseParams(paramStr), tree, s.slice(0,closeTag.index));
- s = s.slice(closeTag.index+closeTag[0].length);
- }
- else if (plugin.type == 'function')
- {
- parsePluginFunc(nm, parseParams(paramStr), tree);
- }
- if (nm=='append' || nm=='assign' || nm=='capture' || nm=='eval' || nm=='include')
- {
- s = s.replace(/^\n/,'');
- }
- }
- else //variable
- {
- buildInFunctions.expression.parse(openTag[1],tree);
- }
- }
- else //variable
- {
- var node = buildInFunctions.expression.parse(openTag[1],tree);
- if (node.type=='build-in' && node.name=='operator' && node.op == '=')
- {
- s = s.replace(/^\n/,'');
- }
- }
- }
- if (s)
- {
- parseText(s, tree);
- }
- return tree;
- }
-
- function parseText(text, tree)
- {
- if (parseText.parseEmbeddedVars)
- {
- var re = /([$][\w@]+)|`([^`]*)`/;
- for (var found=re.exec(text); found; found=re.exec(text))
- {
- tree.push({type: 'text', data: text.slice(0,found.index)});
- tree.push( parseExpression(found[1] ? found[1] : found[2]).tree );
- text = text.slice(found.index + found[0].length);
- }
- }
- tree.push({type: 'text', data: text});
- return tree;
- }
-
- function parseFunc(name, params, tree)
- {
- params.__parsed.name = parseText(name,[])[0];
- tree.push({
- type: 'plugin',
- name: '__func',
- params: params
- });
- return tree;
- }
-
- function parseOperator(op, type, precedence, tree)
- {
- tree.push({
- type: 'build-in',
- name: 'operator',
- op: op,
- optype: type,
- precedence: precedence,
- params: {}
- });
- }
-
- function parseVar(s, e, nm)
- {
- var rootName = e.token;
- var parts = [{type:'text', data:nm.replace(/^(\w+)@(key|index|iteration|first|last|show|total)/gi, "$1__$2")}];
-
- var re = /^(?:\.|\s*->\s*|\[\s*)/;
- for (var op=s.match(re); op; op=s.match(re))
- {
- e.token += op[0];
- s = s.slice(op[0].length);
-
- var eProp = {value:'', tree:[]};
- if (op[0].match(/\[/))
- {
- eProp = parseExpression(s);
- if (eProp)
- {
- e.token += eProp.value;
- parts.push( eProp.tree );
- s = s.slice(eProp.value.length);
- }
-
- var closeOp = s.match(/\s*\]/);
- if (closeOp)
- {
- e.token += closeOp[0];
- s = s.slice(closeOp[0].length);
- }
- }
- else
- {
- var parseMod = parseModifiers.stop;
- parseModifiers.stop = true;
- if (lookUp(s,eProp))
- {
- e.token += eProp.value;
- var part = eProp.tree[0];
- if (part.type == 'plugin' && part.name == '__func')
- {
- part.hasOwner = true;
- }
- parts.push( part );
- s = s.slice(eProp.value.length);
- }
- else
- {
- eProp = false;
- }
- parseModifiers.stop = parseMod;
- }
-
- if (!eProp)
- {
- parts.push({type:'text', data:''});
- }
- }
-
- e.tree.push({type: 'var', parts: parts});
-
- e.value += e.token.substr(rootName.length);
-
- onParseVar(e.token);
-
- return s;
- }
-
- function onParseVar(nm) {}
-
-
- var tokens =
- [
- {
- re: /^\$([\w@]+)/, //var
- parse: function(e, s)
- {
- parseModifiers(parseVar(s, e, RegExp.$1), e);
- }
- },
- {
- re: /^(true|false)/i, //bool
- parse: function(e, s)
- {
- parseText(e.token.match(/true/i) ? '1' : '', e.tree);
- }
- },
- {
- re: /^'([^'\\]*(?:\\.[^'\\]*)*)'/, //single quotes
- parse: function(e, s)
- {
- parseText(evalString(RegExp.$1), e.tree);
- parseModifiers(s, e);
- }
- },
- {
- re: /^"([^"\\]*(?:\\.[^"\\]*)*)"/, //double quotes
- parse: function(e, s)
- {
- var v = evalString(RegExp.$1);
- var isVar = v.match(tokens[0].re);
- if (isVar)
- {
- var eVar = {token:isVar[0], tree:[]};
- parseVar(v, eVar, isVar[1]);
- if (eVar.token.length == v.length)
- {
- e.tree.push( eVar.tree[0] );
- return;
- }
- }
- parseText.parseEmbeddedVars = true;
- e.tree.push({
- type: 'plugin',
- name: '__quoted',
- params: {__parsed: parse(v,[])}
- });
- parseText.parseEmbeddedVars = false;
- parseModifiers(s, e);
- }
- },
- {
- re: /^(\w+)\s*[(]([)]?)/, //func()
- parse: function(e, s)
- {
- var fnm = RegExp.$1;
- var noArgs = RegExp.$2;
- var params = parseParams(noArgs?'':s,/^\s*,\s*/);
- parseFunc(fnm, params, e.tree);
- e.value += params.toString();
- parseModifiers(s.slice(params.toString().length), e);
- }
- },
- {
- re: /^\s*\(\s*/, //expression in parentheses
- parse: function(e, s)
- {
- var parens = [];
- e.tree.push(parens);
- parens.parent = e.tree;
- e.tree = parens;
- }
- },
- {
- re: /^\s*\)\s*/,
- parse: function(e, s)
- {
- if (e.tree.parent) //it may be the end of func() or (expr)
- {
- e.tree = e.tree.parent;
- }
- }
- },
- {
- re: /^\s*(\+\+|--)\s*/,
- parse: function(e, s)
- {
- if (e.tree.length && e.tree[e.tree.length-1].type == 'var')
- {
- parseOperator(RegExp.$1, 'post-unary', 1, e.tree);
- }
- else
- {
- parseOperator(RegExp.$1, 'pre-unary', 1, e.tree);
- }
- }
- },
- {
- re: /^\s*(===|!==|==|!=)\s*/,
- parse: function(e, s)
- {
- parseOperator(RegExp.$1, 'binary', 6, e.tree);
- }
- },
- {
- re: /^\s+(eq|ne|neq)\s+/i,
- parse: function(e, s)
- {
- var op = RegExp.$1.replace(/ne(q)?/,'!=').replace(/eq/,'==');
- parseOperator(op, 'binary', 6, e.tree);
- }
- },
- {
- re: /^\s*!\s*/,
- parse: function(e, s)
- {
- parseOperator('!', 'pre-unary', 2, e.tree);
- }
- },
- {
- re: /^\s+not\s+/i,
- parse: function(e, s)
- {
- parseOperator('!', 'pre-unary', 2, e.tree);
- }
- },
- {
- re: /^\s*(=|\+=|-=|\*=|\/=|%=)\s*/,
- parse: function(e, s)
- {
- parseOperator(RegExp.$1, 'binary', 10, e.tree);
- }
- },
- {
- re: /^\s*(\*|\/|%)\s*/,
- parse: function(e, s)
- {
- parseOperator(RegExp.$1, 'binary', 3, e.tree);
- }
- },
- {
- re: /^\s+mod\s+/i,
- parse: function(e, s)
- {
- parseOperator('%', 'binary', 3, e.tree);
- }
- },
- {
- re: /^\s*(\+|-)\s*/,
- parse: function(e, s)
- {
- if (!e.tree.length || e.tree[e.tree.length-1].name == 'operator')
- {
- parseOperator(RegExp.$1, 'pre-unary', 4, e.tree);
- }
- else
- {
- parseOperator(RegExp.$1, 'binary', 4, e.tree);
- }
- }
- },
- {
- re: /^\s*(<=|>=|<>|<|>)\s*/,
- parse: function(e, s)
- {
- parseOperator(RegExp.$1.replace(/<>/,'!='), 'binary', 5, e.tree);
- }
- },
- {
- re: /^\s+(lt|lte|le|gt|gte|ge)\s+/i,
- parse: function(e, s)
- {
- var op = RegExp.$1.replace(/lt/,'<').replace(/l(t)?e/,'<=').replace(/gt/,'>').replace(/g(t)?e/,'>=');
- parseOperator(op, 'binary', 5, e.tree);
- }
- },
- {
- re: /^\s+(is\s+(not\s+)?div\s+by)\s+/i,
- parse: function(e, s)
- {
- parseOperator(RegExp.$2?'div_not':'div', 'binary', 7, e.tree);
- }
- },
- {
- re: /^\s+is\s+(not\s+)?(even|odd)(\s+by\s+)?\s*/i,
- parse: function(e, s)
- {
- var op = RegExp.$1 ? ((RegExp.$2=='odd')?'even':'even_not') : ((RegExp.$2=='odd')?'even_not':'even');
- parseOperator(op, 'binary', 7, e.tree);
- if (!RegExp.$3)
- {
- parseText('1', e.tree);
- }
- }
- },
- {
- re: /^\s*(&&)\s*/,
- parse: function(e, s)
- {
- parseOperator(RegExp.$1, 'binary', 8, e.tree);
- }
- },
- {
- re: /^\s*(\|\|)\s*/,
- parse: function(e, s)
- {
- parseOperator(RegExp.$1, 'binary', 9, e.tree);
- }
- },
- {
- re: /^\s+and\s+/i,
- parse: function(e, s)
- {
- parseOperator('&&', 'binary', 11, e.tree);
- }
- },
- {
- re: /^\s+xor\s+/i,
- parse: function(e, s)
- {
- parseOperator('xor', 'binary', 12, e.tree);
- }
- },
- {
- re: /^\s+or\s+/i,
- parse: function(e, s)
- {
- parseOperator('||', 'binary', 13, e.tree);
- }
- },
- {
- re: /^#(\w+)#/, //config variable
- parse: function(e, s)
- {
- var eVar = {token:'$smarty',tree:[]};
- parseVar('.config.'+RegExp.$1, eVar, 'smarty');
- e.tree.push( eVar.tree[0] );
- parseModifiers(s, e);
- }
- },
- {
- re: /^\s*\[\s*/, //array
- parse: function(e, s)
- {
- var params = parseParams(s, /^\s*,\s*/, /^('[^'\\]*(?:\\.[^'\\]*)*'|"[^"\\]*(?:\\.[^"\\]*)*"|\w+)\s*=>\s*/);
- parsePluginFunc('__array',params,e.tree);
- e.value += params.toString();
- var paren = s.slice(params.toString().length).match(/\s*\]/);
- if (paren)
- {
- e.value += paren[0];
- }
- }
- },
- {
- re: /^[\d.]+/, //number
- parse: function(e, s)
- {
- if (e.token.indexOf('.') > -1) {
- e.token = parseFloat(e.token);
- } else {
- e.token = parseInt(e.token, 10);
- }
- parseText(e.token, e.tree);
- parseModifiers(s, e);
- }
- },
- {
- re: /^\w+/, //static
- parse: function(e, s)
- {
- parseText(e.token, e.tree);
- parseModifiers(s, e);
- }
- }
- ];
-
- function parseModifiers(s, e)
- {
- if (parseModifiers.stop)
- {
- return;
- }
-
- var modifier = s.match(/^\|(\w+)/);
- if (!modifier)
- {
- return;
- }
-
- e.value += modifier[0];
-
- var fnm = modifier[1]=='default' ? 'defaultValue' : modifier[1];
- s = s.slice(modifier[0].length).replace(/^\s+/,'');
-
- parseModifiers.stop = true;
- var params = [];
- for (var colon=s.match(/^\s*:\s*/); colon; colon=s.match(/^\s*:\s*/))
- {
- e.value += s.slice(0,colon[0].length);
- s = s.slice(colon[0].length);
-
- var param = {value:'', tree:[]};
- if (lookUp(s, param))
- {
- e.value += param.value;
- params.push(param.tree[0]);
- s = s.slice(param.value.length);
- }
- else
- {
- parseText('',params);
- }
- }
- parseModifiers.stop = false;
-
- params.unshift(e.tree.pop()); //modifiers have the highest priority
- e.tree.push(parseFunc(fnm,{__parsed:params},[])[0]);
-
- parseModifiers(s, e); //modifiers can be combined
- }
-
- function lookUp(s,e)
- {
- if (!s)
- {
- return false;
- }
-
- if (s.substr(0,jSmart.prototype.left_delimiter.length)==jSmart.prototype.left_delimiter)
- {
- var tag = findTag('',s);
- if (tag)
- {
- e.token = tag[0];
- e.value += tag[0];
- parse(tag[0], e.tree);
- parseModifiers(s.slice(e.value.length), e);
- return true;
- }
- }
-
- for (var i=0; i<tokens.length; ++i)
- {
- if (s.match(tokens[i].re))
- {
- e.token = RegExp.lastMatch;
- e.value += RegExp.lastMatch;
- tokens[i].parse(e, s.slice(e.token.length));
- return true;
- }
- }
- return false;
- }
-
- function bundleOp(i, tree, precedence)
- {
- var op = tree[i];
- if (op.name == 'operator' && op.precedence == precedence && !op.params.__parsed)
- {
- if (op.optype == 'binary')
- {
- op.params.__parsed = [tree[i-1],tree[i+1]];
- tree.splice(i-1,3,op);
- return true;
- }
- else if (op.optype == 'post-unary')
- {
- op.params.__parsed = [tree[i-1]];
- tree.splice(i-1,2,op);
- return true;
- }
-
- op.params.__parsed = [tree[i+1]];
- tree.splice(i,2,op);
- }
- return false;
- }
-
- function composeExpression(tree)
- {
- var i = 0;
- for (i=0; i<tree.length; ++i)
- {
- if (tree[i] instanceof Array)
- {
- tree[i] = composeExpression(tree[i])
- }
- }
-
- for (var precedence=1; precedence<14; ++precedence)
- {
- if (precedence==2 || precedence==10)
- {
- for (i=tree.length; i>0; --i)
- {
- i -= bundleOp(i-1, tree, precedence);
- }
- }
- else
- {
- for (i=0; i<tree.length; ++i)
- {
- i -= bundleOp(i, tree, precedence);
- }
- }
- }
- return tree[0]; //only one node must be left
- }
-
- function parseExpression(s)
- {
- var e = { value:'', tree:[] };
- while (lookUp(s.slice(e.value.length), e)){}
- if (!e.tree.length)
- {
- return false;
- }
- e.tree = composeExpression(e.tree);
- return e;
- }
-
- function parseParams(paramsStr, reDelim, reName)
- {
- var s = paramsStr.replace(/\n/g,' ').replace(/^\s+|\s+$/g,'');
- var params = [];
- params.__parsed = [];
- var paramsStr = '';
-
- if (!s)
- {
- return params;
- }
-
- if (!reDelim)
- {
- reDelim = /^\s+/;
- reName = /^(\w+)\s*=\s*/;
- }
-
- while (s)
- {
- var nm = null;
- if (reName)
- {
- var foundName = s.match(reName);
- if (foundName)
- {
- nm = trimQuotes(foundName[1]);
- paramsStr += s.slice(0,foundName[0].length);
- s = s.slice(foundName[0].length);
- }
- }
-
- var param = parseExpression(s);
- if (!param)
- {
- break;
- }
-
- if (nm)
- {
- params[nm] = param.value;
- params.__parsed[nm] = param.tree;
- }
- else
- {
- params.push(param.value);
- params.__parsed.push(param.tree);
- }
-
- paramsStr += s.slice(0,param.value.length);
- s = s.slice(param.value.length);
-
- var foundDelim = s.match(reDelim);
- if (foundDelim)
- {
- paramsStr += s.slice(0,foundDelim[0].length);
- s = s.slice(foundDelim[0].length);
- }
- else
- {
- break;
- }
- }
- params.toString = function() { return paramsStr; }
- return params;
- }
-
- function parsePluginBlock(name, params, tree, content)
- {
- tree.push({
- type: 'plugin',
- name: name,
- params: params,
- subTree: parse(content,[])
- });
- }
-
- function parsePluginFunc(name, params, tree)
- {
- tree.push({
- type: 'plugin',
- name: name,
- params: params
- });
- }
-
- function getActualParamValues(params,data)
- {
- var actualParams = [];
- for (var nm in params.__parsed)
- {
- if (params.__parsed.hasOwnProperty(nm))
- {
- var v = process([params.__parsed[nm]], data);
- actualParams[nm] = v;
- }
- }
-
- actualParams.__get = function(nm,defVal,id)
- {
- if (nm in actualParams && typeof(actualParams[nm]) != 'undefined')
- {
- return actualParams[nm];
- }
- if (typeof(id)!='undefined' && typeof(actualParams[id]) != 'undefined')
- {
- return actualParams[id];
- }
- if (defVal === null)
- {
- throw new Error("The required attribute '"+nm+"' is missing");
- }
- return defVal;
- };
- return actualParams;
- }
-
- /**
- * Returns boolean true if object is empty otherwise false.
- *
- * @param object hash Object you are testing against.
- *
- * @return boolean
- */
- function isEmptyObject(hash) {
- for (var i in hash) {
- if (hash.hasOwnProperty(i)) {
- return false;
- }
- }
- return true;
- }
-
- function getVarValue(node, data, val)
- {
- var v = data;
- var nm = '';
- for (var i=0; i<node.parts.length; ++i)
- {
- var part = node.parts[i];
- if (part.type == 'plugin' && part.name == '__func' && part.hasOwner)
- {
- data.__owner = v;
- v = process([node.parts[i]],data);
- delete data.__owner;
- }
- else
- {
- nm = process([part],data);
-
- //section name
- if (nm in data.smarty.section && part.type=='text' && process([node.parts[0]],data)!='smarty')
- {
- nm = data.smarty.section[nm].index;
- }
-
- //add to array
- if (!nm && typeof val != 'undefined' && v instanceof Array)
- {
- nm = v.length;
- }
-
- //set new value
- if (typeof val != 'undefined' && i==node.parts.length-1)
- {
- v[nm] = val;
- }
-
- if (typeof v == 'object' && v !== null && nm in v)
- {
- v = v[nm];
- }
- else
- {
- if (typeof val == 'undefined')
- {
- return val;
- }
- v[nm] = {};
- v = v[nm];
- }
- }
- }
- return v;
- }
-
- function process(tree, data)
- {
- var res = '';
- for (var i=0; i<tree.length; ++i)
- {
- var s = '';
- var node = tree[i];
- if (node.type == 'text')
- {
- s = node.data;
- }
- else if (node.type == 'var')
- {
- s = getVarValue(node,data);
- }
- else if (node.type == 'build-in')
- {
- s = buildInFunctions[node.name].process(node,data);
- }
- else if (node.type == 'plugin')
- {
- var plugin = plugins[node.name];
- if (plugin.type == 'block')
- {
- var repeat = {value:true};
- plugin.process(getActualParamValues(node.params,data), '', data, repeat);
- while (repeat.value)
- {
- repeat.value = false;
- s += plugin.process(
- getActualParamValues(node.params,data),
- process(node.subTree, data),
- data,
- repeat
- );
- }
- }
- else if (plugin.type == 'function')
- {
- s = plugin.process(getActualParamValues(node.params,data), data);
- }
- }
- if (typeof s == 'boolean')
- {
- s = s ? '1' : '';
- }
- if (s == null) {
- s = '';
- }
- if (tree.length == 1)
- {
- return s;
- }
- res += s!==null ? s : '';
-
- if (data.smarty['continue'] || data.smarty['break'])
- {
- return res;
- }
- }
- return res;
- }
-
- function getTemplate(name, tree, nocache)
- {
- if (nocache || !(name in files))
- {
- var tpl = jSmart.prototype.getTemplate(name);
- if (typeof(tpl) != 'string')
- {
- throw new Error('No template for '+ name);
- }
- parse(applyFilters(jSmart.prototype.filters_global.pre, stripComments(tpl.replace(/\r\n/g,'\n'))), tree);
- files[name] = tree;
- }
- else
- {
- tree = files[name];
- }
- return tree;
- }
-
- function stripComments(s)
- {
- var sRes = '';
- for (var openTag=s.match(/{\*/); openTag; openTag=s.match(/{\*/))
- {
- sRes += s.slice(0,openTag.index);
- s = s.slice(openTag.index+openTag[0].length);
- var closeTag = s.match(/\*}/);
- if (!closeTag)
- {
- throw new Error('Unclosed {*');
- }
- s = s.slice(closeTag.index+closeTag[0].length);
- }
- return sRes + s;
- }
-
- function applyFilters(filters, s)
- {
- for (var i=0; i<filters.length; ++i)
- {
- s = filters[i](s);
- }
- return s;
- }
-
-
- jSmart = function(tpl)
- {
- this.tree = [];
- this.tree.blocks = {};
- this.scripts = {};
- this.default_modifiers = [];
- this.filters = {'variable':[], 'post':[]};
- this.smarty = {
- 'smarty': {
- block: {},
- 'break': false,
- capture: {},
- 'continue': false,
- counter: {},
- cycle: {},
- foreach: {},
- section: {},
- now: Math.floor( (new Date()).getTime()/1000 ),
- 'const': {},
- config: {},
- current_dir: '/',
- template: '',
- ldelim: jSmart.prototype.left_delimiter,
- rdelim: jSmart.prototype.right_delimiter,
- version: '2.15.0'
- }
- };
- blocks = this.tree.blocks;
- parse(
- applyFilters(jSmart.prototype.filters_global.pre, stripComments((new String(tpl?tpl:'')).replace(/\r\n/g,'\n'))),
- this.tree
- );
- };
-
- jSmart.prototype.fetch = function(data)
- {
- blocks = this.tree.blocks;
- scripts = this.scripts;
- escape_html = this.escape_html;
- default_modifiers = jSmart.prototype.default_modifiers_global.concat(this.default_modifiers);
- this.data = obMerge((typeof data == 'object') ? data : {}, this.smarty);
- varFilters = jSmart.prototype.filters_global.variable.concat(this.filters.variable);
- var res = process(this.tree, this.data);
- if (jSmart.prototype.debugging)
- {
- plugins.debug.process([],this.data);
- }
- return applyFilters(jSmart.prototype.filters_global.post.concat(this.filters.post), res);
- };
-
- jSmart.prototype.escape_html = false;
-
- /**
- @param type valid values are 'function', 'block', 'modifier'
- @param callback func(params,data) or block(params,content,data,repeat)
- */
- jSmart.prototype.registerPlugin = function(type, name, callback)
- {
- if (type == 'modifier')
- {
- modifiers[name] = callback;
- }
- else
- {
- plugins[name] = {'type': type, 'process': callback};
- }
- };
-
- /**
- @param type valid values are 'pre', 'variable', 'post'
- @param callback function(textValue) { ... }
- */
- jSmart.prototype.registerFilter = function(type, callback)
- {
- (this.tree ? this.filters : jSmart.prototype.filters_global)[type=='output'?'post':type].push(callback);
- }
-
- jSmart.prototype.filters_global = {'pre':[],'variable':[],'post':[]};
-
- jSmart.prototype.configLoad = function(confValues, section, data)
- {
- data = data ? data : this.data;
- var s = confValues.replace(/\r\n/g,'\n').replace(/^\s+|\s+$/g,'');
- var re = /^\s*(?:\[([^\]]+)\]|(?:(\w+)[ \t]*=[ \t]*("""|'[^'\\\n]*(?:\\.[^'\\\n]*)*'|"[^"\\\n]*(?:\\.[^"\\\n]*)*"|[^\n]*)))/m;
- var currSect = '';
- for (var f=s.match(re); f; f=s.match(re))
- {
- s = s.slice(f.index+f[0].length);
- if (f[1])
- {
- currSect = f[1];
- }
- else if ((!currSect || currSect == section) && currSect.substr(0,1) != '.')
- {
- if (f[3] == '"""')
- {
- var triple = s.match(/"""/);
- if (triple)
- {
- data.smarty.config[f[2]] = s.slice(0,triple.index);
- s = s.slice(triple.index + triple[0].length);
- }
- }
- else
- {
- data.smarty.config[f[2]] = trimQuotes(f[3]);
- }
- }
- var newln = s.match(/\n+/);
- if (newln)
- {
- s = s.slice(newln.index + newln[0].length);
- }
- else
- {
- break;
- }
- }
- }
-
- jSmart.prototype.clearConfig = function(varName)
- {
- if (varName)
- {
- delete this.data.smarty.config[varName];
- }
- else
- {
- this.data.smarty.config = {};
- }
- }
-
- /**
- add modifier to implicitly apply to every variable in a template
- @param modifiers single string (e.g. "replace:'from':'to'")
- or array of strings (e.g. ['escape:"htmlall"', "replace:'from':'to'"])
- */
- jSmart.prototype.addDefaultModifier = function(modifiers)
- {
- if (!(modifiers instanceof Array))
- {
- modifiers = [modifiers];
- }
-
- for (var i=0; i<modifiers.length; ++i)
- {
- var e = { value:'', tree:[0] };
- parseModifiers('|'+modifiers[i], e);
- (this.tree ? this.default_modifiers : this.default_modifiers_global).push( e.tree[0] );
- }
- }
-
- jSmart.prototype.default_modifiers_global = [];
-
- /**
- override this function
- @param name value of 'file' parameter in {include} and {extends}
- @return template text
- */
- jSmart.prototype.getTemplate = function(name)
- {
- throw new Error('No template for ' + name);
- }
-
- /**
- override this function
- @param name value of 'file' parameter in {fetch}
- @return file content
- */
- jSmart.prototype.getFile = function(name)
- {
- throw new Error('No file for ' + name);
- }
-
- /**
- override this function
- @param name value of 'file' parameter in {include_php} and {include_javascript}
- or value of 'script' parameter in {insert}
- @return Javascript script
- */
- jSmart.prototype.getJavascript = function(name)
- {
- throw new Error('No Javascript for ' + name);
- }
-
- /**
- override this function
- @param name value of 'file' parameter in {config_load}
- @return config file content
- */
- jSmart.prototype.getConfig = function(name)
- {
- throw new Error('No config for ' + name);
- }
-
-
-
- /**
- whether to skip tags in open brace { followed by white space(s) and close brace } with white space(s) before
- */
- jSmart.prototype.auto_literal = true;
-
- jSmart.prototype.left_delimiter = '{';
- jSmart.prototype.right_delimiter = '}';
-
- /** enables the debugging console */
- jSmart.prototype.debugging = false;
-
-
- jSmart.prototype.PHPJS = function(fnm, modifier)
- {
- if (eval('typeof '+fnm) == 'function')
- {
- return (typeof window == 'object') ? window : global;
- }
- else if (typeof(PHP_JS) == 'function')
- {
- return new PHP_JS();
- }
- throw new Error("Modifier '" + modifier + "' uses JavaScript port of PHP function '" + fnm + "'. You can find one at http://phpjs.org");
- }
-
- jSmart.prototype.makeTimeStamp = function(s)
- {
- if (!s)
- {
- return Math.floor( (new Date()).getTime()/1000 );
- }
- if (isNaN(s))
- {
- var tm = jSmart.prototype.PHPJS('strtotime','date_format').strtotime(s);
- if (tm == -1 || tm === false) {
- return Math.floor( (new Date()).getTime()/1000 );
- }
- return tm;
- }
- s = new String(s);
- if (s.length == 14) //mysql timestamp format of YYYYMMDDHHMMSS
- {
- return Math.floor( (new Date(s.substr(0,4),s.substr(4,2)-1,s.substr(6,2),s.substr(8,2),s.substr(10,2)).getTime()/1000 ) );
- }
- return parseInt(s);
- }
-
-
-
- /**
- register custom functions
- */
- jSmart.prototype.registerPlugin(
- 'function',
- '__array',
- function(params, data)
- {
- var a = [];
- for (var nm in params)
- {
- if (params.hasOwnProperty(nm) && params[nm] && typeof params[nm] != 'function')
- {
- a[nm] = params[nm];
- }
- }
- return a;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- '__func',
- function(params, data) {
- var paramNames = [], paramValues = {}, paramData = [];
- for (var i=0; i<params.length; ++i) {
- paramNames.push(params.name+'__p'+i);
- paramData.push(params[i]);
- paramValues[params.name+'__p'+i] = params[i];
- }
- var fname, mergedParams = obMerge({}, data, paramValues);
- if (('__owner' in data && params.name in data.__owner)) {
- fname = '__owner.'+params.name;
- return execute(fname + '(' + paramNames.join(',') + ')', mergedParams);
- } else if (modifiers.hasOwnProperty(params.name)) {
- fname = modifiers[params.name]
- return executeByFuncObject(fname, paramData, mergedParams);
- } else {
- fname = params.name;
- return execute(fname + '(' + paramNames.join(',') + ')', mergedParams);
- }
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- '__quoted',
- function(params, data)
- {
- return params.join('');
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'append',
- function(params, data)
- {
- var varName = params.__get('var',null,0);
- if (!(varName in data) || !(data[varName] instanceof Array))
- {
- data[varName] = [];
- }
- var index = params.__get('index',false);
- var val = params.__get('value',null,1);
- if (index === false)
- {
- data[varName].push(val);
- }
- else
- {
- data[varName][index] = val;
- }
- return '';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'assign',
- function(params, data)
- {
- assignVar(params.__get('var',null,0), params.__get('value',null,1), data);
- return '';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'break',
- function(params, data)
- {
- data.smarty['break'] = true;
- return '';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'call',
- function(params, data)
- {
- var fname = params.__get('name',null,0);
- delete params.name;
- var assignTo = params.__get('assign',false);
- delete params.assign;
- var s = plugins[fname].process(params, data);
- if (assignTo)
- {
- assignVar(assignTo, s, data);
- return '';
- }
- return s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'block',
- 'capture',
- function(params, content, data, repeat)
- {
- if (content)
- {
- content = content.replace(/^\n/,'');
- data.smarty.capture[params.__get('name','default',0)] = content;
-
- if ('assign' in params)
- {
- assignVar(params.assign, content, data);
- }
-
- var append = params.__get('append',false);
- if (append)
- {
- if (append in data)
- {
- if (data[append] instanceof Array)
- {
- data[append].push(content);
- }
- }
- else
- {
- data[append] = [content];
- }
- }
- }
- return '';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'continue',
- function(params, data)
- {
- data.smarty['continue'] = true;
- return '';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'counter',
- function(params, data)
- {
- var name = params.__get('name','default');
- if (name in data.smarty.counter)
- {
- var counter = data.smarty.counter[name];
- if ('start' in params)
- {
- counter.value = parseInt(params['start']);
- }
- else
- {
- counter.value = parseInt(counter.value);
- counter.skip = parseInt(counter.skip);
- if ('down' == counter.direction)
- {
- counter.value -= counter.skip;
- }
- else
- {
- counter.value += counter.skip;
- }
- }
- counter.skip = params.__get('skip',counter.skip);
- counter.direction = params.__get('direction',counter.direction);
- counter.assign = params.__get('assign',counter.assign);
- }
- else
- {
- data.smarty.counter[name] = {
- value: parseInt(params.__get('start',1)),
- skip: parseInt(params.__get('skip',1)),
- direction: params.__get('direction','up'),
- assign: params.__get('assign',false)
- };
- }
-
- if (data.smarty.counter[name].assign)
- {
- data[data.smarty.counter[name].assign] = data.smarty.counter[name].value;
- return '';
- }
-
- if (params.__get('print',true))
- {
- return data.smarty.counter[name].value;
- }
-
- return '';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'cycle',
- function(params, data)
- {
- var name = params.__get('name','default');
- var reset = params.__get('reset',false);
- if (!(name in data.smarty.cycle))
- {
- data.smarty.cycle[name] = {arr: [''], delimiter: params.__get('delimiter',','), index: 0};
- reset = true;
- }
-
- if (params.__get('delimiter',false))
- {
- data.smarty.cycle[name].delimiter = params.delimiter;
- }
- var values = params.__get('values',false);
- if (values)
- {
- var arr = [];
- if (values instanceof Object)
- {
- for (nm in values)
- {
- arr.push(values[nm]);
- }
- }
- else
- {
- arr = values.split(data.smarty.cycle[name].delimiter);
- }
-
- if (arr.length != data.smarty.cycle[name].arr.length || arr[0] != data.smarty.cycle[name].arr[0])
- {
- data.smarty.cycle[name].arr = arr;
- data.smarty.cycle[name].index = 0;
- reset = true;
- }
- }
-
- if (params.__get('advance','true'))
- {
- data.smarty.cycle[name].index += 1;
- }
- if (data.smarty.cycle[name].index >= data.smarty.cycle[name].arr.length || reset)
- {
- data.smarty.cycle[name].index = 0;
- }
-
- if (params.__get('assign',false))
- {
- assignVar(params.assign, data.smarty.cycle[name].arr[ data.smarty.cycle[name].index ], data);
- return '';
- }
-
- if (params.__get('print',true))
- {
- return data.smarty.cycle[name].arr[ data.smarty.cycle[name].index ];
- }
-
- return '';
- }
- );
-
- jSmart.prototype.print_r = function(v,indent)
- {
- if (v instanceof Object)
- {
- var s = ((v instanceof Array) ? 'Array['+v.length+']' : 'Object') + '<br>';
- for (var nm in v)
- {
- if (v.hasOwnProperty(nm))
- {
- s += indent + ' <strong>' + nm + '</strong> : ' + jSmart.prototype.print_r(v[nm],indent+' ') + '<br>';
- }
- }
- return s;
- }
- return v;
- }
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'debug',
- function(params, data)
- {
- if (typeof dbgWnd != 'undefined')
- {
- dbgWnd.close();
- }
- dbgWnd = window.open('','','width=680,height=600,resizable,scrollbars=yes');
- var sVars = '';
- var i=0;
- for (var nm in data)
- {
- sVars += '<tr class=' + (++i%2?'odd':'even') + '><td><strong>' + nm + '</strong></td><td>' + jSmart.prototype.print_r(data[nm],'') + '</td></tr>';
- }
- dbgWnd.document.write(" \
- <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en'> \
- <head> \
- <title>jSmart Debug Console</title> \
- <style type='text/css'> \
- table {width: 100%;} \
- td {vertical-align:top;width: 50%;} \
- .even td {background-color: #fafafa;} \
- </style> \
- </head> \
- <body> \
- <h1>jSmart Debug Console</h1> \
- <h2>assigned template variables</h2> \
- <table>" + sVars + "</table> \
- </body> \
- </html> \
- ");
- return '';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'eval',
- function(params, data)
- {
- var tree = [];
- parse(params.__get('var','',0), tree);
- var s = process(tree, data);
- if ('assign' in params)
- {
- assignVar(params.assign, s, data);
- return '';
- }
- return s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'fetch',
- function(params, data)
- {
- var s = jSmart.prototype.getFile(params.__get('file',null,0));
- if ('assign' in params)
- {
- assignVar(params.assign, s, data);
- return '';
- }
- return s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'html_checkboxes',
- function (params, data) {
- var type = params.__get('type','checkbox'),
- name = params.__get('name',type),
- realName = params.__get('name',type),
- values = params.__get('values',params.options),
- output = params.__get('options',[]),
- useName = ('options' in params),
- selected = params.__get('selected',false),
- separator = params.__get('separator',''),
- labels = Boolean(params.__get('labels',true)),
- label_ids = Boolean(params.__get('label_ids',false)),
- p,
- res = [],
- i = 0,
- s = '',
- value,
- id;
-
- if (type == 'checkbox') {
- name += '[]';
- }
- if (!useName) {
- for (p in params.output) {
- output.push(params.output[p]);
- }
- }
-
- for (p in values) {
- if (values.hasOwnProperty(p)) {
- value = (useName ? p : values[p]);
- id = realName + '_' + value;
- s = (labels ? ( label_ids ? '<label for="'+id+'">' : '<label>') : '');
-
- s += '<input type="' + type + '" name="' + name + '" value="' + value + '" ';
- if (label_ids) {
- s += 'id="'+id+'" ';
- }
- if (selected == (useName ? p : values[p])) {
- s += 'checked="checked" ';
- }
- s += '/>' + output[useName?p:i++];
- s += (labels ? '</label>' : '');
- s += separator;
- res.push(s);
- }
- }
- if ('assign' in params) {
- assignVar(params.assign, res, data);
- return '';
- }
- return res.join('\n');
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'html_image',
- function (params, data) {
- var url = params.__get('file', null),
- width = params.__get('width', false),
- height = params.__get('height', false),
- alt = params.__get('alt', ''),
- href = params.__get('href', params.__get('link', false)),
- path_prefix = params.__get('path_prefix', ''),
- paramNames = {file:1, width:1, height:1, alt:1, href:1, basedir:1, path_prefix:1, link:1},
- s = '<img src="' + path_prefix + url + '"' + ' alt="'+alt+'"' + (width ? ' width="'+width+'"':'') + (height ? ' height="'+height+'"':''),
- p;
-
- for (p in params) {
- if (params.hasOwnProperty(p) && typeof(params[p]) == 'string') {
- if (!(p in paramNames)) {
- s += ' ' + p + '="' + params[p] + '"';
- }
- }
- }
- s += ' />';
- return href ? '<a href="'+href+'">'+s+'</a>' : s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'html_options',
- function(params, data)
- {
- var values = params.__get('values',params.options);
- var output = params.__get('options',[]);
- var useName = ('options' in params);
- var p;
- if (!useName)
- {
- for (p in params.output)
- {
- output.push(params.output[p]);
- }
- }
- var selected = params.__get('selected',false);
-
- var res = [];
- var s = '';
- var i = 0;
- for (p in values)
- {
- if (values.hasOwnProperty(p))
- {
- s = '<option value="' + (useName ? p : values[p]) + '"';
- if (selected == (useName ? p : values[p]))
- {
- s += ' selected="selected"';
- }
- s += '>' + output[useName ? p : i++] + '</option>';
- res.push(s);
- }
- }
- var name = params.__get('name',false);
- return (name ? ('<select name="' + name + '">\n' + res.join('\n') + '\n</select>') : res.join('\n')) + '\n';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'html_radios',
- function(params, data)
- {
- params.type = 'radio';
- return plugins.html_checkboxes.process(params,data);
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'html_select_date',
- function(params, data)
- {
- var prefix = params.__get('prefix','Date_');
- var months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
-
- var s = '';
- s += '<select name="'+prefix+'Month">\n';
- var i=0;
- for (i=0; i<months.length; ++i)
- {
- s += '<option value="' + i + '">' + months[i] + '</option>\n';
- }
- s += '</select>\n'
-
- s += '<select name="'+prefix+'Day">\n';
- for (i=0; i<31; ++i)
- {
- s += '<option value="' + i + '">' + i + '</option>\n';
- }
- s += '</select>\n'
- return s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'html_table',
- function(params, data)
- {
- var loop = [];
- var p;
- if (params.loop instanceof Array)
- {
- loop = params.loop
- }
- else
- {
- for (p in params.loop)
- {
- if (params.loop.hasOwnProperty(p))
- {
- loop.push( params.loop[p] );
- }
- }
- }
- var rows = params.__get('rows',false);
- var cols = params.__get('cols',false);
- if (!cols)
- {
- cols = rows ? Math.ceil(loop.length/rows) : 3;
- }
- var colNames = [];
- if (isNaN(cols))
- {
- if (typeof cols == 'object')
- {
- for (p in cols)
- {
- if (cols.hasOwnProperty(p))
- {
- colNames.push(cols[p]);
- }
- }
- }
- else
- {
- colNames = cols.split(/\s*,\s*/);
- }
- cols = colNames.length;
- }
- rows = rows ? rows : Math.ceil(loop.length/cols);
-
- var inner = params.__get('inner','cols');
- var caption = params.__get('caption','');
- var table_attr = params.__get('table_attr','border="1"');
- var th_attr = params.__get('th_attr',false);
- if (th_attr && typeof th_attr != 'object')
- {
- th_attr = [th_attr];
- }
- var tr_attr = params.__get('tr_attr',false);
- if (tr_attr && typeof tr_attr != 'object')
- {
- tr_attr = [tr_attr];
- }
- var td_attr = params.__get('td_attr',false);
- if (td_attr && typeof td_attr != 'object')
- {
- td_attr = [td_attr];
- }
- var trailpad = params.__get('trailpad',' ');
- var hdir = params.__get('hdir','right');
- var vdir = params.__get('vdir','down');
-
- var s = '';
- for (var row=0; row<rows; ++row)
- {
- s += '<tr' + (tr_attr ? ' '+tr_attr[row%tr_attr.length] : '') + '>\n';
- for (var col=0; col<cols; ++col)
- {
- var idx = (inner=='cols') ? ((vdir=='down'?row:rows-1-row) * cols + (hdir=='right'?col:cols-1-col)) : ((hdir=='right'?col:cols-1-col) * rows + (vdir=='down'?row:rows-1-row));
-
- s += '<td' + (td_attr ? ' '+td_attr[col%td_attr.length] : '') + '>' + (idx < loop.length ? loop[idx] : trailpad) + '</td>\n';
- }
- s += '</tr>\n';
- }
-
- var sHead = '';
- if (colNames.length)
- {
- sHead = '\n<thead><tr>';
- for (var i=0; i<colNames.length; ++i)
- {
- sHead += '\n<th' + (th_attr ? ' '+th_attr[i%th_attr.length] : '') + '>' + colNames[hdir=='right'?i:colNames.length-1-i] + '</th>';
- }
- sHead += '\n</tr></thead>';
- }
-
- return '<table ' + table_attr + '>' + (caption?'\n<caption>'+caption+'</caption>':'') + sHead + '\n<tbody>\n' + s + '</tbody>\n</table>\n';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'include',
- function(params, data)
- {
- var file = params.__get('file',null,0);
- var incData = obMerge({},data,params);
- incData.smarty.template = file;
- var s = process(getTemplate(file,[],findInArray(params,'nocache')>=0), incData);
- if ('assign' in params)
- {
- assignVar(params.assign, s, data);
- return '';
- }
- return s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'include_javascript',
- function(params, data)
- {
- var file = params.__get('file',null,0);
- if (params.__get('once',true) && file in scripts)
- {
- return '';
- }
- scripts[file] = true;
- var s = execute(jSmart.prototype.getJavascript(file), {'$this':data});
- if ('assign' in params)
- {
- assignVar(params.assign, s, data);
- return '';
- }
- return s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'include_php',
- function(params, data)
- {
- return plugins['include_javascript'].process(params,data);
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'insert',
- function(params, data)
- {
- var fparams = {};
- for (var nm in params)
- {
- if (params.hasOwnProperty(nm) && isNaN(nm) && params[nm] && typeof params[nm] == 'string' && nm != 'name' && nm != 'assign' && nm != 'script')
- {
- fparams[nm] = params[nm];
- }
- }
- var prefix = 'insert_';
- if ('script' in params)
- {
- eval(jSmart.prototype.getJavascript(params.script));
- prefix = 'smarty_insert_';
- }
- var func = eval(prefix+params.__get('name',null,0));
- var s = func(fparams, data);
- if ('assign' in params)
- {
- assignVar(params.assign, s, data);
- return '';
- }
- return s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'block',
- 'javascript',
- function(params, content, data, repeat)
- {
- data['$this'] = data;
- execute(content,data);
- delete data['$this'];
- return '';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'config_load',
- function(params, data)
- {
- jSmart.prototype.configLoad(jSmart.prototype.getConfig(params.__get('file',null,0)), params.__get('section','',1), data);
- return '';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'mailto',
- function(params, data)
- {
- var address = params.__get('address',null);
- var encode = params.__get('encode','none');
- var text = params.__get('text',address);
- var cc = jSmart.prototype.PHPJS('rawurlencode','mailto').rawurlencode(params.__get('cc','')).replace('%40','@');
- var bcc = jSmart.prototype.PHPJS('rawurlencode','mailto').rawurlencode(params.__get('bcc','')).replace('%40','@');
- var followupto = jSmart.prototype.PHPJS('rawurlencode','mailto').rawurlencode(params.__get('followupto','')).replace('%40','@');
- var subject = jSmart.prototype.PHPJS('rawurlencode','mailto').rawurlencode( params.__get('subject','') );
- var newsgroups = jSmart.prototype.PHPJS('rawurlencode','mailto').rawurlencode(params.__get('newsgroups',''));
- var extra = params.__get('extra','');
-
- address += (cc?'?cc='+cc:'');
- address += (bcc?(cc?'&':'?')+'bcc='+bcc:'');
- address += (subject ? ((cc||bcc)?'&':'?') + 'subject='+subject : '');
- address += (newsgroups ? ((cc||bcc||subject)?'&':'?') + 'newsgroups='+newsgroups : '');
- address += (followupto ? ((cc||bcc||subject||newsgroups)?'&':'?') + 'followupto='+followupto : '');
-
- s = '<a href="mailto:' + address + '" ' + extra + '>' + text + '</a>';
-
- if (encode == 'javascript')
- {
- s = "document.write('" + s + "');";
- var sEncoded = '';
- for (var i=0; i<s.length; ++i)
- {
- sEncoded += '%' + jSmart.prototype.PHPJS('bin2hex','mailto').bin2hex(s.substr(i,1));
- }
- return '<script type="text/javascript">eval(unescape(\'' + sEncoded + "'))</script>";
- }
- else if (encode == 'javascript_charcode')
- {
- var codes = [];
- for (var i=0; i<s.length; ++i)
- {
- codes.push(jSmart.prototype.PHPJS('ord','mailto').ord(s.substr(i,1)));
- }
- return '<script type="text/javascript" language="javascript">\n<!--\n{document.write(String.fromCharCode('
- + codes.join(',') + '))}\n//-->\n</script>\n';
- }
- else if (encode == 'hex')
- {
- if (address.match(/^.+\?.+$/))
- {
- throw new Error('mailto: hex encoding does not work with extra attributes. Try javascript.');
- }
- var aEncoded = '';
- for (var i=0; i<address.length; ++i)
- {
- if (address.substr(i,1).match(/\w/))
- {
- aEncoded += '%' + jSmart.prototype.PHPJS('bin2hex','mailto').bin2hex(address.substr(i,1));
- }
- else
- {
- aEncoded += address.substr(i,1);
- }
- }
- aEncoded = aEncoded.toLowerCase();
- var tEncoded = '';
- for (var i=0; i<text.length; ++i)
- {
- tEncoded += '&#x' + jSmart.prototype.PHPJS('bin2hex','mailto').bin2hex(text.substr(i,1)) + ';';
- }
- tEncoded = tEncoded.toLowerCase();
- return '<a href="mailto:' + aEncoded + '" ' + extra + '>' + tEncoded + '</a>';
- }
- return s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'function',
- 'math',
- function(params, data)
- {
- with (Math)
- {
- with (params)
- {
- var res = eval(params.__get('equation',null).replace(/pi\(\s*\)/g,'PI'));
- }
- }
-
- if ('format' in params)
- {
- res = jSmart.prototype.PHPJS('sprintf','math').sprintf(params.format,res);
- }
-
- if ('assign' in params)
- {
- assignVar(params.assign, res, data);
- return '';
- }
- return res;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'block',
- 'nocache',
- function(params, content, data, repeat)
- {
- return content;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'block',
- 'textformat',
- function(params, content, data, repeat)
- {
- if (!content) {
- return '';
- }
-
- content = new String(content);
-
- var wrap = params.__get('wrap',80);
- var wrap_char = params.__get('wrap_char','\n');
- var wrap_cut = params.__get('wrap_cut',false);
- var indent_char = params.__get('indent_char',' ');
- var indent = params.__get('indent',0);
- var indentStr = (new Array(indent+1)).join(indent_char);
- var indent_first = params.__get('indent_first',0);
- var indentFirstStr = (new Array(indent_first+1)).join(indent_char);
-
- var style = params.__get('style','');
-
- if (style == 'email') {
- wrap = 72;
- }
-
- var paragraphs = content.split(/[\r\n]{2}/);
- for (var i=0; i<paragraphs.length; ++i) {
- var p = paragraphs[i];
- if (!p) {
- continue;
- }
- p = p.replace(/^\s+|\s+$/,'').replace(/\s+/g,' ');
- if (indent_first> 0 ) {
- p = indentFirstStr + p;
- }
- p = modifiers.wordwrap(p, wrap-indent, wrap_char, wrap_cut);
- if (indent > 0) {
- p = p.replace(/^/mg, indentStr);
- }
- paragraphs[i] = p;
- }
- var s = paragraphs.join(wrap_char+wrap_char);
- if ('assign' in params)
- {
- assignVar(params.assign, s, data);
- return '';
- }
- return s;
- }
- );
-
-
- /**
- register modifiers
- */
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'capitalize',
- function(s, upDigits, lcRest) {
- if (typeof s != 'string') {
- return s;
- }
- var re = new RegExp(upDigits ? '[^a-zA-Z_\u00E0-\u00FC]+' : '[^a-zA-Z0-9_\u00E0-\u00FC]');
- var found = null;
- var res = '';
- if (lcRest) {
- s = s.toLowerCase();
- }
- for (found=s.match(re); found; found=s.match(re))
- {
- var word = s.slice(0,found.index);
- if (word.match(/\d/))
- {
- res += word;
- }
- else
- {
- res += word.charAt(0).toUpperCase() + word.slice(1);
- }
- res += s.slice(found.index, found.index+found[0].length);
- s = s.slice(found.index+found[0].length);
- }
- if (s.match(/\d/))
- {
- return res + s;
- }
- return res + s.charAt(0).toUpperCase() + s.slice(1);
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'cat',
- function(s, value)
- {
- value = value ? value : '';
- return new String(s) + value;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'count',
- function(v, recursive)
- {
- if (v === null || typeof v === 'undefined') {
- return 0;
- } else if (v.constructor !== Array && v.constructor !== Object) {
- return 1;
- }
-
- recursive = Boolean(recursive);
- var k, cnt = 0;
- for (k in v)
- {
- if (v.hasOwnProperty(k))
- {
- cnt++;
- if (recursive && v[k] && (v[k].constructor === Array || v[k].constructor === Object)) {
- cnt += modifiers.count(v[k], true);
- }
- }
- }
- return cnt;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'count_characters',
- function(s, includeWhitespaces)
- {
- s = new String(s);
- return includeWhitespaces ? s.length : s.replace(/\s/g,'').length;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'count_paragraphs',
- function(s)
- {
- var found = (new String(s)).match(/\n+/g);
- if (found)
- {
- return found.length+1;
- }
- return 1;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'count_sentences',
- function(s)
- {
- if (typeof s == 'string')
- {
- var found = s.match(/[^\s]\.(?!\w)/g);
- if (found)
- {
- return found.length;
- }
- }
- return 0;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'count_words',
- function(s)
- {
- if (typeof s == 'string')
- {
- var found = s.match(/\w+/g);
- if (found)
- {
- return found.length;
- }
- }
- return 0;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'date_format',
- function(s, fmt, defaultDate)
- {
- return jSmart.prototype.PHPJS('strftime','date_format').strftime(fmt?fmt:'%b %e, %Y', jSmart.prototype.makeTimeStamp(s?s:defaultDate));
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'defaultValue',
- function(s, value)
- {
- return (s && s!='null' && s!='undefined') ? s : (value ? value : '');
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'unescape',
- function(s, esc_type, char_set)
- {
- s = new String(s);
- esc_type = esc_type || 'html';
- char_set = char_set || 'UTF-8';
-
- switch (esc_type)
- {
- case 'html':
- return s.replace(/</g, '<').replace(/>/g,'>').replace(/'/g,"'").replace(/"/g,'"');
- case 'entity':
- case 'htmlall':
- return jSmart.prototype.PHPJS('html_entity_decode','unescape').html_entity_decode(s, 1);
- case 'url':
- return jSmart.prototype.PHPJS('rawurldecode','unescape').rawurldecode(s);
- };
- return s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'escape',
- function(s, esc_type, char_set, double_encode)
- {
- s = new String(s);
- esc_type = esc_type || 'html';
- char_set = char_set || 'UTF-8';
- double_encode = (typeof double_encode != 'undefined') ? Boolean(double_encode) : true;
-
- switch (esc_type)
- {
- case 'html':
- if (double_encode) {
- s = s.replace(/&/g, '&');
- }
- return s.replace(/</g,'<').replace(/>/g,'>').replace(/'/g,''').replace(/"/g,'"');
- case 'htmlall':
- return jSmart.prototype.PHPJS('htmlentities','escape').htmlentities(s, 3, char_set);
- case 'url':
- return jSmart.prototype.PHPJS('rawurlencode','escape').rawurlencode(s);
- case 'urlpathinfo':
- return jSmart.prototype.PHPJS('rawurlencode','escape').rawurlencode(s).replace(/%2F/g, '/');
- case 'quotes':
- return s.replace(/(^|[^\\])'/g, "$1\\'");
- case 'hex':
- var res = '';
- for (var i=0; i<s.length; ++i)
- {
- res += '%' + jSmart.prototype.PHPJS('bin2hex','escape').bin2hex(s.substr(i,1)).toLowerCase();
- }
- return res;
- case 'hexentity':
- var res = '';
- for (var i=0; i<s.length; ++i) {
- res += '&#x' + jSmart.prototype.PHPJS('bin2hex','escape').bin2hex(s.substr(i,1)) + ';';
- }
- return res;
- case 'decentity':
- var res = '';
- for (var i=0; i<s.length; ++i) {
- res += '&#' + jSmart.prototype.PHPJS('ord','escape').ord(s.substr(i,1)) + ';';
- }
- return res;
- case 'mail':
- return s.replace(/@/g,' [AT] ').replace(/[.]/g,' [DOT] ');
- case 'nonstd':
- var res = '';
- for (var i=0; i<s.length; ++i)
- {
- var _ord = jSmart.prototype.PHPJS('ord','escape').ord(s.substr(i,1));
- if (_ord >= 126) {
- res += '&#' + _ord + ';';
- } else {
- res += s.substr(i, 1);
- }
-
- }
- return res;
- case 'javascript':
- return s.replace(/\\/g,'\\\\').replace(/'/g,"\\'").replace(/"/g,'\\"').replace(/\r/g,'\\r').replace(/\n/g,'\\n').replace(/<\//g,'<\/');
- };
- return s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'indent',
- function(s, repeat, indentWith)
- {
- s = new String(s);
- repeat = repeat ? repeat : 4;
- indentWith = indentWith ? indentWith : ' ';
-
- var indentStr = '';
- while (repeat--)
- {
- indentStr += indentWith;
- }
-
- var tail = s.match(/\n+$/);
- return indentStr + s.replace(/\n+$/,'').replace(/\n/g,'\n'+indentStr) + (tail ? tail[0] : '');
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'lower',
- function(s)
- {
- return new String(s).toLowerCase();
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'nl2br',
- function(s)
- {
- return new String(s).replace(/\n/g,'<br />\n');
- }
- );
-
- /**
- only modifiers (flags) 'i' and 'm' are supported
- backslashes should be escaped e.g. \\s
- */
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'regex_replace',
- function(s, re, replaceWith)
- {
- var pattern = re.match(/^ *\/(.*)\/(.*) *$/);
- return (new String(s)).replace(new RegExp(pattern[1],'g'+(pattern.length>1?pattern[2]:'')), replaceWith);
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'replace',
- function(s, search, replaceWith)
- {
- if (!search)
- {
- return s;
- }
- s = new String(s);
- search = new String(search);
- replaceWith = new String(replaceWith);
- var res = '';
- var pos = -1;
- for (pos=s.indexOf(search); pos>=0; pos=s.indexOf(search))
- {
- res += s.slice(0,pos) + replaceWith;
- pos += search.length;
- s = s.slice(pos);
- }
- return res + s;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'spacify',
- function(s, space)
- {
- if (!space)
- {
- space = ' ';
- }
- return (new String(s)).replace(/(\n|.)(?!$)/g,'$1'+space);
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'noprint',
- function(s)
- {
- return '';
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'string_format',
- function(s, fmt)
- {
- return jSmart.prototype.PHPJS('sprintf','string_format').sprintf(fmt,s);
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'strip',
- function(s, replaceWith)
- {
- replaceWith = replaceWith ? replaceWith : ' ';
- return (new String(s)).replace(/[\s]+/g, replaceWith);
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'strip_tags',
- function(s, addSpace)
- {
- addSpace = (addSpace==null) ? true : addSpace;
- return (new String(s)).replace(/<[^>]*?>/g, addSpace ? ' ' : '');
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'truncate',
- function(s, length, etc, breakWords, middle)
- {
- s = new String(s);
- length = length ? length : 80;
- etc = (etc!=null) ? etc : '...';
-
- if (s.length <= length)
- {
- return s;
- }
-
- length -= Math.min(length,etc.length);
- if (middle)
- {
- //one of floor()'s should be replaced with ceil() but it so in Smarty
- return s.slice(0,Math.floor(length/2)) + etc + s.slice(s.length-Math.floor(length/2));
- }
-
- if (!breakWords)
- {
- s = s.slice(0,length+1).replace(/\s+?(\S+)?$/,'');
- }
-
- return s.slice(0,length) + etc;
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'upper',
- function(s)
- {
- return (new String(s)).toUpperCase();
- }
- );
-
- jSmart.prototype.registerPlugin(
- 'modifier',
- 'wordwrap',
- function(s, width, wrapWith, breakWords)
- {
- width = width || 80;
- wrapWith = wrapWith || '\n';
-
- var lines = (new String(s)).split('\n');
- for (var i=0; i<lines.length; ++i)
- {
- var line = lines[i];
- var parts = ''
- while (line.length > width)
- {
- var pos = 0;
- var found = line.slice(pos).match(/\s+/);
- for (;found && (pos+found.index)<=width; found=line.slice(pos).match(/\s+/))
- {
- pos += found.index + found[0].length;
- }
- pos = pos || (breakWords ? width : (found ? found.index+found[0].length : line.length));
- parts += line.slice(0,pos).replace(/\s+$/,'');// + wrapWith;
- if (pos < line.length)
- {
- parts += wrapWith;
- }
- line = line.slice(pos);
- }
- lines[i] = parts + line;
- }
- return lines.join('\n');
- }
- );
-
-
- String.prototype.fetch = function(data)
- {
- var tpl = new jSmart(this);
- return tpl.fetch(data);
- };
-
- if (typeof module === "object" && module && typeof module.exports === "object") {
- module.exports = jSmart;
- } else {
- if (typeof global !== "undefined") {
- global.jSmart = jSmart;
- }
-
- if (typeof define === "function" && define.amd) {
- define("jSmart", [], function () { return jSmart; });
- }
- }
-})();
+++ /dev/null
-/*!
- * jSmart Javascript template engine (v2.15.0)
- * https://github.com/umakantp/jsmart
- * http://opensource.org/licenses/LGPL-3.0
- *
- * Copyright 2011-2015, Max Miroshnikov <miroshnikov at gmail dot com>
- * Umakant Patil <me @ umakantpatil dot com>
- */
-!function(){function obMerge(a){for(var b=1;b<arguments.length;++b)for(var c in arguments[b])a[c]=arguments[b][c];return a}function countProperties(a){var b=0;for(var c in a)a.hasOwnProperty(c)&&b++;return b}function findInArray(a,b){if(Array.prototype.indexOf)return a.indexOf(b);for(var c=0;c<a.length;++c)if(a[c]===b)return c;return-1}function evalString(a){return a.replace(/\\t/," ").replace(/\\n/,"\n").replace(/\\(['"\\])/g,"$1")}function trimQuotes(a){return evalString(a.replace(/^['"](.*)['"]$/,"$1")).replace(/^\s+|\s+$/g,"")}function findTag(a,b){for(var c=0,d=0,e=jSmart.prototype.left_delimiter,f=jSmart.prototype.right_delimiter,g=jSmart.prototype.auto_literal,h=/^\s*(.+)\s*$/i,i=a?new RegExp("^\\s*("+a+")\\s*$","i"):h,j=0;j<b.length;++j)if(b.substr(j,e.length)==e){if(g&&j+1<b.length&&b.substr(j+1,1).match(/\s/))continue;c||(b=b.slice(j),d+=parseInt(j),j=0),++c}else if(b.substr(j,f.length)==f){if(g&&j-1>=0&&b.substr(j-1,1).match(/\s/))continue;if(!--c){var k=b.slice(e.length,j).replace(/[\r\n]/g," "),l=k.match(i);if(l)return l.index=d,l[0]=b.slice(0,j+f.length),l}0>c&&(c=0)}return null}function findCloseTag(a,b,c){var d="",e=null,f=null,g=0;do{if(e&&(g+=e[0].length),e=findTag(a,c),!e)throw new Error("Unclosed {"+b+"}");d+=c.slice(0,e.index),g+=e.index,c=c.slice(e.index+e[0].length),f=findTag(b,d),f&&(d=d.slice(f.index+f[0].length))}while(f);return e.index=g,e}function findElseTag(a,b,c,d){for(var e=0,f=findTag(c,d);f;f=findTag(c,d)){var g=findTag(a,d);if(!g||g.index>f.index)return f.index+=e,f;d=d.slice(g.index+g[0].length),e+=g.index+g[0].length;var h=findCloseTag(b,a,d);d=d.slice(h.index+h[0].length),e+=h.index+h[0].length}return null}function execute(code,data){if("string"==typeof code)with({__code:code})with(modifiers)with(data)try{return eval(__code)}catch(e){throw new Error(e.message+" in \n"+code)}return code}function executeByFuncObject(a,b){try{return a.apply(this,b)}catch(c){throw new Error(c.message)}}function assignVar(a,b,c){a.match(/\[\]$/)?c[a.replace(/\[\]$/,"")].push(b):c[a]=b}function parse(a,b){for(var c=findTag("",a);c;c=findTag("",a)){c.index&&parseText(a.slice(0,c.index),b),a=a.slice(c.index+c[0].length);var d=c[1].match(/^\s*(\w+)(.*)$/);if(d){var e=d[1],f=d.length>2?d[2].replace(/^\s+|\s+$/g,""):"";if(e in buildInFunctions){var g=buildInFunctions[e],h=("parseParams"in g?g.parseParams:parseParams)(f);if("block"==g.type){a=a.replace(/^\n/,"");var i=findCloseTag("/"+e,e+" +[^}]*",a);g.parse(h,b,a.slice(0,i.index)),a=a.slice(i.index+i[0].length)}else g.parse(h,b),"extends"==e&&(b=[]);a=a.replace(/^\n/,"")}else if(e in plugins){var j=plugins[e];if("block"==j.type){var i=findCloseTag("/"+e,e+" +[^}]*",a);parsePluginBlock(e,parseParams(f),b,a.slice(0,i.index)),a=a.slice(i.index+i[0].length)}else"function"==j.type&&parsePluginFunc(e,parseParams(f),b);("append"==e||"assign"==e||"capture"==e||"eval"==e||"include"==e)&&(a=a.replace(/^\n/,""))}else buildInFunctions.expression.parse(c[1],b)}else{var k=buildInFunctions.expression.parse(c[1],b);"build-in"==k.type&&"operator"==k.name&&"="==k.op&&(a=a.replace(/^\n/,""))}}return a&&parseText(a,b),b}function parseText(a,b){if(parseText.parseEmbeddedVars)for(var c=/([$][\w@]+)|`([^`]*)`/,d=c.exec(a);d;d=c.exec(a))b.push({type:"text",data:a.slice(0,d.index)}),b.push(parseExpression(d[1]?d[1]:d[2]).tree),a=a.slice(d.index+d[0].length);return b.push({type:"text",data:a}),b}function parseFunc(a,b,c){return b.__parsed.name=parseText(a,[])[0],c.push({type:"plugin",name:"__func",params:b}),c}function parseOperator(a,b,c,d){d.push({type:"build-in",name:"operator",op:a,optype:b,precedence:c,params:{}})}function parseVar(a,b,c){for(var d=b.token,e=[{type:"text",data:c.replace(/^(\w+)@(key|index|iteration|first|last|show|total)/gi,"$1__$2")}],f=/^(?:\.|\s*->\s*|\[\s*)/,g=a.match(f);g;g=a.match(f)){b.token+=g[0],a=a.slice(g[0].length);var h={value:"",tree:[]};if(g[0].match(/\[/)){h=parseExpression(a),h&&(b.token+=h.value,e.push(h.tree),a=a.slice(h.value.length));var i=a.match(/\s*\]/);i&&(b.token+=i[0],a=a.slice(i[0].length))}else{var j=parseModifiers.stop;if(parseModifiers.stop=!0,lookUp(a,h)){b.token+=h.value;var k=h.tree[0];"plugin"==k.type&&"__func"==k.name&&(k.hasOwner=!0),e.push(k),a=a.slice(h.value.length)}else h=!1;parseModifiers.stop=j}h||e.push({type:"text",data:""})}return b.tree.push({type:"var",parts:e}),b.value+=b.token.substr(d.length),onParseVar(b.token),a}function onParseVar(){}function parseModifiers(a,b){if(!parseModifiers.stop){var c=a.match(/^\|(\w+)/);if(c){b.value+=c[0];var d="default"==c[1]?"defaultValue":c[1];a=a.slice(c[0].length).replace(/^\s+/,""),parseModifiers.stop=!0;for(var e=[],f=a.match(/^\s*:\s*/);f;f=a.match(/^\s*:\s*/)){b.value+=a.slice(0,f[0].length),a=a.slice(f[0].length);var g={value:"",tree:[]};lookUp(a,g)?(b.value+=g.value,e.push(g.tree[0]),a=a.slice(g.value.length)):parseText("",e)}parseModifiers.stop=!1,e.unshift(b.tree.pop()),b.tree.push(parseFunc(d,{__parsed:e},[])[0]),parseModifiers(a,b)}}}function lookUp(a,b){if(!a)return!1;if(a.substr(0,jSmart.prototype.left_delimiter.length)==jSmart.prototype.left_delimiter){var c=findTag("",a);if(c)return b.token=c[0],b.value+=c[0],parse(c[0],b.tree),parseModifiers(a.slice(b.value.length),b),!0}for(var d=0;d<tokens.length;++d)if(a.match(tokens[d].re))return b.token=RegExp.lastMatch,b.value+=RegExp.lastMatch,tokens[d].parse(b,a.slice(b.token.length)),!0;return!1}function bundleOp(a,b,c){var d=b[a];if("operator"==d.name&&d.precedence==c&&!d.params.__parsed){if("binary"==d.optype)return d.params.__parsed=[b[a-1],b[a+1]],b.splice(a-1,3,d),!0;if("post-unary"==d.optype)return d.params.__parsed=[b[a-1]],b.splice(a-1,2,d),!0;d.params.__parsed=[b[a+1]],b.splice(a,2,d)}return!1}function composeExpression(a){var b=0;for(b=0;b<a.length;++b)a[b]instanceof Array&&(a[b]=composeExpression(a[b]));for(var c=1;14>c;++c)if(2==c||10==c)for(b=a.length;b>0;--b)b-=bundleOp(b-1,a,c);else for(b=0;b<a.length;++b)b-=bundleOp(b,a,c);return a[0]}function parseExpression(a){for(var b={value:"",tree:[]};lookUp(a.slice(b.value.length),b););return b.tree.length?(b.tree=composeExpression(b.tree),b):!1}function parseParams(a,b,c){var d=a.replace(/\n/g," ").replace(/^\s+|\s+$/g,""),e=[];e.__parsed=[];var a="";if(!d)return e;for(b||(b=/^\s+/,c=/^(\w+)\s*=\s*/);d;){var f=null;if(c){var g=d.match(c);g&&(f=trimQuotes(g[1]),a+=d.slice(0,g[0].length),d=d.slice(g[0].length))}var h=parseExpression(d);if(!h)break;f?(e[f]=h.value,e.__parsed[f]=h.tree):(e.push(h.value),e.__parsed.push(h.tree)),a+=d.slice(0,h.value.length),d=d.slice(h.value.length);var i=d.match(b);if(!i)break;a+=d.slice(0,i[0].length),d=d.slice(i[0].length)}return e.toString=function(){return a},e}function parsePluginBlock(a,b,c,d){c.push({type:"plugin",name:a,params:b,subTree:parse(d,[])})}function parsePluginFunc(a,b,c){c.push({type:"plugin",name:a,params:b})}function getActualParamValues(a,b){var c=[];for(var d in a.__parsed)if(a.__parsed.hasOwnProperty(d)){var e=process([a.__parsed[d]],b);c[d]=e}return c.__get=function(a,b,d){if(a in c&&"undefined"!=typeof c[a])return c[a];if("undefined"!=typeof d&&"undefined"!=typeof c[d])return c[d];if(null===b)throw new Error("The required attribute '"+a+"' is missing");return b},c}function isEmptyObject(a){for(var b in a)if(a.hasOwnProperty(b))return!1;return!0}function getVarValue(a,b,c){for(var d=b,e="",f=0;f<a.parts.length;++f){var g=a.parts[f];if("plugin"==g.type&&"__func"==g.name&&g.hasOwner)b.__owner=d,d=process([a.parts[f]],b),delete b.__owner;else if(e=process([g],b),e in b.smarty.section&&"text"==g.type&&"smarty"!=process([a.parts[0]],b)&&(e=b.smarty.section[e].index),!e&&"undefined"!=typeof c&&d instanceof Array&&(e=d.length),"undefined"!=typeof c&&f==a.parts.length-1&&(d[e]=c),"object"==typeof d&&null!==d&&e in d)d=d[e];else{if("undefined"==typeof c)return c;d[e]={},d=d[e]}}return d}function process(a,b){for(var c="",d=0;d<a.length;++d){var e="",f=a[d];if("text"==f.type)e=f.data;else if("var"==f.type)e=getVarValue(f,b);else if("build-in"==f.type)e=buildInFunctions[f.name].process(f,b);else if("plugin"==f.type){var g=plugins[f.name];if("block"==g.type){var h={value:!0};for(g.process(getActualParamValues(f.params,b),"",b,h);h.value;)h.value=!1,e+=g.process(getActualParamValues(f.params,b),process(f.subTree,b),b,h)}else"function"==g.type&&(e=g.process(getActualParamValues(f.params,b),b))}if("boolean"==typeof e&&(e=e?"1":""),1==a.length)return e;if(c+=e,b.smarty["continue"]||b.smarty["break"])return c}return c}function getTemplate(a,b,c){if(!c&&a in files)b=files[a];else{var d=jSmart.prototype.getTemplate(a);if("string"!=typeof d)throw new Error("No template for "+a);parse(applyFilters(jSmart.prototype.filters_global.pre,stripComments(d.replace(/\r\n/g,"\n"))),b),files[a]=b}return b}function stripComments(a){for(var b="",c=a.match(/{\*/);c;c=a.match(/{\*/)){b+=a.slice(0,c.index),a=a.slice(c.index+c[0].length);var d=a.match(/\*}/);if(!d)throw new Error("Unclosed {*");a=a.slice(d.index+d[0].length)}return b+a}function applyFilters(a,b){for(var c=0;c<a.length;++c)b=a[c](b);return b}var buildInFunctions={expression:{parse:function(a,b){var c=parseExpression(a);return b.push({type:"build-in",name:"expression",expression:c.tree,params:parseParams(a.slice(c.value.length).replace(/^\s+|\s+$/g,""))}),c.tree},process:function(a,b){var c=getActualParamValues(a.params,b),d=process([a.expression],b);if(findInArray(c,"nofilter")<0){for(var e=0;e<default_modifiers.length;++e){var f=default_modifiers[e];f.params.__parsed[0]={type:"text",data:d},d=process([f],b)}escape_html&&(d=modifiers.escape(d)),d=applyFilters(varFilters,d),tpl_modifiers.length&&(__t=function(){return d},d=process(tpl_modifiers,b))}return d}},operator:{process:function(a,b){var c=getActualParamValues(a.params,b),d=c[0];if("binary"!=a.optype){if("!"==a.op)return!d;var e="var"==a.params.__parsed[0].type;e&&(d=getVarValue(a.params.__parsed[0],b));var f=d;if("pre-unary"==a.optype){switch(a.op){case"-":f=-d;break;case"++":f=++d;break;case"--":f=--d}e&&getVarValue(a.params.__parsed[0],b,d)}else{switch(a.op){case"++":d++;break;case"--":d--}getVarValue(a.params.__parsed[0],b,d)}return f}var g=c[1];if("="==a.op)return getVarValue(a.params.__parsed[0],b,g),"";if(a.op.match(/(\+=|-=|\*=|\/=|%=)/)){switch(d=getVarValue(a.params.__parsed[0],b),a.op){case"+=":d+=g;break;case"-=":d-=g;break;case"*=":d*=g;break;case"/=":d/=g;break;case"%=":d%=g}return getVarValue(a.params.__parsed[0],b,d)}if(a.op.match(/div/))return"div"!=a.op^d%g==0;if(a.op.match(/even/))return"even"!=a.op^d/g%2==0;if(a.op.match(/xor/))return(d||g)&&!(d&&g);switch(a.op){case"==":return d==g;case"!=":return d!=g;case"+":return Number(d)+Number(g);case"-":return Number(d)-Number(g);case"*":return Number(d)*Number(g);case"/":return Number(d)/Number(g);case"%":return Number(d)%Number(g);case"&&":return d&&g;case"||":return d||g;case"<":return g>d;case"<=":return g>=d;case">":return d>g;case">=":return d>=g;case"===":return d===g;case"!==":return d!==g}}},section:{type:"block",parse:function(a,b,c){var d=[],e=[];b.push({type:"build-in",name:"section",params:a,subTree:d,subTreeElse:e});var f=findElseTag("section [^}]+","/section","sectionelse",c);f?(parse(c.slice(0,f.index),d),parse(c.slice(f.index+f[0].length).replace(/^[\r\n]/,""),e)):parse(c,d)},process:function(a,b){var c=getActualParamValues(a.params,b),d={};b.smarty.section[c.__get("name",null,0)]=d;var e=c.__get("show",!0);if(d.show=e,!e)return process(a.subTreeElse,b);var f=parseInt(c.__get("start",0)),g=c.loop instanceof Object?countProperties(c.loop):isNaN(c.loop)?0:parseInt(c.loop),h=parseInt(c.__get("step",1)),i=parseInt(c.__get("max"));isNaN(i)&&(i=Number.MAX_VALUE),0>f?(f+=g,0>f&&(f=0)):f>=g&&(f=g?g-1:0);for(var j=0,k=0,l=f;l>=0&&g>l&&i>j;l+=h,++j)k=l;d.total=j,d.loop=j,j=0;var m="";for(l=f;l>=0&&g>l&&i>j&&!b.smarty["break"];l+=h,++j)d.first=l==f,d.last=0>l+h||l+h>=g,d.index=l,d.index_prev=l-h,d.index_next=l+h,d.iteration=d.rownum=j+1,m+=process(a.subTree,b),b.smarty["continue"]=!1;return b.smarty["break"]=!1,j?m:process(a.subTreeElse,b)}},setfilter:{type:"block",parseParams:function(a){return[parseExpression("__t()|"+a).tree]},parse:function(a,b,c){b.push({type:"build-in",name:"setfilter",params:a,subTree:parse(c,[])})},process:function(a,b){tpl_modifiers=a.params;var c=process(a.subTree,b);return tpl_modifiers=[],c}},"for":{type:"block",parseParams:function(a){var b=a.match(/^\s*\$(\w+)\s*=\s*([^\s]+)\s*to\s*([^\s]+)\s*(?:step\s*([^\s]+))?\s*(.*)$/);if(!b)throw new Error("Invalid {for} parameters: "+a);return parseParams("varName='"+b[1]+"' from="+b[2]+" to="+b[3]+" step="+(b[4]?b[4]:"1")+" "+b[5])},parse:function(a,b,c){var d=[],e=[];b.push({type:"build-in",name:"for",params:a,subTree:d,subTreeElse:e});var f=findElseTag("for\\s[^}]+","/for","forelse",c);f?(parse(c.slice(0,f.index),d),parse(c.slice(f.index+f[0].length),e)):parse(c,d)},process:function(a,b){var c=getActualParamValues(a.params,b),d=parseInt(c.__get("from")),e=parseInt(c.__get("to")),f=parseInt(c.__get("step"));isNaN(f)&&(f=1);var g=parseInt(c.__get("max"));isNaN(g)&&(g=Number.MAX_VALUE);for(var h=0,i="",j=Math.min(Math.ceil(((f>0?e-d:d-e)+1)/Math.abs(f)),g),k=parseInt(c.from);j>h&&!b.smarty["break"];k+=f,++h)b[c.varName]=k,i+=process(a.subTree,b),b.smarty["continue"]=!1;return b.smarty["break"]=!1,h||(i=process(a.subTreeElse,b)),i}},"if":{type:"block",parse:function(a,b,c){var d=[],e=[];b.push({type:"build-in",name:"if",params:a,subTreeIf:d,subTreeElse:e});var f=findElseTag("if\\s+[^}]+","/if","else[^}]*",c);if(f){parse(c.slice(0,f.index),d),c=c.slice(f.index+f[0].length);var g=f[1].match(/^else\s*if(.*)/);g?buildInFunctions["if"].parse(parseParams(g[1]),e,c.replace(/^\n/,"")):parse(c.replace(/^\n/,""),e)}else parse(c,d)},process:function(a,b){var c=getActualParamValues(a.params,b)[0];return c&&!(c instanceof Array&&0==c.length||"object"==typeof c&&isEmptyObject(c))?process(a.subTreeIf,b):process(a.subTreeElse,b)}},foreach:{type:"block",parseParams:function(a){var b=a.match(/^\s*([$].+)\s*as\s*[$](\w+)\s*(=>\s*[$](\w+))?\s*$/i);return b&&(a="from="+b[1]+" item="+(b[4]||b[2]),b[4]&&(a+=" key="+b[2])),parseParams(a)},parse:function(a,b,c){var d=[],e=[];b.push({type:"build-in",name:"foreach",params:a,subTree:d,subTreeElse:e});var f=findElseTag("foreach\\s[^}]+","/foreach","foreachelse",c);f?(parse(c.slice(0,f.index),d),parse(c.slice(f.index+f[0].length).replace(/^[\r\n]/,""),e)):parse(c,d)},process:function(a,b){var c=getActualParamValues(a.params,b),d=c.from;d instanceof Object||(d=[d]);var e=countProperties(d);b[c.item+"__total"]=e,"name"in c&&(b.smarty.foreach[c.name]={},b.smarty.foreach[c.name].total=e);var f="",g=0;for(var h in d)if(d.hasOwnProperty(h)){if(b.smarty["break"])break;b[c.item+"__key"]=isNaN(h)?h:parseInt(h),"key"in c&&(b[c.key]=b[c.item+"__key"]),b[c.item]=d[h],b[c.item+"__index"]=parseInt(g),b[c.item+"__iteration"]=parseInt(g+1),b[c.item+"__first"]=0===g,b[c.item+"__last"]=g==e-1,"name"in c&&(b.smarty.foreach[c.name].index=parseInt(g),b.smarty.foreach[c.name].iteration=parseInt(g+1),b.smarty.foreach[c.name].first=0===g?1:"",b.smarty.foreach[c.name].last=g==e-1?1:""),++g,f+=process(a.subTree,b),b.smarty["continue"]=!1}return b.smarty["break"]=!1,b[c.item+"__show"]=g>0,c.name&&(b.smarty.foreach[c.name].show=g>0?1:""),g>0?f:process(a.subTreeElse,b)}},"function":{type:"block",parse:function(a,b,c){var d=[];plugins[trimQuotes(a.name?a.name:a[0])]={type:"function",subTree:d,defautParams:a,process:function(a,b){var c=getActualParamValues(this.defautParams,b);return delete c.name,process(this.subTree,obMerge({},b,c,a))}},parse(c,d)}},php:{type:"block",parse:function(){}},"extends":{type:"function",parse:function(a,b){b.splice(0,b.length),getTemplate(trimQuotes(a.file?a.file:a[0]),b)}},block:{type:"block",parse:function(a,b,c){b.push({type:"build-in",name:"block",params:a}),a.append=findInArray(a,"append")>=0,a.prepend=findInArray(a,"prepend")>=0,a.hide=findInArray(a,"hide")>=0,a.hasChild=a.hasParent=!1,onParseVar=function(b){b.match(/^\s*[$]smarty.block.child\s*$/)&&(a.hasChild=!0),b.match(/^\s*[$]smarty.block.parent\s*$/)&&(a.hasParent=!0)};var b=parse(c,[]);onParseVar=function(){};var d=trimQuotes(a.name?a.name:a[0]);d in blocks||(blocks[d]=[]),blocks[d].push({tree:b,params:a})},process:function(a,b){b.smarty.block.parent=b.smarty.block.child="";var c=trimQuotes(a.params.name?a.params.name:a.params[0]);return this.processBlocks(blocks[c],blocks[c].length-1,b),b.smarty.block.child},processBlocks:function(a,b,c){if(!b&&a[b].params.hide)return void(c.smarty.block.child="");for(var d=!0,e=!1;b>=0;--b){if(a[b].params.hasParent){var f=c.smarty.block.child;c.smarty.block.child="",this.processBlocks(a,b-1,c),c.smarty.block.parent=c.smarty.block.child,c.smarty.block.child=f}var f=c.smarty.block.child,g=process(a[b].tree,c);c.smarty.block.child=f,a[b].params.hasChild?c.smarty.block.child=g:d?c.smarty.block.child=g+c.smarty.block.child:e&&(c.smarty.block.child+=g),d=a[b].params.append,e=a[b].params.prepend}}},strip:{type:"block",parse:function(a,b,c){parse(c.replace(/[ \t]*[\r\n]+[ \t]*/g,""),b)}},literal:{type:"block",parse:function(a,b,c){parseText(c,b)}},ldelim:{type:"function",parse:function(a,b){parseText(jSmart.prototype.left_delimiter,b)}},rdelim:{type:"function",parse:function(a,b){parseText(jSmart.prototype.right_delimiter,b)}},"while":{type:"block",parse:function(a,b,c){b.push({type:"build-in",name:"while",params:a,subTree:parse(c,[])})},process:function(a,b){for(var c="";getActualParamValues(a.params,b)[0]&&!b.smarty["break"];)c+=process(a.subTree,b),b.smarty["continue"]=!1;return b.smarty["break"]=!1,c}}},plugins={},modifiers={},files={},blocks=null,scripts=null,tpl_modifiers=[],tokens=[{re:/^\$([\w@]+)/,parse:function(a,b){parseModifiers(parseVar(b,a,RegExp.$1),a)}},{re:/^(true|false)/i,parse:function(a){parseText(a.token.match(/true/i)?"1":"",a.tree)}},{re:/^'([^'\\]*(?:\\.[^'\\]*)*)'/,parse:function(a,b){parseText(evalString(RegExp.$1),a.tree),parseModifiers(b,a)}},{re:/^"([^"\\]*(?:\\.[^"\\]*)*)"/,parse:function(a,b){var c=evalString(RegExp.$1),d=c.match(tokens[0].re);if(d){var e={token:d[0],tree:[]};if(parseVar(c,e,d[1]),e.token.length==c.length)return void a.tree.push(e.tree[0])}parseText.parseEmbeddedVars=!0,a.tree.push({type:"plugin",name:"__quoted",params:{__parsed:parse(c,[])}}),parseText.parseEmbeddedVars=!1,parseModifiers(b,a)}},{re:/^(\w+)\s*[(]([)]?)/,parse:function(a,b){var c=RegExp.$1,d=RegExp.$2,e=parseParams(d?"":b,/^\s*,\s*/);parseFunc(c,e,a.tree),a.value+=e.toString(),parseModifiers(b.slice(e.toString().length),a)}},{re:/^\s*\(\s*/,parse:function(a){var b=[];a.tree.push(b),b.parent=a.tree,a.tree=b}},{re:/^\s*\)\s*/,parse:function(a){a.tree.parent&&(a.tree=a.tree.parent)}},{re:/^\s*(\+\+|--)\s*/,parse:function(a){a.tree.length&&"var"==a.tree[a.tree.length-1].type?parseOperator(RegExp.$1,"post-unary",1,a.tree):parseOperator(RegExp.$1,"pre-unary",1,a.tree)}},{re:/^\s*(===|!==|==|!=)\s*/,parse:function(a){parseOperator(RegExp.$1,"binary",6,a.tree)}},{re:/^\s+(eq|ne|neq)\s+/i,parse:function(a){var b=RegExp.$1.replace(/ne(q)?/,"!=").replace(/eq/,"==");parseOperator(b,"binary",6,a.tree)}},{re:/^\s*!\s*/,parse:function(a){parseOperator("!","pre-unary",2,a.tree)}},{re:/^\s+not\s+/i,parse:function(a){parseOperator("!","pre-unary",2,a.tree)}},{re:/^\s*(=|\+=|-=|\*=|\/=|%=)\s*/,parse:function(a){parseOperator(RegExp.$1,"binary",10,a.tree)}},{re:/^\s*(\*|\/|%)\s*/,parse:function(a){parseOperator(RegExp.$1,"binary",3,a.tree)}},{re:/^\s+mod\s+/i,parse:function(a){parseOperator("%","binary",3,a.tree)}},{re:/^\s*(\+|-)\s*/,parse:function(a){a.tree.length&&"operator"!=a.tree[a.tree.length-1].name?parseOperator(RegExp.$1,"binary",4,a.tree):parseOperator(RegExp.$1,"pre-unary",4,a.tree)}},{re:/^\s*(<=|>=|<>|<|>)\s*/,parse:function(a){parseOperator(RegExp.$1.replace(/<>/,"!="),"binary",5,a.tree)}},{re:/^\s+(lt|lte|le|gt|gte|ge)\s+/i,parse:function(a){var b=RegExp.$1.replace(/lt/,"<").replace(/l(t)?e/,"<=").replace(/gt/,">").replace(/g(t)?e/,">=");parseOperator(b,"binary",5,a.tree)}},{re:/^\s+(is\s+(not\s+)?div\s+by)\s+/i,parse:function(a){parseOperator(RegExp.$2?"div_not":"div","binary",7,a.tree)}},{re:/^\s+is\s+(not\s+)?(even|odd)(\s+by\s+)?\s*/i,parse:function(a){var b=RegExp.$1?"odd"==RegExp.$2?"even":"even_not":"odd"==RegExp.$2?"even_not":"even";parseOperator(b,"binary",7,a.tree),RegExp.$3||parseText("1",a.tree)}},{re:/^\s*(&&)\s*/,parse:function(a){parseOperator(RegExp.$1,"binary",8,a.tree)}},{re:/^\s*(\|\|)\s*/,parse:function(a){parseOperator(RegExp.$1,"binary",9,a.tree)}},{re:/^\s+and\s+/i,parse:function(a){parseOperator("&&","binary",11,a.tree)}},{re:/^\s+xor\s+/i,parse:function(a){parseOperator("xor","binary",12,a.tree)}},{re:/^\s+or\s+/i,parse:function(a){parseOperator("||","binary",13,a.tree)}},{re:/^#(\w+)#/,parse:function(a,b){var c={token:"$smarty",tree:[]};parseVar(".config."+RegExp.$1,c,"smarty"),a.tree.push(c.tree[0]),parseModifiers(b,a)}},{re:/^\s*\[\s*/,parse:function(a,b){var c=parseParams(b,/^\s*,\s*/,/^('[^'\\]*(?:\\.[^'\\]*)*'|"[^"\\]*(?:\\.[^"\\]*)*"|\w+)\s*=>\s*/);parsePluginFunc("__array",c,a.tree),a.value+=c.toString();var d=b.slice(c.toString().length).match(/\s*\]/);d&&(a.value+=d[0])}},{re:/^[\d.]+/,parse:function(a,b){a.token=a.token.indexOf(".")>-1?parseFloat(a.token):parseInt(a.token,10),parseText(a.token,a.tree),parseModifiers(b,a)}},{re:/^\w+/,parse:function(a,b){parseText(a.token,a.tree),parseModifiers(b,a)}}];jSmart=function(a){this.tree=[],this.tree.blocks={},this.scripts={},this.default_modifiers=[],this.filters={variable:[],post:[]},this.smarty={smarty:{block:{},"break":!1,capture:{},"continue":!1,counter:{},cycle:{},foreach:{},section:{},now:Math.floor((new Date).getTime()/1e3),"const":{},config:{},current_dir:"/",template:"",ldelim:jSmart.prototype.left_delimiter,rdelim:jSmart.prototype.right_delimiter,version:"2.15.0"}},blocks=this.tree.blocks,parse(applyFilters(jSmart.prototype.filters_global.pre,stripComments(new String(a?a:"").replace(/\r\n/g,"\n"))),this.tree)},jSmart.prototype.fetch=function(a){blocks=this.tree.blocks,scripts=this.scripts,escape_html=this.escape_html,default_modifiers=jSmart.prototype.default_modifiers_global.concat(this.default_modifiers),this.data=obMerge("object"==typeof a?a:{},this.smarty),varFilters=jSmart.prototype.filters_global.variable.concat(this.filters.variable);var b=process(this.tree,this.data);return jSmart.prototype.debugging&&plugins.debug.process([],this.data),applyFilters(jSmart.prototype.filters_global.post.concat(this.filters.post),b)},jSmart.prototype.escape_html=!1,jSmart.prototype.registerPlugin=function(a,b,c){"modifier"==a?modifiers[b]=c:plugins[b]={type:a,process:c}},jSmart.prototype.registerFilter=function(a,b){(this.tree?this.filters:jSmart.prototype.filters_global)["output"==a?"post":a].push(b)},jSmart.prototype.filters_global={pre:[],variable:[],post:[]},jSmart.prototype.configLoad=function(a,b,c){c=c?c:this.data;for(var d=a.replace(/\r\n/g,"\n").replace(/^\s+|\s+$/g,""),e=/^\s*(?:\[([^\]]+)\]|(?:(\w+)[ \t]*=[ \t]*("""|'[^'\\\n]*(?:\\.[^'\\\n]*)*'|"[^"\\\n]*(?:\\.[^"\\\n]*)*"|[^\n]*)))/m,f="",g=d.match(e);g;g=d.match(e)){if(d=d.slice(g.index+g[0].length),g[1])f=g[1];else if((!f||f==b)&&"."!=f.substr(0,1))if('"""'==g[3]){var h=d.match(/"""/);h&&(c.smarty.config[g[2]]=d.slice(0,h.index),d=d.slice(h.index+h[0].length))}else c.smarty.config[g[2]]=trimQuotes(g[3]);var i=d.match(/\n+/);if(!i)break;d=d.slice(i.index+i[0].length)}},jSmart.prototype.clearConfig=function(a){a?delete this.data.smarty.config[a]:this.data.smarty.config={}},jSmart.prototype.addDefaultModifier=function(a){a instanceof Array||(a=[a]);for(var b=0;b<a.length;++b){var c={value:"",tree:[0]};parseModifiers("|"+a[b],c),(this.tree?this.default_modifiers:this.default_modifiers_global).push(c.tree[0])}},jSmart.prototype.default_modifiers_global=[],jSmart.prototype.getTemplate=function(a){throw new Error("No template for "+a)},jSmart.prototype.getFile=function(a){throw new Error("No file for "+a)},jSmart.prototype.getJavascript=function(a){throw new Error("No Javascript for "+a)},jSmart.prototype.getConfig=function(a){throw new Error("No config for "+a)},jSmart.prototype.auto_literal=!0,jSmart.prototype.left_delimiter="{",jSmart.prototype.right_delimiter="}",jSmart.prototype.debugging=!1,jSmart.prototype.PHPJS=function(fnm,modifier){if("function"==eval("typeof "+fnm))return"object"==typeof window?window:global;if("function"==typeof PHP_JS)return new PHP_JS;throw new Error("Modifier '"+modifier+"' uses JavaScript port of PHP function '"+fnm+"'. You can find one at http://phpjs.org")},jSmart.prototype.makeTimeStamp=function(a){if(!a)return Math.floor((new Date).getTime()/1e3);if(isNaN(a)){var b=jSmart.prototype.PHPJS("strtotime","date_format").strtotime(a);return-1==b||b===!1?Math.floor((new Date).getTime()/1e3):b}return a=new String(a),14==a.length?Math.floor(new Date(a.substr(0,4),a.substr(4,2)-1,a.substr(6,2),a.substr(8,2),a.substr(10,2)).getTime()/1e3):parseInt(a)},jSmart.prototype.registerPlugin("function","__array",function(a){var b=[];for(var c in a)a.hasOwnProperty(c)&&a[c]&&"function"!=typeof a[c]&&(b[c]=a[c]);return b}),jSmart.prototype.registerPlugin("function","__func",function(a,b){for(var c=[],d={},e=[],f=0;f<a.length;++f)c.push(a.name+"__p"+f),e.push(a[f]),d[a.name+"__p"+f]=a[f];var g,h=obMerge({},b,d);return"__owner"in b&&a.name in b.__owner?(g="__owner."+a.name,execute(g+"("+c.join(",")+")",h)):modifiers.hasOwnProperty(a.name)?(g=modifiers[a.name],executeByFuncObject(g,e,h)):(g=a.name,execute(g+"("+c.join(",")+")",h))}),jSmart.prototype.registerPlugin("function","__quoted",function(a){return a.join("")}),jSmart.prototype.registerPlugin("function","append",function(a,b){var c=a.__get("var",null,0);c in b&&b[c]instanceof Array||(b[c]=[]);var d=a.__get("index",!1),e=a.__get("value",null,1);return d===!1?b[c].push(e):b[c][d]=e,""}),jSmart.prototype.registerPlugin("function","assign",function(a,b){return assignVar(a.__get("var",null,0),a.__get("value",null,1),b),""}),jSmart.prototype.registerPlugin("function","break",function(a,b){return b.smarty["break"]=!0,""}),jSmart.prototype.registerPlugin("function","call",function(a,b){var c=a.__get("name",null,0);delete a.name;var d=a.__get("assign",!1);delete a.assign;var e=plugins[c].process(a,b);return d?(assignVar(d,e,b),""):e}),jSmart.prototype.registerPlugin("block","capture",function(a,b,c){if(b){b=b.replace(/^\n/,""),c.smarty.capture[a.__get("name","default",0)]=b,"assign"in a&&assignVar(a.assign,b,c);var d=a.__get("append",!1);d&&(d in c?c[d]instanceof Array&&c[d].push(b):c[d]=[b])}return""}),jSmart.prototype.registerPlugin("function","continue",function(a,b){return b.smarty["continue"]=!0,""}),jSmart.prototype.registerPlugin("function","counter",function(a,b){var c=a.__get("name","default");if(c in b.smarty.counter){var d=b.smarty.counter[c];"start"in a?d.value=parseInt(a.start):(d.value=parseInt(d.value),d.skip=parseInt(d.skip),"down"==d.direction?d.value-=d.skip:d.value+=d.skip),d.skip=a.__get("skip",d.skip),d.direction=a.__get("direction",d.direction),d.assign=a.__get("assign",d.assign)}else b.smarty.counter[c]={value:parseInt(a.__get("start",1)),skip:parseInt(a.__get("skip",1)),direction:a.__get("direction","up"),assign:a.__get("assign",!1)};return b.smarty.counter[c].assign?(b[b.smarty.counter[c].assign]=b.smarty.counter[c].value,""):a.__get("print",!0)?b.smarty.counter[c].value:""}),jSmart.prototype.registerPlugin("function","cycle",function(a,b){var c=a.__get("name","default"),d=a.__get("reset",!1);c in b.smarty.cycle||(b.smarty.cycle[c]={arr:[""],delimiter:a.__get("delimiter",","),index:0},d=!0),a.__get("delimiter",!1)&&(b.smarty.cycle[c].delimiter=a.delimiter);var e=a.__get("values",!1);if(e){var f=[];if(e instanceof Object)for(nm in e)f.push(e[nm]);else f=e.split(b.smarty.cycle[c].delimiter);(f.length!=b.smarty.cycle[c].arr.length||f[0]!=b.smarty.cycle[c].arr[0])&&(b.smarty.cycle[c].arr=f,b.smarty.cycle[c].index=0,d=!0)}return a.__get("advance","true")&&(b.smarty.cycle[c].index+=1),(b.smarty.cycle[c].index>=b.smarty.cycle[c].arr.length||d)&&(b.smarty.cycle[c].index=0),a.__get("assign",!1)?(assignVar(a.assign,b.smarty.cycle[c].arr[b.smarty.cycle[c].index],b),""):a.__get("print",!0)?b.smarty.cycle[c].arr[b.smarty.cycle[c].index]:""}),jSmart.prototype.print_r=function(a,b){if(a instanceof Object){var c=(a instanceof Array?"Array["+a.length+"]":"Object")+"<br>";for(var d in a)a.hasOwnProperty(d)&&(c+=b+" <strong>"+d+"</strong> : "+jSmart.prototype.print_r(a[d],b+" ")+"<br>");return c}return a},jSmart.prototype.registerPlugin("function","debug",function(a,b){"undefined"!=typeof dbgWnd&&dbgWnd.close(),dbgWnd=window.open("","","width=680,height=600,resizable,scrollbars=yes");var c="",d=0;for(var e in b)c+="<tr class="+(++d%2?"odd":"even")+"><td><strong>"+e+"</strong></td><td>"+jSmart.prototype.print_r(b[e],"")+"</td></tr>";return dbgWnd.document.write(" <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en'> <head> <title>jSmart Debug Console</title> <style type='text/css'> table {width: 100%;} td {vertical-align:top;width: 50%;} .even td {background-color: #fafafa;} </style> </head> <body> <h1>jSmart Debug Console</h1> <h2>assigned template variables</h2> <table>"+c+"</table> </body> </html> "),""}),jSmart.prototype.registerPlugin("function","eval",function(a,b){var c=[];parse(a.__get("var","",0),c);var d=process(c,b);return"assign"in a?(assignVar(a.assign,d,b),""):d}),jSmart.prototype.registerPlugin("function","fetch",function(a,b){var c=jSmart.prototype.getFile(a.__get("file",null,0));return"assign"in a?(assignVar(a.assign,c,b),""):c}),jSmart.prototype.registerPlugin("function","html_checkboxes",function(a,b){var c,d,e,f=a.__get("type","checkbox"),g=a.__get("name",f),h=a.__get("name",f),i=a.__get("values",a.options),j=a.__get("options",[]),k="options"in a,l=a.__get("selected",!1),m=a.__get("separator",""),n=Boolean(a.__get("labels",!0)),o=Boolean(a.__get("label_ids",!1)),p=[],q=0,r="";if("checkbox"==f&&(g+="[]"),!k)for(c in a.output)j.push(a.output[c]);for(c in i)i.hasOwnProperty(c)&&(d=k?c:i[c],e=h+"_"+d,r=n?o?'<label for="'+e+'">':"<label>":"",r+='<input type="'+f+'" name="'+g+'" value="'+d+'" ',o&&(r+='id="'+e+'" '),l==(k?c:i[c])&&(r+='checked="checked" '),r+="/>"+j[k?c:q++],r+=n?"</label>":"",r+=m,p.push(r));return"assign"in a?(assignVar(a.assign,p,b),""):p.join("\n")}),jSmart.prototype.registerPlugin("function","html_image",function(a){var b,c=a.__get("file",null),d=a.__get("width",!1),e=a.__get("height",!1),f=a.__get("alt",""),g=a.__get("href",a.__get("link",!1)),h=a.__get("path_prefix",""),i={file:1,width:1,height:1,alt:1,href:1,basedir:1,path_prefix:1,link:1},j='<img src="'+h+c+'" alt="'+f+'"'+(d?' width="'+d+'"':"")+(e?' height="'+e+'"':"");for(b in a)a.hasOwnProperty(b)&&"string"==typeof a[b]&&(b in i||(j+=" "+b+'="'+a[b]+'"'));return j+=" />",g?'<a href="'+g+'">'+j+"</a>":j}),jSmart.prototype.registerPlugin("function","html_options",function(a){var b,c=a.__get("values",a.options),d=a.__get("options",[]),e="options"in a;if(!e)for(b in a.output)d.push(a.output[b]);var f=a.__get("selected",!1),g=[],h="",i=0;for(b in c)c.hasOwnProperty(b)&&(h='<option value="'+(e?b:c[b])+'"',f==(e?b:c[b])&&(h+=' selected="selected"'),h+=">"+d[e?b:i++]+"</option>",g.push(h));var j=a.__get("name",!1);return(j?'<select name="'+j+'">\n'+g.join("\n")+"\n</select>":g.join("\n"))+"\n"}),jSmart.prototype.registerPlugin("function","html_radios",function(a,b){return a.type="radio",plugins.html_checkboxes.process(a,b)}),jSmart.prototype.registerPlugin("function","html_select_date",function(a){var b=a.__get("prefix","Date_"),c=["January","February","March","April","May","June","July","August","September","October","November","December"],d="";d+='<select name="'+b+'Month">\n';
-var e=0;for(e=0;e<c.length;++e)d+='<option value="'+e+'">'+c[e]+"</option>\n";for(d+="</select>\n",d+='<select name="'+b+'Day">\n',e=0;31>e;++e)d+='<option value="'+e+'">'+e+"</option>\n";return d+="</select>\n"}),jSmart.prototype.registerPlugin("function","html_table",function(a){var b,c=[];if(a.loop instanceof Array)c=a.loop;else for(b in a.loop)a.loop.hasOwnProperty(b)&&c.push(a.loop[b]);var d=a.__get("rows",!1),e=a.__get("cols",!1);e||(e=d?Math.ceil(c.length/d):3);var f=[];if(isNaN(e)){if("object"==typeof e)for(b in e)e.hasOwnProperty(b)&&f.push(e[b]);else f=e.split(/\s*,\s*/);e=f.length}d=d?d:Math.ceil(c.length/e);var g=a.__get("inner","cols"),h=a.__get("caption",""),i=a.__get("table_attr",'border="1"'),j=a.__get("th_attr",!1);j&&"object"!=typeof j&&(j=[j]);var k=a.__get("tr_attr",!1);k&&"object"!=typeof k&&(k=[k]);var l=a.__get("td_attr",!1);l&&"object"!=typeof l&&(l=[l]);for(var m=a.__get("trailpad"," "),n=a.__get("hdir","right"),o=a.__get("vdir","down"),p="",q=0;d>q;++q){p+="<tr"+(k?" "+k[q%k.length]:"")+">\n";for(var r=0;e>r;++r){var s="cols"==g?("down"==o?q:d-1-q)*e+("right"==n?r:e-1-r):("right"==n?r:e-1-r)*d+("down"==o?q:d-1-q);p+="<td"+(l?" "+l[r%l.length]:"")+">"+(s<c.length?c[s]:m)+"</td>\n"}p+="</tr>\n"}var t="";if(f.length){t="\n<thead><tr>";for(var u=0;u<f.length;++u)t+="\n<th"+(j?" "+j[u%j.length]:"")+">"+f["right"==n?u:f.length-1-u]+"</th>";t+="\n</tr></thead>"}return"<table "+i+">"+(h?"\n<caption>"+h+"</caption>":"")+t+"\n<tbody>\n"+p+"</tbody>\n</table>\n"}),jSmart.prototype.registerPlugin("function","include",function(a,b){var c=a.__get("file",null,0),d=obMerge({},b,a);d.smarty.template=c;var e=process(getTemplate(c,[],findInArray(a,"nocache")>=0),d);return"assign"in a?(assignVar(a.assign,e,b),""):e}),jSmart.prototype.registerPlugin("function","include_javascript",function(a,b){var c=a.__get("file",null,0);if(a.__get("once",!0)&&c in scripts)return"";scripts[c]=!0;var d=execute(jSmart.prototype.getJavascript(c),{$this:b});return"assign"in a?(assignVar(a.assign,d,b),""):d}),jSmart.prototype.registerPlugin("function","include_php",function(a,b){return plugins.include_javascript.process(a,b)}),jSmart.prototype.registerPlugin("function","insert",function(params,data){var fparams={};for(var nm in params)params.hasOwnProperty(nm)&&isNaN(nm)&¶ms[nm]&&"string"==typeof params[nm]&&"name"!=nm&&"assign"!=nm&&"script"!=nm&&(fparams[nm]=params[nm]);var prefix="insert_";"script"in params&&(eval(jSmart.prototype.getJavascript(params.script)),prefix="smarty_insert_");var func=eval(prefix+params.__get("name",null,0)),s=func(fparams,data);return"assign"in params?(assignVar(params.assign,s,data),""):s}),jSmart.prototype.registerPlugin("block","javascript",function(a,b,c){return c.$this=c,execute(b,c),delete c.$this,""}),jSmart.prototype.registerPlugin("function","config_load",function(a,b){return jSmart.prototype.configLoad(jSmart.prototype.getConfig(a.__get("file",null,0)),a.__get("section","",1),b),""}),jSmart.prototype.registerPlugin("function","mailto",function(a){var b=a.__get("address",null),c=a.__get("encode","none"),d=a.__get("text",b),e=jSmart.prototype.PHPJS("rawurlencode","mailto").rawurlencode(a.__get("cc","")).replace("%40","@"),f=jSmart.prototype.PHPJS("rawurlencode","mailto").rawurlencode(a.__get("bcc","")).replace("%40","@"),g=jSmart.prototype.PHPJS("rawurlencode","mailto").rawurlencode(a.__get("followupto","")).replace("%40","@"),h=jSmart.prototype.PHPJS("rawurlencode","mailto").rawurlencode(a.__get("subject","")),i=jSmart.prototype.PHPJS("rawurlencode","mailto").rawurlencode(a.__get("newsgroups","")),j=a.__get("extra","");if(b+=e?"?cc="+e:"",b+=f?(e?"&":"?")+"bcc="+f:"",b+=h?(e||f?"&":"?")+"subject="+h:"",b+=i?(e||f||h?"&":"?")+"newsgroups="+i:"",b+=g?(e||f||h||i?"&":"?")+"followupto="+g:"",s='<a href="mailto:'+b+'" '+j+">"+d+"</a>","javascript"==c){s="document.write('"+s+"');";for(var k="",l=0;l<s.length;++l)k+="%"+jSmart.prototype.PHPJS("bin2hex","mailto").bin2hex(s.substr(l,1));return'<script type="text/javascript">eval(unescape(\''+k+"'))</script>"}if("javascript_charcode"==c){for(var m=[],l=0;l<s.length;++l)m.push(jSmart.prototype.PHPJS("ord","mailto").ord(s.substr(l,1)));return'<script type="text/javascript" language="javascript">\n<!--\n{document.write(String.fromCharCode('+m.join(",")+"))}\n//-->\n</script>\n"}if("hex"==c){if(b.match(/^.+\?.+$/))throw new Error("mailto: hex encoding does not work with extra attributes. Try javascript.");for(var n="",l=0;l<b.length;++l)n+=b.substr(l,1).match(/\w/)?"%"+jSmart.prototype.PHPJS("bin2hex","mailto").bin2hex(b.substr(l,1)):b.substr(l,1);for(var o="",l=0;l<d.length;++l)o+="&#x"+jSmart.prototype.PHPJS("bin2hex","mailto").bin2hex(d.substr(l,1))+";";return'<a href="mailto:'+n+'" '+j+">"+o+"</a>"}return s}),jSmart.prototype.registerPlugin("function","math",function(params,data){with(Math)with(params)var res=eval(params.__get("equation",null).replace(/pi\(\s*\)/g,"PI"));return"format"in params&&(res=jSmart.prototype.PHPJS("sprintf","math").sprintf(params.format,res)),"assign"in params?(assignVar(params.assign,res,data),""):res}),jSmart.prototype.registerPlugin("block","nocache",function(a,b){return b}),jSmart.prototype.registerPlugin("block","textformat",function(a,b,c){if(!b)return"";var d=a.__get("wrap",80),e=a.__get("wrap_char","\n"),f=a.__get("wrap_cut",!1),g=a.__get("indent_char"," "),h=a.__get("indent",0),i=new Array(h+1).join(g),j=a.__get("indent_first",0),k=new Array(j+1).join(g),l=a.__get("style","");"email"==l&&(d=72);for(var m=b.split(/[\r\n]{2}/),n=0;n<m.length;++n){var o=m[n];o&&(o=o.replace(/^\s+|\s+$/,"").replace(/\s+/g," "),j>0&&(o=k+o),o=modifiers.wordwrap(o,d-h,e,f),h>0&&(o=o.replace(/^/gm,i)),m[n]=o)}var p=m.join(e+e);return"assign"in a?(assignVar(a.assign,p,c),""):p}),jSmart.prototype.registerPlugin("modifier","capitalize",function(a,b,c){var d=new RegExp(b?"[^a-zA-Z_à -ü]+":"[^a-zA-Z0-9_à -ü]"),e=null,f="";for(c&&(a=a.toLowerCase()),e=a.match(d);e;e=a.match(d)){var g=a.slice(0,e.index);f+=g.match(/\d/)?g:g.charAt(0).toUpperCase()+g.slice(1),f+=a.slice(e.index,e.index+e[0].length),a=a.slice(e.index+e[0].length)}return a.match(/\d/)?f+a:f+a.charAt(0).toUpperCase()+a.slice(1)}),jSmart.prototype.registerPlugin("modifier","cat",function(a,b){return b=b?b:"",a+b}),jSmart.prototype.registerPlugin("modifier","count",function(a,b){if(null===a||"undefined"==typeof a)return 0;if(a.constructor!==Array&&a.constructor!==Object)return 1;b=Boolean(b);var c,d=0;for(c in a)a.hasOwnProperty(c)&&(d++,b&&a[c]&&(a[c].constructor===Array||a[c].constructor===Object)&&(d+=modifiers.count(a[c],!0)));return d}),jSmart.prototype.registerPlugin("modifier","count_characters",function(a,b){return b?a.length:a.replace(/\s/g,"").length}),jSmart.prototype.registerPlugin("modifier","count_paragraphs",function(a){var b=a.match(/\n+/g);return b?b.length+1:1}),jSmart.prototype.registerPlugin("modifier","count_sentences",function(a){var b=a.match(/[^\s]\.(?!\w)/g);return b?b.length:0}),jSmart.prototype.registerPlugin("modifier","count_words",function(a){var b=a.match(/\w+/g);return b?b.length:0}),jSmart.prototype.registerPlugin("modifier","date_format",function(a,b,c){return jSmart.prototype.PHPJS("strftime","date_format").strftime(b?b:"%b %e, %Y",jSmart.prototype.makeTimeStamp(a?a:c))}),jSmart.prototype.registerPlugin("modifier","defaultValue",function(a,b){return a&&"null"!=a&&"undefined"!=a?a:b?b:""}),jSmart.prototype.registerPlugin("modifier","unescape",function(a,b,c){switch(a=new String(a),b=b||"html",c=c||"UTF-8",b){case"html":return a.replace(/</g,"<").replace(/>/g,">").replace(/'/g,"'").replace(/"/g,'"');case"entity":case"htmlall":return jSmart.prototype.PHPJS("html_entity_decode","unescape").html_entity_decode(a,0);case"url":return jSmart.prototype.PHPJS("rawurldecode","unescape").rawurldecode(a)}return a}),jSmart.prototype.registerPlugin("modifier","escape",function(a,b,c,d){switch(a=new String(a),b=b||"html",c=c||"UTF-8",d="undefined"!=typeof d?Boolean(d):!0,b){case"html":return d&&(a=a.replace(/&/g,"&")),a.replace(/</g,"<").replace(/>/g,">").replace(/'/g,"'").replace(/"/g,""");case"htmlall":return jSmart.prototype.PHPJS("htmlentities","escape").htmlentities(a,3,c);case"url":return jSmart.prototype.PHPJS("rawurlencode","escape").rawurlencode(a);case"urlpathinfo":return jSmart.prototype.PHPJS("rawurlencode","escape").rawurlencode(a).replace(/%2F/g,"/");case"quotes":return a.replace(/(^|[^\\])'/g,"$1\\'");case"hex":for(var e="",f=0;f<a.length;++f)e+="%"+jSmart.prototype.PHPJS("bin2hex","escape").bin2hex(a.substr(f,1));return e;case"hexentity":for(var e="",f=0;f<a.length;++f)e+="&#x"+jSmart.prototype.PHPJS("bin2hex","escape").bin2hex(a.substr(f,1)).toLowerCase()+";";return e;case"decentity":for(var e="",f=0;f<a.length;++f)e+="&#"+jSmart.prototype.PHPJS("ord","escape").ord(a.substr(f,1))+";";return e;case"mail":return a.replace(/@/g," [AT] ").replace(/[.]/g," [DOT] ");case"nonstd":for(var e="",f=0;f<a.length;++f){var g=jSmart.prototype.PHPJS("ord","escape").ord(a.substr(f,1));e+=g>=126?"&#"+g+";":a.substr(f,1)}return e;case"javascript":return a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/"/g,'\\"').replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/<\//g,"</")}return a}),jSmart.prototype.registerPlugin("modifier","indent",function(a,b,c){b=b?b:4,c=c?c:" ";for(var d="";b--;)d+=c;var e=a.match(/\n+$/);return d+a.replace(/\n+$/,"").replace(/\n/g,"\n"+d)+(e?e[0]:"")}),jSmart.prototype.registerPlugin("modifier","lower",function(a){return a.toLowerCase()}),jSmart.prototype.registerPlugin("modifier","nl2br",function(a){return a.replace(/\n/g,"<br />\n")}),jSmart.prototype.registerPlugin("modifier","regex_replace",function(a,b,c){var d=b.match(/^ *\/(.*)\/(.*) *$/);return new String(a).replace(new RegExp(d[1],"g"+(d.length>1?d[2]:"")),c)}),jSmart.prototype.registerPlugin("modifier","replace",function(a,b,c){if(!b)return a;a=new String(a),b=new String(b),c=new String(c);var d="",e=-1;for(e=a.indexOf(b);e>=0;e=a.indexOf(b))d+=a.slice(0,e)+c,e+=b.length,a=a.slice(e);return d+a}),jSmart.prototype.registerPlugin("modifier","spacify",function(a,b){return b||(b=" "),a.replace(/(\n|.)(?!$)/g,"$1"+b)}),jSmart.prototype.registerPlugin("modifier","noprint",function(){return""}),jSmart.prototype.registerPlugin("modifier","string_format",function(a,b){return jSmart.prototype.PHPJS("sprintf","string_format").sprintf(b,a)}),jSmart.prototype.registerPlugin("modifier","strip",function(a,b){return b=b?b:" ",new String(a).replace(/[\s]+/g,b)}),jSmart.prototype.registerPlugin("modifier","strip_tags",function(a,b){return b=null==b?!0:b,new String(a).replace(/<[^>]*?>/g,b?" ":"")}),jSmart.prototype.registerPlugin("modifier","truncate",function(a,b,c,d,e){return b=b?b:80,c=null!=c?c:"...",a.length<=b?a:(b-=Math.min(b,c.length),e?a.slice(0,Math.floor(b/2))+c+a.slice(a.length-Math.floor(b/2)):(d||(a=a.slice(0,b+1).replace(/\s+?(\S+)?$/,"")),a.slice(0,b)+c))}),jSmart.prototype.registerPlugin("modifier","upper",function(a){return a.toUpperCase()}),jSmart.prototype.registerPlugin("modifier","wordwrap",function(a,b,c,d){b=b||80,c=c||"\n";for(var e=a.split("\n"),f=0;f<e.length;++f){for(var g=e[f],h="";g.length>b;){for(var i=0,j=g.slice(i).match(/\s+/);j&&i+j.index<=b;j=g.slice(i).match(/\s+/))i+=j.index+j[0].length;i=i||(d?b:j?j.index+j[0].length:g.length),h+=g.slice(0,i).replace(/\s+$/,""),i<g.length&&(h+=c),g=g.slice(i)}e[f]=h+g}return e.join("\n")}),String.prototype.fetch=function(a){var b=new jSmart(this);return b.fetch(a)},"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=jSmart:("undefined"!=typeof global&&(global.jSmart=jSmart),"function"==typeof define&&define.amd&&define("jSmart",[],function(){return jSmart}))}();
\ No newline at end of file
* It is licensed under the GNU Affero General Public License <http://www.gnu.org/licenses/>
*
*/
-$(document).ready(function(){
- // Elements with the class "userinfo" will get a hover-card.
- // Note that this elements does need a href attribute which links to
- // a valid profile url
- $("body").on("mouseover", ".userinfo, .wall-item-responses a, .wall-item-bottom .mention a", function(e) {
- var timeNow = new Date().getTime();
- removeAllhoverCards(e,timeNow);
- var hoverCardData = false;
- var hrefAttr = false;
- var targetElement = $(this);
-
- // get href-attribute
- if(targetElement.is('[href]')) {
- hrefAttr = targetElement.attr('href');
- } else {
- return true;
- }
-
- // no hover card if the element has the no-hover-card class
- if(targetElement.hasClass('no-hover-card')) {
- return true;
- }
-
- // no hovercard for anchor links
- if(hrefAttr.substring(0,1) == '#') {
- return true;
- }
+$(document).ready(function () {
+ let $body = $('body');
+ // Prevents normal click action on click hovercard elements
+ $body.on('click', '.userinfo.click-card', function (e) {
+ e.preventDefault();
+ });
+ // This event listener needs to be declared before the one that removes
+ // all cards so that we can stop the immediate propagation of the event
+ // Since the manual popover appears instantly and the hovercard removal is
+ // on a 100ms delay, leaving event propagation immediately hides any click hovercard
+ $body.on('mousedown', '.userinfo.click-card', function (e) {
+ e.stopImmediatePropagation();
+ let timeNow = new Date().getTime();
+
+ let contactUrl = false;
+ let targetElement = $(this);
+
+ // get href-attribute
+ if (targetElement.is('[href]')) {
+ contactUrl = targetElement.attr('href');
+ } else {
+ return true;
+ }
- targetElement.attr('data-awaiting-hover-card',timeNow);
+ // no hovercard for anchor links
+ if (contactUrl.substring(0, 1) === '#') {
+ return true;
+ }
- // Take link href attribute as link to the profile
- var profileurl = hrefAttr;
- // the url to get the contact and template data
- var url = baseurl + "/hovercard";
+ openHovercard(targetElement, contactUrl, timeNow);
+ });
- // store the title in an other data attribute beause bootstrap
- // popover destroys the title.attribute. We can restore it later
- var title = targetElement.attr("title");
- targetElement.attr({"data-orig-title": title, title: ""});
+ // hover cards should be removed very easily, e.g. when any of these events happens
+ $body.on('mouseleave touchstart scroll mousedown submit keydown', function (e) {
+ // remove hover card only for desktiop user, since on mobile we open the hovercards
+ // by click event insteadof hover
+ removeAllHovercards(e, new Date().getTime());
+ });
- // if the device is a mobile open the hover card by click and not by hover
- if(typeof is_mobile != "undefined") {
- targetElement[0].removeAttribute("href");
- var hctrigger = 'click';
- } else {
- var hctrigger = 'manual';
- };
+ $body.on('mouseover', '.userinfo.hover-card, .wall-item-responses a, .wall-item-bottom .mention a', function (e) {
+ let timeNow = new Date().getTime();
+ removeAllHovercards(e, timeNow);
+ let contactUrl = false;
+ let targetElement = $(this);
+
+ // get href-attribute
+ if (targetElement.is('[href]')) {
+ contactUrl = targetElement.attr('href');
+ } else {
+ return true;
+ }
- // Timeout until the hover-card does appear
- setTimeout(function(){
- if(targetElement.is(":hover") && parseInt(targetElement.attr('data-awaiting-hover-card'),10) == timeNow) {
- if($('.hovercard').length == 0) { // no card if there already is one open
- // get an additional data atribute if the card is active
- targetElement.attr('data-hover-card-active',timeNow);
- // get the whole html content of the hover card and
- // push it to the bootstrap popover
- getHoverCardContent(profileurl, url, function(data){
- if(data) {
- targetElement.popover({
- html: true,
- placement: function () {
- // Calculate the placement of the the hovercard (if top or bottom)
- // The placement depence on the distance between window top and the element
- // which triggers the hover-card
- var get_position = $(targetElement).offset().top - $(window).scrollTop();
- if (get_position < 270 ){
- return "bottom";
- }
- return "top";
- },
- trigger: hctrigger,
- template: '<div class="popover hovercard" data-card-created="' + timeNow + '"><div class="arrow"></div><div class="popover-content hovercard-content"></div></div>',
- content: data,
- container: "body",
- sanitizeFn: function (content) {
- return DOMPurify.sanitize(content)
- },
- }).popover('show');
- }
- });
- }
- }
- }, 500);
- }).on("mouseleave", ".userinfo, .wall-item-responses a, .wall-item-bottom .mention a", function(e) { // action when mouse leaves the hover-card
- var timeNow = new Date().getTime();
- // copy the original title to the title atribute
- var title = $(this).attr("data-orig-title");
- $(this).attr({"data-orig-title": "", title: title});
- removeAllhoverCards(e,timeNow);
- });
+ // no hover card if the element has the no-hover-card class
+ if (targetElement.hasClass('no-hover-card')) {
+ return true;
+ }
+ // no hovercard for anchor links
+ if (contactUrl.substring(0, 1) === '#') {
+ return true;
+ }
+ targetElement.attr('data-awaiting-hover-card', timeNow);
- // hover cards should be removed very easily, e.g. when any of these events happen
- $('body').on("mouseleave touchstart scroll click dblclick mousedown mouseup submit keydown keypress keyup", function(e){
- // remove hover card only for desktiop user, since on mobile we openen the hovercards
- // by click event insteadof hover
- if(typeof is_mobile == "undefined") {
- var timeNow = new Date().getTime();
- removeAllhoverCards(e,timeNow);
- };
+ // Delay until the hover-card does appear
+ setTimeout(function () {
+ if (
+ targetElement.is(':hover')
+ && parseInt(targetElement.attr('data-awaiting-hover-card'), 10) === timeNow
+ && $('.hovercard').length === 0
+ ) {
+ openHovercard(targetElement, contactUrl, timeNow);
+ }
+ }, 500);
+ }).on('mouseleave', '.userinfo.hover-card, .wall-item-responses a, .wall-item-bottom .mention a', function (e) { // action when mouse leaves the hover-card
+ removeAllHovercards(e, new Date().getTime());
});
// if we're hovering a hover card, give it a class, so we don't remove it
- $('body').on('mouseover','.hovercard', function(e) {
+ $body.on('mouseover', '.hovercard', function (e) {
$(this).addClass('dont-remove-card');
});
- $('body').on('mouseleave','.hovercard', function(e) {
+
+ $body.on('mouseleave', '.hovercard', function (e) {
$(this).removeClass('dont-remove-card');
- $(this).popover("hide");
+ $(this).popover('hide');
});
-
}); // End of $(document).ready
// removes all hover cards
-function removeAllhoverCards(event,priorTo) {
+function removeAllHovercards(event, priorTo) {
// don't remove hovercards until after 100ms, so user have time to move the cursor to it (which gives it the dont-remove-card class)
- setTimeout(function(){
- $.each($('.hovercard'),function(){
- var title = $(this).attr("data-orig-title");
+ setTimeout(function () {
+ $.each($('.hovercard'), function () {
+ let title = $(this).attr('data-orig-title');
// don't remove card if it was created after removeAllhoverCards() was called
- if($(this).data('card-created') < priorTo) {
+ if ($(this).data('card-created') < priorTo) {
// don't remove it if we're hovering it right now!
- if(!$(this).hasClass('dont-remove-card')) {
- $('[data-hover-card-active="' + $(this).data('card-created') + '"]').removeAttr('data-hover-card-active');
- $(this).popover("hide");
- }
- }
- });
- },100);
-}
+ if (!$(this).hasClass('dont-remove-card')) {
+ let $handle = $('[data-hover-card-active="' + $(this).data('card-created') + '"]');
+ $handle.removeAttr('data-hover-card-active');
-// Ajax request to get json contact data
-function getContactData(purl, url, actionOnSuccess) {
- var postdata = {
- mode : 'none',
- profileurl : purl,
- datatype : 'json',
- };
+ // Restoring the popover handle title
+ let title = $handle.attr('data-orig-title');
+ $handle.attr({'data-orig-title': '', title: title});
- // Normalize and clean the profile so we can use a standardized url
- // as key for the cache
- var nurl = cleanContactUrl(purl).normalizeLink();
-
- // If the contact is allready in the cache use the cached result instead
- // of doing a new ajax request
- if(nurl in getContactData.cache) {
- setTimeout(function() { actionOnSuccess(getContactData.cache[nurl]); } , 1);
- return;
- }
-
- $.ajax({
- url: url,
- data: postdata,
- dataType: "json",
- success: function(data, textStatus, request){
- // Check if the nurl (normalized profile url) is present and store it to the cache
- // The nurl will be the identifier in the object
- if(data.nurl.length > 0) {
- // Test if the contact is allready connected with the user (if url containing
- // the expression ("redir/") We will store different cache keys
- if((data.url.search("redir/")) >= 0 ) {
- var key = data.url;
- } else {
- var key = data.nurl;
+ $(this).popover('hide');
}
- getContactData.cache[key] = data;
}
- actionOnSuccess(data, url, request);
- },
- error: function(data) {
- actionOnSuccess(false, data, url);
- }
- });
+ });
+ }, 100);
}
-getContactData.cache = {};
-
-// Get hover-card template data and the contact-data and transform it with
-// the help of jSmart. At the end we have full html content of the hovercard
-function getHoverCardContent(purl, url, callback) {
- // fetch the raw content of the template
- getHoverCardTemplate(url, function(stpl) {
- var template = unescape(stpl);
-
- // get the contact data
- getContactData (purl, url, function(data) {
- if(typeof template != 'undefined') {
- // get the hover-card variables
- var variables = getHoverCardVariables(data);
- var tpl;
-
- // use friendicas template delimiters instead of
- // the original one
- jSmart.prototype.left_delimiter = '{{';
- jSmart.prototype.right_delimiter = '}}';
- // create a new jSmart instant with the raw content
- // of the template
- var tpl = new jSmart (template);
- // insert the variables content into the template content
- var HoverCardContent = tpl.fetch(variables);
-
- callback(HoverCardContent);
- }
- });
+function openHovercard(targetElement, contactUrl, timeNow) {
+ // store the title in a data attribute because Bootstrap
+ // popover destroys the title attribute.
+ let title = targetElement.attr('title');
+ targetElement.attr({'data-orig-title': title, title: ''});
+
+ // get an additional data atribute if the card is active
+ targetElement.attr('data-hover-card-active', timeNow);
+ // get the whole html content of the hover card and
+ // push it to the bootstrap popover
+ getHoverCardContent(contactUrl, function (data) {
+ if (data) {
+ targetElement.popover({
+ html: true,
+ placement: function () {
+ // Calculate the placement of the the hovercard (if top or bottom)
+ // The placement depence on the distance between window top and the element
+ // which triggers the hover-card
+ let get_position = $(targetElement).offset().top - $(window).scrollTop();
+ if (get_position < 270) {
+ return 'bottom';
+ }
+ return 'top';
+ },
+ trigger: 'manual',
+ template: '<div class="popover hovercard" data-card-created="' + timeNow + '"><div class="arrow"></div><div class="popover-content hovercard-content"></div></div>',
+ content: data,
+ container: 'body',
+ sanitizeFn: function (content) {
+ return DOMPurify.sanitize(content)
+ },
+ }).popover('show');
+ }
});
-
-// This is interisting. this pice of code ajax request are done asynchron.
-// To make it work getHOverCardTemplate() and getHOverCardData have to return it's
-// data (no succes handler for each of this). I leave it here, because it could be useful.
-// https://lostechies.com/joshuaflanagan/2011/10/20/coordinating-multiple-ajax-requests-with-jquery-when/
-// $.when(
-// getHoverCardTemplate(url),
-// getContactData (term, url )
-//
-// ).done(function(template, profile){
-// if(typeof template != 'undefined') {
-// var variables = getHoverCardVariables(profile);
-//
-// jSmart.prototype.left_delimiter = '{{';
-// jSmart.prototype.right_delimiter = '}}';
-// var tpl = new jSmart (template);
-// var html = tpl.fetch(variables);
-//
-// return html;
-// }
-// });
}
+getHoverCardContent.cache = {};
-// Ajax request to get the raw template content
-function getHoverCardTemplate (url, callback) {
- var postdata = {
- mode: 'none',
- datatype: 'tpl'
+function getHoverCardContent(contact_url, callback) {
+ let postdata = {
+ url: contact_url,
};
- // Look if we have the template already in the cace, so we don't have
- // request it again
- if('hovercard' in getHoverCardTemplate.cache) {
- setTimeout(function() { callback(getHoverCardTemplate.cache['hovercard']); } , 1);
+ // Normalize and clean the profile so we can use a standardized url
+ // as key for the cache
+ let nurl = cleanContactUrl(contact_url).normalizeLink();
+
+ // If the contact is already in the cache use the cached result instead
+ // of doing a new ajax request
+ if (nurl in getHoverCardContent.cache) {
+ callback(getHoverCardContent.cache[nurl]);
return;
}
$.ajax({
- url: url,
+ url: baseurl + '/contact/hovercard',
data: postdata,
- success: function(data, textStatus) {
- // write the data in the cache
- getHoverCardTemplate.cache['hovercard'] = data;
+ success: function (data, textStatus, request) {
+ getHoverCardContent.cache[nurl] = data;
callback(data);
- }
- }).fail(function () {callback([]); });
-}
-getHoverCardTemplate.cache = {};
-
-// The Variables used for the template
-function getHoverCardVariables(object) {
- var profile = {
- name: object.name,
- nick: object.nick,
- addr: object.addr,
- thumb: object.thumb,
- url: object.url,
- nurl: object.nurl,
- location: object.location,
- gender: object.gender,
- about: object.about,
- network: object.network,
- tags: object.tags,
- bd: object.bd,
- account_type: object.account_type,
- actions: object.actions
- };
-
- var variables = { profile: profile};
-
- return variables;
+ },
+ });
}
height: 0px;
}
+/* Contact-page */
+#connect-desc {
+ color: grey;
+}
+
+.search-input.form-control.form-search {
+ background-color: #ebebeb;
+ border-color:lightgrey;
+}
+
+.search-input.form-control.form-search:focus {
+ background-color: white;
+ border-color:grey;
+}
+
+/* Addon-Showmore*/
+.showmore-wrap {
+ background-color:lightgrey;
+ text-decoration: underline;
+ text-decoration-color: black;
+ text-decoration-style: wavy;
+}
{{/if}}
</div>
<div class="event-card-profile-name profile-entry-name">
- <a href="{{$author_link}}" class="userinfo">{{$author_name}}</a>
+ <a href="{{$author_link}}" class="userinfo hover-card">{{$author_name}}</a>
</div>
{{if $location.map}}
<div id="event-location-map-{{$id}}" class="event-location-map">{{$location.map nofilter}}</div>
<script type="text/javascript" src="view/theme/frio/frameworks/justifiedGallery/jquery.justifiedGallery.min.js"></script>
<script type="text/javascript" src="view/theme/frio/frameworks/bootstrap-colorpicker/js/bootstrap-colorpicker.min.js"></script>
<script type="text/javascript" src="view/theme/frio/frameworks/flexMenu/flexmenu.custom.js"></script>
-<script type="text/javascript" src="view/theme/frio/frameworks/jsmart/jsmart.custom.js"></script>
<script type="text/javascript" src="view/theme/frio/frameworks/jquery-scrollspy/jquery-scrollspy.js"></script>
<script type="text/javascript" src="view/theme/frio/frameworks/autosize/autosize.min.js"></script>
<script type="text/javascript" src="view/theme/frio/frameworks/sticky-kit/jquery.sticky-kit.min.js"></script>
<ul id="nav-notifications-template" class="media-list" style="display:none;" rel="template">
<li class="{4} notif-entry">
<div class="notif-entry-wrapper media">
- <div class="notif-photo-wrapper media-object pull-left"><a href="{6}" class="userinfo"><img data-src="{1}"></a></div>
+ <div class="notif-photo-wrapper media-object pull-left"><a href="{6}" class="userinfo click-card"><img data-src="{1}"></a></div>
<a href="{0}" class="notif-desc-wrapper media-body">
{2}
<div><time class="notif-when time" data-toggle="tooltip" title="{5}">{3}</time></div>
<div class="notif-item {{if !$item_seen}}unseen{{/if}} {{$item_label}} media">
<div class="notif-photo-wrapper media-object pull-left">
- <a class="userinfo" href="{{$item_url}}"><img src="{{$item_image}}" class="notif-image"></a>
+ <a class="userinfo click-card" href="{{$item_url}}"><img src="{{$item_image}}" class="notif-image"></a>
</div>
<div class="notif-desc-wrapper media-body">
<a href="{{$item_link}}">
{{* avatar picture *}}
<div class="contact-photo-wrapper mframe p-author h-card pull-left">
- <a class="userinfo u-url" id="wall-item-photo-menu-{{$id}}" href="{{$profile_url}}">
+ <a class="userinfo click-card u-url" id="wall-item-photo-menu-{{$id}}" href="{{$profile_url}}">
<div class="contact-photo-image-wrapper">
<img src="{{$thumb}}" class="contact-photo-xs media-object p-name u-photo" id="wall-item-photo-{{$id}}" alt="{{$name}}" />
</div>
{{* the header with the comment author name *}}
<div role="heading " class="contact-info-comment">
<h5 class="media-heading">
- <a href="{{$profile_url}}" title="View {{$name}}'s profile" class="wall-item-name-link userinfo"><span class="btn-link">{{$name}}</span></a>
+ <a href="{{$profile_url}}" title="View {{$name}}'s profile" class="wall-item-name-link userinfo hover-card"><span class="btn-link">{{$name}}</span></a>
</h5>
</div>
{{if $permonly}}
{{include file="field_textarea.tpl" field=$permonlybox}}
+ <input type="input" id="registertarpit" style="display: none;" placeholder="Don't enter anything here"/>
{{/if}}
{{$publish nofilter}}
{{* The avatar picture and the photo-menu *}}
<div class="dropdown pull-left"><!-- Dropdown -->
<div class="hidden-sm hidden-xs contact-photo-wrapper mframe{{if $item.owner_url}} wwfrom{{/if}}">
- <a href="{{$item.profile_url}}" class="userinfo u-url" id="wall-item-photo-menu-{{$item.id}}">
+ <a href="{{$item.profile_url}}" class="userinfo click-card u-url" id="wall-item-photo-menu-{{$item.id}}">
<div class="contact-photo-image-wrapper">
<img src="{{$item.thumb}}" class="contact-photo media-object {{$item.sparkle}}" id="wall-item-photo-{{$item.id}}" alt="{{$item.name}}" />
</div>
</a>
</div>
<div class="hidden-lg hidden-md contact-photo-wrapper mframe{{if $item.owner_url}} wwfrom{{/if}}">
- <a href="{{$item.profile_url}}" class="userinfo u-url" id="wall-item-photo-menu-xs-{{$item.id}}">
+ <a href="{{$item.profile_url}}" class="userinfo click-card u-url" id="wall-item-photo-menu-xs-{{$item.id}}">
<div class="contact-photo-image-wrapper">
<img src="{{$item.thumb}}" class="contact-photo-xs media-object {{$item.sparkle}}" id="wall-item-photo-xs-{{$item.id}}" alt="{{$item.name}}" />
</div>
{{* contact info header*}}
- <div role="heading " class="contact-info hidden-sm hidden-xs media-body"><!-- <= For computer -->
- <h4 class="media-heading"><a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo"><span class="wall-item-name {{$item.sparkle}}">{{$item.name}}</span></a>
- {{if $item.owner_url}}{{$item.via}} <a href="{{$item.owner_url}}" target="redir" title="{{$item.olinktitle}}" class="wall-item-name-link userinfo"><span class="wall-item-name {{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}">{{$item.owner_name}}</span></a>{{/if}}
- {{if $item.lock}}<span class="navicon lock fakelink" onClick="lockview(event, {{$item.id}});" title="{{$item.lock}}"> <small><i class="fa fa-lock" aria-hidden="true"></i></small></span>{{/if}}
+ <div role="heading" class="contact-info hidden-sm hidden-xs media-body"><!-- <= For computer -->
+ <h4 class="media-heading">
+ <a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo hover-card">
+ <span class="wall-item-name {{$item.sparkle}}">{{$item.name}}</span>
+ </a>
+ {{if $item.owner_url}}
+ {{$item.via}}
+ <a href="{{$item.owner_url}}" target="redir" title="{{$item.olinktitle}}" class="wall-item-name-link userinfo hover-card">
+ <span class="wall-item-name {{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}">{{$item.owner_name}}</span>
+ </a>
+ {{/if}}
+ {{if $item.lock}}
+ <span class="navicon lock fakelink" onClick="lockview(event, {{$item.id}});" title="{{$item.lock}}">
+ <small><i class="fa fa-lock" aria-hidden="true"></i></small>
+ </span>
+ {{/if}}
<div class="additional-info text-muted">
<div id="wall-item-ago-{{$item.id}}" class="wall-item-ago">
{{* contact info header for smartphones *}}
<div role="heading " class="contact-info-xs hidden-lg hidden-md">
<h5 class="media-heading">
- <a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo"><span>{{$item.name}}</span></a>
+ <a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo hover-card"><span>{{$item.name}}</span></a>
<p class="text-muted"><small>
<span class="wall-item-ago">{{$item.ago}}</span> {{if $item.location}} — ({{$item.location nofilter}}){{/if}}</small>
</p>
</div>
</div>
+ {{* Import contacts CSV *}}
+ <div class="panel">
+ <div class="section-subtitle-wrapper" role="tab" id="importcontact-settings">
+ <h4>
+ <a class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#settings" href="#importcontact-settings-collapse" aria-expanded="false" aria-controls="importcontact-settings-collapse">
+ {{$importcontact}}
+ </a>
+ </h4>
+ </div>
+ <div id="importcontact-settings-collapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="importcontact-settings">
+ <div class="section-content-tools-wrapper">
+
+ <div id="importcontact-relocate-desc">{{$importcontact_text}}</div>
+ <input type="hidden" name="MAX_FILE_SIZE" value="{{$importcontact_maxsize}}" />
+ <input type="file" name="importcontact-filename" />
+
+ <br/>
+ <div class="form-group pull-right settings-submit-wrapper" >
+ <button type="submit" name="importcontact-submit" class="btn btn-primary" value="{{$importcontact_button}}">{{$importcontact_button}}</button>
+ </div>
+ <div class="clear"></div>
+ </div>
+ </div>
+ </div>
+
{{* The relocate setting section *}}
<div class="panel">
<div class="section-subtitle-wrapper" role="tab" id="relocate-settings">
--- /dev/null
+
+<div class="generic-page-wrapper">
+ {{* include the title template for the settings title *}}
+ {{include file="section_title.tpl" title=$title}}
+
+ {{foreach $options as $o}}
+ <dl>
+ <dt><a href="{{$o.0}}">{{$o.1}}</a></dt>
+ <dd>{{$o.2}}</dd>
+ </dl>
+ {{/foreach}}
+</div>
</li>
{{/if}}
+ {{if $item.pin}}
+ <li role="menuitem">
+ <button type="button" id="pin-{{$item.id}}" onclick="dopin({{$item.id}});" class="btn-link {{$item.pin.classdo}}" title="{{$item.pin.do}}"><i class="fa fa-circle-o" aria-hidden="true"></i> {{$item.pin.do}}</button>
+ <button type="button" id="unpin-{{$item.id}}" onclick="dopin({{$item.id}});" class="btn-link {{$item.pin.classundo}}" title="{{$item.pin.undo}}"><i class="fa fa-dot-circle-o" aria-hidden="true"></i> {{$item.pin.undo}}</button>
+ </li>
+ {{/if}}
+
{{if $item.star}}
<li role="menuitem">
<button type="button" id="star-{{$item.id}}" onclick="dostar({{$item.id}});" class="btn-link {{$item.star.classdo}}" title="{{$item.star.do}}"><i class="fa fa-star-o" aria-hidden="true"></i> {{$item.star.do}}</button>
<div class="dropdown pull-left"><!-- Dropdown -->
{{if $item.thread_level==1}}
<div class="hidden-sm hidden-xs contact-photo-wrapper mframe{{if $item.owner_url}} wwfrom{{/if}} p-author h-card">
- <a class="userinfo u-url" id="wall-item-photo-menu-{{$item.id}}" href="{{$item.profile_url}}">
+ <a class="userinfo click-card u-url" id="wall-item-photo-menu-{{$item.id}}" href="{{$item.profile_url}}">
<div class="contact-photo-image-wrapper">
<img src="{{$item.thumb}}" class="contact-photo media-object {{$item.sparkle}} p-name u-photo" id="wall-item-photo-{{$item.id}}" alt="{{$item.name}}" />
</div>
</a>
</div>
<div class="hidden-lg hidden-md contact-photo-wrapper mframe{{if $item.owner_url}} wwfrom{{/if}}">
- <a class="userinfo u-url" id="wall-item-photo-menu-xs-{{$item.id}}" href="{{$item.profile_url}}">
+ <a class="userinfo click-card u-url" id="wall-item-photo-menu-xs-{{$item.id}}" href="{{$item.profile_url}}">
<div class="contact-photo-image-wrapper">
<img src="{{$item.thumb}}" class="contact-photo-xs media-object {{$item.sparkle}}" id="wall-item-photo-xs-{{$item.id}}" alt="{{$item.name}}" />
</div>
{{* The avatar picture for comments *}}
{{if $item.thread_level!=1}}
<div class="contact-photo-wrapper mframe{{if $item.owner_url}} wwfrom{{/if}} p-author h-card">
- <a class="userinfo u-url" id="wall-item-photo-menu-{{$item.id}}" href="{{$item.profile_url}}">
+ <a class="userinfo click-card u-url" id="wall-item-photo-menu-{{$item.id}}" href="{{$item.profile_url}}">
<div class="contact-photo-image-wrapper">
<img src="{{$item.thumb}}" class="contact-photo-xs media-object {{$item.sparkle}} p-name u-photo" id="wall-item-photo-comment-{{$item.id}}" alt="{{$item.name}}" />
</div>
{{* contact info header*}}
{{if $item.thread_level==1}}
<div role="heading " aria-level="{{$item.thread_level}}" class="contact-info hidden-sm hidden-xs media-body"><!-- <= For computer -->
- <h4 class="media-heading"><a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo"><span class="wall-item-name {{$item.sparkle}}">{{$item.name}}</span></a>
- {{if $item.owner_url}}{{$item.via}} <a href="{{$item.owner_url}}" target="redir" title="{{$item.olinktitle}}" class="wall-item-name-link userinfo"><span class="wall-item-name {{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}">{{$item.owner_name}}</span></a>{{/if}}
- {{if $item.lock}}<span class="navicon lock fakelink" onClick="lockview(event,{{$item.id}});" title="{{$item.lock}}" data-toggle="tooltip"> <small><i class="fa fa-lock" aria-hidden="true"></i></small></span>{{/if}}
+ <h4 class="media-heading">
+ <a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo hover-card">
+ <span class="wall-item-name {{$item.sparkle}}">{{$item.name}}</span>
+ </a>
+ {{if $item.owner_url}}
+ {{$item.via}}
+ <a href="{{$item.owner_url}}" target="redir" title="{{$item.olinktitle}}" class="wall-item-name-link userinfo hover-card">
+ <span class="wall-item-name {{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}">{{$item.owner_name}}</span>
+ </a>
+ {{/if}}
+ {{if $item.lock}}
+ <span class="navicon lock fakelink" onClick="lockview(event,{{$item.id}});" title="{{$item.lock}}" data-toggle="tooltip">
+ <small><i class="fa fa-lock" aria-hidden="true"></i></small>
+ </span>
+ {{/if}}
</h4>
<div class="additional-info text-muted">
{{if $item.owner_self}}
{{include file="sub/delivery_count.tpl" delivery=$item.delivery}}
{{/if}}
+ <span class="pinned">{{$item.pinned}}</span>
</small>
</div>
{{* contact info header for smartphones *}}
<div role="heading " aria-level="{{$item.thread_level}}" class="contact-info-xs hidden-lg hidden-md"><!-- <= For smartphone (responsive) -->
<h5 class="media-heading">
- <a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo"><span>{{$item.name}}</span></a>
+ <a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo hover-card"><span>{{$item.name}}</span></a>
<p class="text-muted">
<small>
<a class="time" href="{{$item.plink.orig}}"><span class="wall-item-ago">{{$item.ago}}</span></a>
<div class="media-body">{{*this is the media body for comments - this div must be closed at the end of the file *}}
<div role="heading " aria-level="{{$item.thread_level}}" class="contact-info-comment">
<h5 class="media-heading">
- <a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo"><span class="fakelink">{{$item.name}}</span></a>
+ <a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-name-link userinfo hover-card"><span class="fakelink">{{$item.name}}</span></a>
<span class="text-muted">
<small>
<a class="time" href="{{$item.plink.orig}}" title="{{$item.localtime}}" data-toggle="tooltip">{{$item.ago}}</a>
{{/foreach}}
{{foreach $item.categories as $cat}}
- <span class="category label btn-success sm p-category">{{$cat.name}}{{if $cat.removeurl}} (<a href="{{$cat.removeurl}}" title="{{$remove}}">x</a>) {{/if}} </span>
+ <span class="category label btn-success sm p-category"><a href="{{$cat.url}}">{{$cat.name}}</a>{{if $cat.removeurl}} (<a href="{{$cat.removeurl}}" title="{{$remove}}">x</a>) {{/if}} </span>
{{/foreach}}
</div>
{{if $item.edited}}<div class="itemedited text-muted">{{$item.edited['label']}} (<span title="{{$item.edited['date']}}">{{$item.edited['relative']}}</span>)</div>{{/if}}
<h3>{{$connect}}</h3>
<form action="follow" method="get">
- <label for="side-follow-url" id="connect-desc">{{$desc nofilter}}</label>
{{* The input field - For visual consistence we are using a search input field*}}
<div class="form-group form-group-search">
<input id="side-follow-url" class="search-input form-control form-search" type="text" name="url" value="{{$value}}" placeholder="{{$hint}}" data-toggle="tooltip" title="{{$hint}}" />
<span class="folder p-category">{{$cat.name}}</a>{{if $cat.removeurl}} (<a href="{{$cat.removeurl}}" title="{{$remove}}">x</a>) {{/if}} </span>
{{/foreach}}
{{foreach $item.categories as $cat}}
- <span class="category p-category">{{$cat.name}}</a>{{if $cat.removeurl}} (<a href="{{$cat.removeurl}}" title="{{$remove}}">x</a>) {{/if}} </span>
+ <span class="category p-category"><a href="{{$cat.url}}">{{$cat.name}}</a>{{if $cat.removeurl}} (<a href="{{$cat.removeurl}}" title="{{$remove}}">x</a>) {{/if}} </span>
{{/foreach}}
{{/if}}
</div>
class="wall-item-name-link"><span
class="wall-item-name{{$item.sparkle}}">{{$item.name}}</span></a>
<span class="wall-item-ago" title="{{$item.localtime}}"><time class="dt-published" datetime="{{$item.localtime}}">{{$item.ago}}</time></span>
+ <span class="pinned">{{$item.pinned}}</span>
{{if $item.owner_url}}<br/>{{$item.to}} <a href="{{$item.owner_url}}" target="redir" title="{{$item.olinktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}">{{$item.owner_name}}</span></a> {{$item.vwall}}
{{/if}}
</div>
<div class="wall-item-actions-social">
+ {{if $item.pin}}
+ <a href="#" id="pin-{{$item.id}}" onclick="dopin({{$item.id}}); return false;" class="{{$item.pin.classdo}}" title="{{$item.pin.do}}">{{$item.pin.do}}</a>
+ <a href="#" id="unpin-{{$item.id}}" onclick="dopin({{$item.id}}); return false;" class="{{$item.pin.classundo}}" title="{{$item.pin.undo}}">{{$item.pin.undo}}</a>
+ {{/if}}
{{if $item.star}}
<a href="#" id="star-{{$item.id}}" onclick="dostar({{$item.id}}); return false;" class="{{$item.star.classdo}}" title="{{$item.star.do}}">{{$item.star.do}}</a>
<a href="#" id="unstar-{{$item.id}}" onclick="dostar({{$item.id}}); return false;" class="{{$item.star.classundo}}" title="{{$item.star.undo}}">{{$item.star.undo}}</a>
margin-right: 20px;
}
+.pin-item,
.star-item,
.tag-item {
float: left;
height: 20px;
background-image: url("images/icons.png");
}
+.pinned {
+ background-image: url("images/star.png");
+ repeat: no-repeat;
+}
+.unpinned {
+ background-image: url("images/premium.png");
+ repeat: no-repeat;
+}
+
.starred {
background-image: url("images/star.png");
repeat: no-repeat;
<span class="wall-item-name{{$item.sparkle}}" id="wall-item-name-{{$item.id}}" >{{$item.name}}</span>
</a>
<div class="wall-item-ago">•</div>
- <div class="wall-item-ago" id="wall-item-ago-{{$item.id}}" title="{{$item.localtime}}"><time class="dt-published" datetime="{{$item.localtime}}">{{$item.ago}}</time></div>
+ <div class="wall-item-ago" id="wall-item-ago-{{$item.id}}" title="{{$item.localtime}}"><time class="dt-published" datetime="{{$item.localtime}}">{{$item.ago}}</time><span class="pinned">{{$item.pinned}}</span></div>
</div>
<div>
</div>
{{if $item.has_cats}}
- <div class="categorytags"><span>{{$item.txt_cats}} {{foreach $item.categories as $cat}}<span class="p-category">{{$cat.name}}</span>
+ <div class="categorytags"><span>{{$item.txt_cats}} {{foreach $item.categories as $cat}}<span class="p-category"><a href="{{$cat.url}}">{{$cat.name}}</a></span>
<a href="{{$cat.removeurl}}" title="{{$remove}}">[{{$remove}}]</a>
{{if $cat.last}}{{else}}, {{/if}}{{/foreach}}
</div>
</div>
{{/if}}
+ {{if $item.pin}}
+ <a href="#" id="pinned-{{$item.id}}" onclick="dopin({{$item.id}}); return false;" class="pin-item icon {{$item.ispinned}}" title="{{$item.pin.toggle}}"></a>
+ {{/if}}
{{if $item.star}}
<a href="#" id="starred-{{$item.id}}" onclick="dostar({{$item.id}}); return false;" class="star-item icon {{$item.isstarred}}" title="{{$item.star.toggle}}"></a>
{{/if}}
{{if $item.owner_self}}
{{include file="sub/delivery_count.tpl" delivery=$item.delivery}}
{{/if}}
+ <span class="pinned">{{$item.pinned}}</span>
</span>
{{if $item.lock}}<span class="icon s10 lock fakelink" onclick="lockview(event,{{$item.id}});" title="{{$item.lock}}">{{$item.lock}}</span>{{/if}}
<span class="wall-item-network" title="{{$item.app}}">
<span class="folder p-category">{{$cat.name}}{{if $cat.removeurl}} (<a href="{{$cat.removeurl}}" title="{{$remove}}">x</a>) {{/if}} </span>
{{/foreach}}
{{foreach $item.categories as $cat}}
- <span class="category p-category">{{$cat.name}}{{if $cat.removeurl}} (<a href="{{$cat.removeurl}}" title="{{$remove}}">x</a>) {{/if}} </span>
+ <span class="category p-category"><a href="{{$cat.url}}">{{$cat.name}}</a>{{if $cat.removeurl}} (<a href="{{$cat.removeurl}}" title="{{$remove}}">x</a>) {{/if}} </span>
{{/foreach}}
</div>
</div>
{{/if}}
{{/if}}
+ {{if $item.pin}}
+ <a role="button" id="pin-{{$item.id}}" onclick="dopin({{$item.id}}); return false;" class="{{$item.pin.classdo}}" title="{{$item.pin.do}}"><i class="icon-circle icon-large"><span class="sr-only">{{$item.pin.do}}</span></i></a>
+ <a role="button" id="unpin-{{$item.id}}" onclick="dopin({{$item.id}}); return false;" class="{{$item.pin.classundo}}" title="{{$item.pin.undo}}"><i class="icon-remove-circle icon-large"><span class="sr-only">{{$item.pin.undo}}</span></i></a>
+ {{/if}}
{{if $item.star}}
<a role="button" id="star-{{$item.id}}" onclick="dostar({{$item.id}}); return false;" class="{{$item.star.classdo}}" title="{{$item.star.do}}"><i class="icon-star icon-large"><span class="sr-only">{{$item.star.do}}</span></i></a>
<a role="button" id="unstar-{{$item.id}}" onclick="dostar({{$item.id}}); return false;" class="{{$item.star.classundo}}" title="{{$item.star.undo}}"><i class="icon-star-empty icon-large"><span class="sr-only">{{$item.star.undo}}</span></i></a>