aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManuel Jiménez Friaza <mjfriaza@openmailbox.org>2018-12-05 12:32:33 +0100
committerManuel Jiménez Friaza <mjfriaza@openmailbox.org>2018-12-05 12:32:33 +0100
commit4cd5529027efa19288ddce125f0d41ccb5519578 (patch)
tree69b5bb1b43d807908d38d7febec21732fd334a49
parent5ac08ec3aa8ede14141390670a8097a60769e11e (diff)
parentd12744011affe7f6b79201442ad9fce6e083bdbb (diff)
downloadvolse-hubzilla-4cd5529027efa19288ddce125f0d41ccb5519578.tar.gz
volse-hubzilla-4cd5529027efa19288ddce125f0d41ccb5519578.tar.bz2
volse-hubzilla-4cd5529027efa19288ddce125f0d41ccb5519578.zip
Merge remote-tracking branch 'upstream/dev' into dev
-rw-r--r--CHANGELOG18
-rw-r--r--Zotlabs/Daemon/Cron.php23
-rw-r--r--Zotlabs/Lib/Activity.php391
-rw-r--r--Zotlabs/Lib/Enotify.php1
-rw-r--r--Zotlabs/Lib/Libzot.php8
-rw-r--r--Zotlabs/Module/Import.php9
-rw-r--r--Zotlabs/Module/Item.php6
-rw-r--r--Zotlabs/Module/Like.php3
-rw-r--r--Zotlabs/Module/Pconfig.php5
-rw-r--r--Zotlabs/Module/Photo.php87
-rw-r--r--Zotlabs/Module/Ping.php8
-rw-r--r--Zotlabs/Module/Wfinger.php3
-rw-r--r--Zotlabs/Update/_1228.php4
-rw-r--r--Zotlabs/Update/_1229.php32
-rw-r--r--Zotlabs/Widget/Notifications.php8
-rwxr-xr-xboot.php3
-rw-r--r--composer.json3
-rw-r--r--composer.lock171
-rw-r--r--include/channel.php15
-rwxr-xr-xinclude/items.php10
-rwxr-xr-xinclude/oembed.php6
-rw-r--r--include/photo/photo_driver.php31
-rw-r--r--include/photo/photo_imagick.php10
-rw-r--r--include/text.php45
-rw-r--r--install/schema_mysql.sql2
-rw-r--r--install/schema_postgres.sql2
-rw-r--r--library/imagesloaded/imagesloaded.pkgd.min.js7
-rw-r--r--vendor/blueimp/jquery-file-upload/README.md2
-rw-r--r--vendor/blueimp/jquery-file-upload/SECURITY.md2
-rw-r--r--vendor/blueimp/jquery-file-upload/angularjs.html8
-rw-r--r--vendor/blueimp/jquery-file-upload/basic-plus.html8
-rw-r--r--vendor/blueimp/jquery-file-upload/basic.html6
-rw-r--r--[-rwxr-xr-x]vendor/blueimp/jquery-file-upload/bower-version-update.js0
-rw-r--r--vendor/blueimp/jquery-file-upload/bower.json2
-rw-r--r--vendor/blueimp/jquery-file-upload/cors/postmessage.html2
-rw-r--r--vendor/blueimp/jquery-file-upload/index.html6
-rw-r--r--vendor/blueimp/jquery-file-upload/jquery-ui.html6
-rw-r--r--vendor/blueimp/jquery-file-upload/package.json2
-rw-r--r--[-rwxr-xr-x]vendor/blueimp/jquery-file-upload/server/php/UploadHandler.php34
-rw-r--r--vendor/blueimp/jquery-file-upload/server/php/index.php2
-rw-r--r--vendor/blueimp/jquery-file-upload/test/index.html6
-rw-r--r--vendor/composer/ClassLoader.php2
-rw-r--r--vendor/composer/LICENSE69
-rw-r--r--vendor/composer/autoload_classmap.php9
-rw-r--r--vendor/composer/autoload_static.php8
-rw-r--r--vendor/composer/installed.json69
-rw-r--r--vendor/desandro/imagesloaded/.gitignore5
-rw-r--r--vendor/desandro/imagesloaded/.jshintrc12
-rw-r--r--vendor/desandro/imagesloaded/README.md362
-rw-r--r--vendor/desandro/imagesloaded/bower.json37
-rw-r--r--vendor/desandro/imagesloaded/composer.json15
-rw-r--r--vendor/desandro/imagesloaded/contributing.md20
-rw-r--r--vendor/desandro/imagesloaded/gulpfile.js128
-rw-r--r--vendor/desandro/imagesloaded/imagesloaded.js377
-rw-r--r--vendor/desandro/imagesloaded/imagesloaded.pkgd.js (renamed from library/imagesloaded/imagesloaded.pkgd.js)72
-rw-r--r--vendor/desandro/imagesloaded/imagesloaded.pkgd.min.js7
-rw-r--r--vendor/desandro/imagesloaded/package.json48
-rw-r--r--vendor/desandro/imagesloaded/sandbox/background/css/background.css29
-rw-r--r--vendor/desandro/imagesloaded/sandbox/background/index.html51
-rw-r--r--vendor/desandro/imagesloaded/sandbox/progress/index.html89
-rw-r--r--vendor/desandro/imagesloaded/sandbox/progress/progress.js111
-rw-r--r--vendor/desandro/imagesloaded/test/css/tests.css41
-rw-r--r--vendor/desandro/imagesloaded/test/img/blue-shell.jpgbin0 -> 24555 bytes
-rw-r--r--vendor/desandro/imagesloaded/test/img/bowser-jr.jpgbin0 -> 36987 bytes
-rw-r--r--vendor/desandro/imagesloaded/test/img/thunder-cloud.jpgbin0 -> 24588 bytes
-rw-r--r--vendor/desandro/imagesloaded/test/index.html104
-rw-r--r--vendor/desandro/imagesloaded/test/unit/append.js30
-rw-r--r--vendor/desandro/imagesloaded/test/unit/background.js70
-rw-r--r--vendor/desandro/imagesloaded/test/unit/basics.js28
-rw-r--r--vendor/desandro/imagesloaded/test/unit/data-uri.js10
-rw-r--r--vendor/desandro/imagesloaded/test/unit/jquery-fail.js29
-rw-r--r--vendor/desandro/imagesloaded/test/unit/jquery-success.js28
-rw-r--r--vendor/desandro/imagesloaded/test/unit/local-files.js31
-rw-r--r--vendor/desandro/imagesloaded/test/unit/no-images.js11
-rw-r--r--vendor/desandro/imagesloaded/test/unit/non-element.js24
-rw-r--r--vendor/desandro/imagesloaded/test/unit/selector-string.js12
-rw-r--r--vendor/desandro/imagesloaded/test/unit/single-element.js11
-rw-r--r--vendor/psr/log/README.md7
-rw-r--r--view/css/default.css37
-rw-r--r--view/css/mod_connedit.css1
-rw-r--r--view/es-es/hstrings.php4
-rw-r--r--view/js/main.js5
-rw-r--r--view/php/default.php14
-rw-r--r--view/php/theme_init.php2
-rw-r--r--view/ru/hmessages.po817
-rw-r--r--view/ru/hstrings.php46
-rw-r--r--view/theme/redbasic/js/redbasic.js6
-rw-r--r--view/tpl/notifications_widget.tpl13
88 files changed, 3088 insertions, 810 deletions
diff --git a/CHANGELOG b/CHANGELOG
index b11016eba..444c7b2e4 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,21 @@
+Hubzilla 3.8.6 (2018-12-03)
+ - Prevent incompatible export files (osada/zap) from being imported
+ - Catch exception if readImageBlob() receives bogus data
+ - Streamline PDF previews
+ - Allow notification filtering by name or address
+ - Fix too restrictive attached photo permissions
+ - Update ES translation
+ - Use flex for the default template
+ - Do not store serialized pconfig value received via to Module/Pconfig.php
+ - Update jquery-file-upload lib and move to composer
+ - Update imagesloaded lib and move to composer
+ - Fix activitypub tag notifications
+ - Fix call to undefined function in PConfig
+ - Fix typo which prevented propagation of comments to zot6 (dev)
+ - Activitypub: add support for pterotype (wordpress plugin)
+ - Openstreetmap: check validity of lat+lon before rendering a map
+
+
Hubzilla 3.8.5 (2018-11-19)
- Fix pconfig for new installs
- Fix delayed publication of posts in combination with channel clones
diff --git a/Zotlabs/Daemon/Cron.php b/Zotlabs/Daemon/Cron.php
index 25e49b817..8b6b42c8a 100644
--- a/Zotlabs/Daemon/Cron.php
+++ b/Zotlabs/Daemon/Cron.php
@@ -94,6 +94,29 @@ class Cron {
@time_sleep_until(microtime(true) + (float) $interval);
}
}
+
+ // Clean expired photos from cache
+
+ $age = get_config('system','active_expire_days', '30');
+ $r = q("SELECT DISTINCT xchan, content FROM photo WHERE photo_usage = %d AND expires < %s - INTERVAL %s",
+ intval(PHOTO_CACHE),
+ db_utcnow(),
+ db_quoteinterval($age . ' DAY')
+ );
+ if($r) {
+ foreach($r as $rr) {
+ $file = dbunescbin($rr['content']);
+ if(is_file($file)) {
+ @unlink($file);
+ logger('info: deleted cached photo file ' . $file, LOGGER_DEBUG);
+ }
+ }
+ }
+ q("DELETE FROM photo WHERE photo_usage = %d AND expires < %s - INTERVAL %s",
+ intval(PHOTO_CACHE),
+ db_utcnow(),
+ db_quoteinterval($age . ' DAY')
+ );
// publish any applicable items that were set to be published in the future
// (time travel posts). Restrict to items that have come of age in the last
diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php
index 6ddbbb9db..8cef41c42 100644
--- a/Zotlabs/Lib/Activity.php
+++ b/Zotlabs/Lib/Activity.php
@@ -11,9 +11,15 @@ class Activity {
static function encode_object($x) {
+
if(($x) && (! is_array($x)) && (substr(trim($x),0,1)) === '{' ) {
$x = json_decode($x,true);
}
+
+ if(is_array($x) && array_key_exists('asld',$x)) {
+ $x = $x['asld'];
+ }
+
if($x['type'] === ACTIVITY_OBJ_PERSON) {
return self::fetch_person($x);
}
@@ -1149,7 +1155,7 @@ class Activity {
}
if($act->obj['type'] === 'Note' && $s['attach']) {
- $s['body'] .= self::bb_attach($s['attach']);
+ $s['body'] .= self::bb_attach($s['attach'],$s['body']);
}
// we will need a hook here to extract magnet links e.g. peertube
@@ -1233,19 +1239,20 @@ class Activity {
static function decode_note($act) {
- $s = [];
-
-
+ $response_activity = false;
- $content = self::get_content($act->obj);
+ $s = [];
+ if(is_array($act->obj)) {
+ $content = self::get_content($act->obj);
+ }
+
$s['owner_xchan'] = $act->actor['id'];
$s['author_xchan'] = $act->actor['id'];
- $s['mid'] = $act->id;
+ $s['mid'] = $act->obj['id'];
$s['parent_mid'] = $act->parent_id;
-
if($act->data['published']) {
$s['created'] = datetime_convert('UTC','UTC',$act->data['published']);
}
@@ -1259,43 +1266,60 @@ class Activity {
$s['edited'] = datetime_convert('UTC','UTC',$act->obj['updated']);
}
- if(! $s['created'])
- $s['created'] = datetime_convert();
- if(! $s['edited'])
- $s['edited'] = $s['created'];
+ if(in_array($act->type, [ 'Like', 'Dislike', 'Flag', 'Block', 'Announce', 'Accept', 'Reject', 'TentativeAccept' ])) {
- if(in_array($act->type,['Announce'])) {
- $root_content = self::get_content($act->raw);
+ $response_activity = true;
- $s['title'] = self::bb_content($root_content,'name');
- $s['summary'] = self::bb_content($root_content,'summary');
- $s['body'] = (self::bb_content($root_content,'bbcode') ? : self::bb_content($root_content,'content'));
+ $s['mid'] = $act->id;
+ $s['parent_mid'] = $act->obj['id'];
- if(strpos($s['body'],'[share') === false) {
+ // over-ride the object timestamp with the activity
- // @fixme - error check and set defaults
+ if($act->data['published']) {
+ $s['created'] = datetime_convert('UTC','UTC',$act->data['published']);
+ }
+
+ if($act->data['updated']) {
+ $s['edited'] = datetime_convert('UTC','UTC',$act->data['updated']);
+ }
- $name = urlencode($act->obj['actor']['name']);
- $profile = $act->obj['actor']['id'];
- $photo = $act->obj['icon']['url'];
+ $obj_actor = ((isset($act->obj['actor'])) ? $act->obj['actor'] : $act->get_actor('attributedTo', $act->obj));
+ // ensure we store the original actor
+ self::actor_store($obj_actor['id'],$obj_actor);
- $s['body'] .= "\r\n[share author='" . $name .
- "' profile='" . $profile .
- "' avatar='" . $photo .
- "' link='" . $act->obj['id'] .
- "' auth='" . ((is_matrix_url($act->obj['id'])) ? 'true' : 'false' ) .
- "' posted='" . $act->obj['published'] .
- "' message_id='" . $act->obj['id'] .
- "']";
+ $mention = self::get_actor_bbmention($obj_actor['id']);
+
+ if($act->type === 'Like') {
+ $content['content'] = sprintf( t('Likes %1$s\'s %2$s'),$mention,$act->obj['type']) . "\n\n" . $content['content'];
+ }
+ if($act->type === 'Dislike') {
+ $content['content'] = sprintf( t('Doesn\'t like %1$s\'s %2$s'),$mention,$act->obj['type']) . "\n\n" . $content['content'];
+ }
+ if($act->type === 'Accept' && $act->obj['type'] === 'Event' ) {
+ $content['content'] = sprintf( t('Will attend %1$s\'s %2$s'),$mention,$act->obj['type']) . "\n\n" . $content['content'];
+ }
+ if($act->type === 'Reject' && $act->obj['type'] === 'Event' ) {
+ $content['content'] = sprintf( t('Will not attend %1$s\'s %2$s'),$mention,$act->obj['type']) . "\n\n" . $content['content'];
+ }
+ if($act->type === 'TentativeAccept' && $act->obj['type'] === 'Event' ) {
+ $content['content'] = sprintf( t('May attend %1$s\'s %2$s'),$mention,$act->obj['type']) . "\n\n" . $content['content'];
+ }
+ if($act->type === 'Announce') {
+ $content['content'] = sprintf( t('&#x1f501; Repeated %1$s\'s %2$s'), $mention, $act->obj['type']);
}
- }
- else {
- $s['title'] = self::bb_content($content,'name');
- $s['summary'] = self::bb_content($content,'summary');
- $s['body'] = (self::bb_content($content,'bbcode') ? : self::bb_content($content,'content'));
}
+ if(! $s['created'])
+ $s['created'] = datetime_convert();
+
+ if(! $s['edited'])
+ $s['edited'] = $s['created'];
+
+ $s['title'] = self::bb_content($content,'name');
+ $s['summary'] = self::bb_content($content,'summary');
+ $s['body'] = ((self::bb_content($content,'bbcode') && (! $response_activity)) ? self::bb_content($content,'bbcode') : self::bb_content($content,'content'));
+
$s['verb'] = self::activity_mapper($act->type);
if($act->type === 'Tombstone') {
@@ -1306,58 +1330,229 @@ class Activity {
$s['obj'] = $act->obj;
$instrument = $act->get_property_obj('instrument');
- if(! $instrument)
+ if((! $instrument) && (! $response_activity)) {
$instrument = $act->get_property_obj('instrument',$act->obj);
+ }
if($instrument && array_key_exists('type',$instrument)
&& $instrument['type'] === 'Service' && array_key_exists('name',$instrument)) {
$s['app'] = escape_tags($instrument['name']);
}
- $a = self::decode_taxonomy($act->obj);
- if($a) {
- $s['term'] = $a;
+
+ if(! $response_activity) {
+ $a = self::decode_taxonomy($act->obj);
+ if($a) {
+ $s['term'] = $a;
+ foreach($a as $b) {
+ if($b['ttype'] === TERM_EMOJI) {
+ $s['title'] = str_replace($b['term'],'[img=16x16]' . $b['url'] . '[/img]',$s['title']);
+ $s['summary'] = str_replace($b['term'],'[img=16x16]' . $b['url'] . '[/img]',$s['summary']);
+ $s['body'] = str_replace($b['term'],'[img=16x16]' . $b['url'] . '[/img]',$s['body']);
+ }
+ }
+ }
+
+ $a = self::decode_attachment($act->obj);
+ if($a) {
+ $s['attach'] = $a;
+ }
}
- $a = self::decode_attachment($act->obj);
- if($a) {
- $s['attach'] = $a;
+ if($act->obj['type'] === 'Note' && $s['attach']) {
+ $s['body'] .= self::bb_attach($s['attach'],$s['body']);
}
+
// we will need a hook here to extract magnet links e.g. peertube
// right now just link to the largest mp4 we find that will fit in our
// standard content region
- if($act->obj['type'] === 'Video') {
+ if(! $response_activity) {
+ if($act->obj['type'] === 'Video') {
- $vtypes = [
- 'video/mp4',
- 'video/ogg',
- 'video/webm'
- ];
+ $vtypes = [
+ 'video/mp4',
+ 'video/ogg',
+ 'video/webm'
+ ];
- $mps = [];
- if(array_key_exists('url',$act->obj) && is_array($act->obj['url'])) {
- foreach($act->obj['url'] as $vurl) {
- if(in_array($vurl['mimeType'], $vtypes)) {
- if(! array_key_exists('width',$vurl)) {
- $vurl['width'] = 0;
+ $mps = [];
+ $ptr = null;
+
+ if(array_key_exists('url',$act->obj)) {
+ if(is_array($act->obj['url'])) {
+ if(array_key_exists(0,$act->obj['url'])) {
+ $ptr = $act->obj['url'];
+ }
+ else {
+ $ptr = [ $act->obj['url'] ];
+ }
+ foreach($ptr as $vurl) {
+ // peertube uses the non-standard element name 'mimeType' here
+ if(array_key_exists('mimeType',$vurl)) {
+ if(in_array($vurl['mimeType'], $vtypes)) {
+ if(! array_key_exists('width',$vurl)) {
+ $vurl['width'] = 0;
+ }
+ $mps[] = $vurl;
+ }
+ }
+ elseif(array_key_exists('mediaType',$vurl)) {
+ if(in_array($vurl['mediaType'], $vtypes)) {
+ if(! array_key_exists('width',$vurl)) {
+ $vurl['width'] = 0;
+ }
+ $mps[] = $vurl;
+ }
+ }
}
- $mps[] = $vurl;
+ }
+ if($mps) {
+ usort($mps,[ __CLASS__, 'vid_sort' ]);
+ foreach($mps as $m) {
+ if(intval($m['width']) < 500 && self::media_not_in_body($m['href'],$s['body'])) {
+ $s['body'] .= "\n\n" . '[video]' . $m['href'] . '[/video]';
+ break;
+ }
+ }
+ }
+ elseif(is_string($act->obj['url']) && self::media_not_in_body($act->obj['url'],$s['body'])) {
+ $s['body'] .= "\n\n" . '[video]' . $act->obj['url'] . '[/video]';
}
}
}
- if($mps) {
- usort($mps,'as_vid_sort');
- foreach($mps as $m) {
- if(intval($m['width']) < 500) {
- $s['body'] .= "\n\n" . '[video]' . $m['href'] . '[/video]';
- break;
+
+ if($act->obj['type'] === 'Audio') {
+
+ $atypes = [
+ 'audio/mpeg',
+ 'audio/ogg',
+ 'audio/wav'
+ ];
+
+ $ptr = null;
+
+ if(array_key_exists('url',$act->obj)) {
+ if(is_array($act->obj['url'])) {
+ if(array_key_exists(0,$act->obj['url'])) {
+ $ptr = $act->obj['url'];
+ }
+ else {
+ $ptr = [ $act->obj['url'] ];
+ }
+ foreach($ptr as $vurl) {
+ if(in_array($vurl['mediaType'], $atypes) && self::media_not_in_body($vurl['href'],$s['body'])) {
+ $s['body'] .= "\n\n" . '[audio]' . $vurl['href'] . '[/audio]';
+ break;
+ }
+ }
+ }
+ elseif(is_string($act->obj['url']) && self::media_not_in_body($act->obj['url'],$s['body'])) {
+ $s['body'] .= "\n\n" . '[audio]' . $act->obj['url'] . '[/audio]';
+ }
+ }
+
+ }
+
+ if($act->obj['type'] === 'Image') {
+
+ $ptr = null;
+
+ if(array_key_exists('url',$act->obj)) {
+ if(is_array($act->obj['url'])) {
+ if(array_key_exists(0,$act->obj['url'])) {
+ $ptr = $act->obj['url'];
+ }
+ else {
+ $ptr = [ $act->obj['url'] ];
+ }
+ foreach($ptr as $vurl) {
+ if(strpos($s['body'],$vurl['href']) === false) {
+ $s['body'] .= "\n\n" . '[zmg]' . $vurl['href'] . '[/zmg]';
+ break;
+ }
+ }
+ }
+ elseif(is_string($act->obj['url'])) {
+ if(strpos($s['body'],$act->obj['url']) === false) {
+ $s['body'] .= "\n\n" . '[zmg]' . $act->obj['url'] . '[/zmg]';
+ }
+ }
+ }
+ }
+
+
+ if($act->obj['type'] === 'Page' && ! $s['body']) {
+
+ $ptr = null;
+ $purl = EMPTY_STR;
+
+ if(array_key_exists('url',$act->obj)) {
+ if(is_array($act->obj['url'])) {
+ if(array_key_exists(0,$act->obj['url'])) {
+ $ptr = $act->obj['url'];
+ }
+ else {
+ $ptr = [ $act->obj['url'] ];
+ }
+ foreach($ptr as $vurl) {
+ if(array_key_exists('mediaType',$vurl) && $vurl['mediaType'] === 'text/html') {
+ $purl = $vurl['href'];
+ break;
+ }
+ elseif(array_key_exists('mimeType',$vurl) && $vurl['mimeType'] === 'text/html') {
+ $purl = $vurl['href'];
+ break;
+ }
+ }
+ }
+ elseif(is_string($act->obj['url'])) {
+ $purl = $act->obj['url'];
+ }
+ if($purl) {
+ $li = z_fetch_url(z_root() . '/linkinfo?binurl=' . bin2hex($purl));
+ if($li['success'] && $li['body']) {
+ $s['body'] .= "\n" . $li['body'];
+ }
+ else {
+ $s['body'] .= "\n\n" . $purl;
+ }
+ }
+ }
+ }
+ }
+
+
+
+ if(in_array($act->obj['type'],[ 'Note','Article','Page' ])) {
+ $ptr = null;
+
+ if(array_key_exists('url',$act->obj)) {
+ if(is_array($act->obj['url'])) {
+ if(array_key_exists(0,$act->obj['url'])) {
+ $ptr = $act->obj['url'];
}
+ else {
+ $ptr = [ $act->obj['url'] ];
+ }
+ foreach($ptr as $vurl) {
+ if(array_key_exists('mediaType',$vurl) && $vurl['mediaType'] === 'text/html') {
+ $s['plink'] = $vurl['href'];
+ break;
+ }
+ }
+ }
+ elseif(is_string($act->obj['url'])) {
+ $s['plink'] = $act->obj['url'];
}
}
}
+ if(! $s['plink']) {
+ $s['plink'] = $s['mid'];
+ }
+
if($act->recips && (! in_array(ACTIVITY_PUBLIC_INBOX,$act->recips)))
$s['item_private'] = 1;
@@ -1371,8 +1566,6 @@ class Activity {
}
-
-
static function announce_note($channel,$observer_hash,$act) {
$s = [];
@@ -1464,7 +1657,7 @@ class Activity {
$body .= self::bb_content($content,'content');
if($act->obj['type'] === 'Note' && $s['attach']) {
- $body .= self::bb_attach($s['attach']);
+ $body .= self::bb_attach($s['attach'],$body);
}
$body .= "[/share]";
@@ -1642,19 +1835,26 @@ class Activity {
}
- static function bb_attach($attach) {
+
+ static function bb_attach($attach,$body) {
$ret = false;
foreach($attach as $a) {
if(strpos($a['type'],'image') !== false) {
- $ret .= "\n\n" . '[img]' . $a['href'] . '[/img]';
+ if(self::media_not_in_body($a['href'],$body)) {
+ $ret .= "\n\n" . '[img]' . $a['href'] . '[/img]';
+ }
}
if(array_key_exists('type',$a) && strpos($a['type'], 'video') === 0) {
- $ret .= "\n\n" . '[video]' . $a['href'] . '[/video]';
+ if(self::media_not_in_body($a['href'],$body)) {
+ $ret .= "\n\n" . '[video]' . $a['href'] . '[/video]';
+ }
}
if(array_key_exists('type',$a) && strpos($a['type'], 'audio') === 0) {
- $ret .= "\n\n" . '[audio]' . $a['href'] . '[/audio]';
+ if(self::media_not_in_body($a['href'],$body)) {
+ $ret .= "\n\n" . '[audio]' . $a['href'] . '[/audio]';
+ }
}
}
@@ -1662,16 +1862,31 @@ class Activity {
}
+ // check for the existence of existing media link in body
+
+ static function media_not_in_body($s,$body) {
+
+ if((strpos($body,']' . $s . '[/img]') === false) &&
+ (strpos($body,']' . $s . '[/zmg]') === false) &&
+ (strpos($body,']' . $s . '[/video]') === false) &&
+ (strpos($body,']' . $s . '[/audio]') === false)) {
+ return true;
+ }
+ return false;
+ }
+
static function bb_content($content,$field) {
require_once('include/html2bbcode.php');
-
+ require_once('include/event.php');
$ret = false;
if(is_array($content[$field])) {
foreach($content[$field] as $k => $v) {
- $ret .= '[language=' . $k . ']' . html2bbcode($v) . '[/language]';
+ $ret .= html2bbcode($v);
+ // save this for auto-translate or dynamic filtering
+ // $ret .= '[language=' . $k . ']' . html2bbcode($v) . '[/language]';
}
}
else {
@@ -1682,6 +1897,9 @@ class Activity {
$ret = html2bbcode($content[$field]);
}
}
+ if($field === 'content' && $content['event'] && (! strpos($ret,'[event'))) {
+ $ret .= format_event_bbcode($content['event']);
+ }
return $ret;
}
@@ -1690,21 +1908,52 @@ class Activity {
static function get_content($act) {
$content = [];
- if (! $act) {
+ $event = null;
+
+ if ((! $act) || (! is_array($act))) {
return $content;
}
+ if($act['type'] === 'Event') {
+ $adjust = false;
+ $event = [];
+ $event['event_hash'] = $act['id'];
+ if(array_key_exists('startTime',$act) && strpos($act['startTime'],-1,1) === 'Z') {
+ $adjust = true;
+ $event['adjust'] = 1;
+ $event['dtstart'] = datetime_convert('UTC','UTC',$event['startTime'] . (($adjust) ? '' : 'Z'));
+ }
+ if(array_key_exists('endTime',$act)) {
+ $event['dtend'] = datetime_convert('UTC','UTC',$event['endTime'] . (($adjust) ? '' : 'Z'));
+ }
+ else {
+ $event['nofinish'] = true;
+ }
+ }
+
foreach ([ 'name', 'summary', 'content' ] as $a) {
if (($x = self::get_textfield($act,$a)) !== false) {
$content[$a] = $x;
}
}
+
+ if($event) {
+ $event['summary'] = html2bbcode($content['summary']);
+ $event['description'] = html2bbcode($content['content']);
+ if($event['summary'] && $event['dtstart']) {
+ $content['event'] = $event;
+ }
+ }
+
if (array_key_exists('source',$act) && array_key_exists('mediaType',$act['source'])) {
if ($act['source']['mediaType'] === 'text/bbcode') {
$content['bbcode'] = purify_html($act['source']['content']);
}
}
+
+
+
return $content;
}
@@ -1722,4 +1971,6 @@ class Activity {
}
return $content;
}
+
+
} \ No newline at end of file
diff --git a/Zotlabs/Lib/Enotify.php b/Zotlabs/Lib/Enotify.php
index 25c96d9cc..5e5798cac 100644
--- a/Zotlabs/Lib/Enotify.php
+++ b/Zotlabs/Lib/Enotify.php
@@ -828,6 +828,7 @@ class Enotify {
$x = array(
'notify_link' => $item['llink'],
'name' => $item['author']['xchan_name'],
+ 'addr' => (($item['author']['xchan_addr']) ? $item['author']['xchan_addr'] : $item['author']['xchan_url']),
'url' => $item['author']['xchan_url'],
'photo' => $item['author']['xchan_photo_s'],
'when' => relative_date(($edit)? $item['edited'] : $item['created']),
diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php
index 70f013eb7..0fbde9765 100644
--- a/Zotlabs/Lib/Libzot.php
+++ b/Zotlabs/Lib/Libzot.php
@@ -1418,7 +1418,7 @@ logger('4');
$DR = new DReport(z_root(),$sender,$d,$arr['mid']);
- $channel = channelx_by_hash($d);
+ $channel = channelx_by_portid($d);
if (! $channel) {
$DR->update('recipient not found');
@@ -1505,8 +1505,10 @@ logger('4');
}
}
- if($arr['mid'] != $arr['parent_mid']) {
+logger('item: ' . print_r($arr,true), LOGGER_DATA);
+ if($arr['mid'] !== $arr['parent_mid']) {
+logger('checking source: "' . $arr['mid'] . '" != "' . $arr['parent_mid'] . '"');
// check source route.
// We are only going to accept comments from this sender if the comment has the same route as the top-level-post,
// this is so that permissions mismatches between senders apply to the entire conversation
@@ -1591,7 +1593,7 @@ logger('4');
$arr['route'] = $last_prior_route;
}
}
-
+logger('hey');
$ab = q("select * from abook where abook_channel = %d and abook_xchan = '%s'",
intval($channel['channel_id']),
dbesc($arr['owner_xchan'])
diff --git a/Zotlabs/Module/Import.php b/Zotlabs/Module/Import.php
index 6016328a5..0daf28aa9 100644
--- a/Zotlabs/Module/Import.php
+++ b/Zotlabs/Module/Import.php
@@ -127,6 +127,15 @@ class Import extends \Zotlabs\Web\Controller {
//
// }
+
+ // prevent incompatible osada or zap data from horking your database
+
+ if(array_path_exists('compatibility/codebase',$data)) {
+ notice('Data export format is not compatible with this software');
+ return;
+ }
+
+
if($moving)
$seize = 1;
diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php
index 1d64ef60c..24949c626 100644
--- a/Zotlabs/Module/Item.php
+++ b/Zotlabs/Module/Item.php
@@ -760,7 +760,7 @@ class Item extends Controller {
// fix permalinks for cards
if($webpage == ITEM_TYPE_CARD) {
- $plink = z_root() . '/cards/' . $channel['channel_address'] . '/' . (($pagetitle) ? $pagetitle : substr($mid,0,16));
+ $plink = z_root() . '/cards/' . $channel['channel_address'] . '/' . (($pagetitle) ? $pagetitle : $uuid);
}
if(($parent_item) && ($parent_item['item_type'] == ITEM_TYPE_CARD)) {
$r = q("select v from iconfig where iconfig.cat = 'system' and iconfig.k = 'CARD' and iconfig.iid = %d limit 1",
@@ -772,7 +772,7 @@ class Item extends Controller {
}
if($webpage == ITEM_TYPE_ARTICLE) {
- $plink = z_root() . '/articles/' . $channel['channel_address'] . '/' . (($pagetitle) ? $pagetitle : substr($mid,0,16));
+ $plink = z_root() . '/articles/' . $channel['channel_address'] . '/' . (($pagetitle) ? $pagetitle : $uuid);
}
if(($parent_item) && ($parent_item['item_type'] == ITEM_TYPE_ARTICLE)) {
$r = q("select v from iconfig where iconfig.cat = 'system' and iconfig.k = 'ARTICLE' and iconfig.iid = %d limit 1",
@@ -784,7 +784,7 @@ class Item extends Controller {
}
if ((! $plink) && ($item_thread_top)) {
- $plink = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $mid;
+ $plink = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . gen_link_id($mid);
$plink = substr($plink,0,190);
}
diff --git a/Zotlabs/Module/Like.php b/Zotlabs/Module/Like.php
index c39726b88..d19154eb4 100644
--- a/Zotlabs/Module/Like.php
+++ b/Zotlabs/Module/Like.php
@@ -1,6 +1,8 @@
<?php
namespace Zotlabs\Module;
+use Zotlabs\Lib\Activity;
+
require_once('include/security.php');
require_once('include/bbcode.php');
require_once('include/items.php');
@@ -400,6 +402,7 @@ class Like extends \Zotlabs\Web\Controller {
$object = json_encode(array(
'type' => $objtype,
'id' => $item['mid'],
+ 'asld' => Activity::fetch_item( [ 'id' => $item['mid'] ] ),
'parent' => (($item['thr_parent']) ? $item['thr_parent'] : $item['parent_mid']),
'link' => $links,
'title' => $item['title'],
diff --git a/Zotlabs/Module/Pconfig.php b/Zotlabs/Module/Pconfig.php
index 44fe5d9a9..f31d5fdf6 100644
--- a/Zotlabs/Module/Pconfig.php
+++ b/Zotlabs/Module/Pconfig.php
@@ -22,6 +22,11 @@ class Pconfig extends \Zotlabs\Web\Controller {
$k = trim(escape_tags($_POST['k']));
$v = trim($_POST['v']);
$aj = intval($_POST['aj']);
+
+ // Do not store "serialized" data received in the $_POST
+ if (preg_match('|^a:[0-9]+:{.*}$|s',$v) || preg_match('O:8:"stdClass":[0-9]+:{.*}$|s',$v)) {
+ return;
+ }
if(in_array(argv(2),$this->disallowed_pconfig())) {
notice( t('This setting requires special processing and editing has been blocked.') . EOL);
diff --git a/Zotlabs/Module/Photo.php b/Zotlabs/Module/Photo.php
index 30e8340e2..ddff3a68e 100644
--- a/Zotlabs/Module/Photo.php
+++ b/Zotlabs/Module/Photo.php
@@ -1,19 +1,20 @@
<?php
+
+
namespace Zotlabs\Module;
require_once('include/security.php');
require_once('include/attach.php');
require_once('include/photo/photo_driver.php');
-
class Photo extends \Zotlabs\Web\Controller {
function init() {
- $prvcachecontrol = false;
$streaming = null;
$channel = null;
$person = 0;
+ $renew = false;
switch(argc()) {
case 4:
@@ -29,7 +30,15 @@ class Photo extends \Zotlabs\Web\Controller {
killme();
// NOTREACHED
}
-
+
+ $cache_mode = array(
+ 'on' => get_config('system','photo_cache_enable', 0),
+ 'age' => 86400,
+ 'exp' => true,
+ 'leak' => false
+ );
+ call_hooks('cache_mode_hook', $cache_mode);
+
$observer_xchan = get_observer_hash();
$ismodified = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
@@ -106,13 +115,14 @@ class Photo extends \Zotlabs\Web\Controller {
License link: http://creativecommons.org/licenses/by/3.0/
*/
+ // @FIXME It seems this part doesn't work because we are not setting such cookie
$cookie_value = false;
if (isset($_COOKIE['devicePixelRatio'])) {
$cookie_value = intval($_COOKIE['devicePixelRatio']);
}
else {
// Force revalidation of cache on next request
- $cache_directive = 'no-cache';
+ // $prvcachecontrol = 'no-cache';
$status = 'no cookie';
}
@@ -129,27 +139,40 @@ class Photo extends \Zotlabs\Web\Controller {
$resolution = 1;
}
- $r = q("SELECT uid, photo_usage FROM photo WHERE resource_id = '%s' AND imgscale = %d LIMIT 1",
+ $r = q("SELECT uid, photo_usage, display_path FROM photo WHERE resource_id = '%s' AND imgscale = %d LIMIT 1",
dbesc($photo),
intval($resolution)
);
if($r) {
-
$allowed = (-1);
- if(intval($r[0]['photo_usage'])) {
+ $u = intval($r[0]['photo_usage']);
+ if($u) {
$allowed = 1;
- if(intval($r[0]['photo_usage']) === PHOTO_COVER)
+ if($u === PHOTO_COVER)
if($resolution < PHOTO_RES_COVER_1200)
$allowed = (-1);
- if(intval($r[0]['photo_usage']) === PHOTO_PROFILE)
+ if($u === PHOTO_PROFILE)
if(! in_array($resolution,[4,5,6]))
$allowed = (-1);
+ if($u === PHOTO_CACHE) {
+ // Validate cache
+ $cache = array(
+ 'resid' => $photo,
+ 'uid' => $r[0]['uid'],
+ 'status' => false
+ );
+ if($cache_mode['on'])
+ call_hooks('cache_url_hook', $cache);
+ if(! $cache['status']) {
+ header("Location: " . htmlspecialchars_decode($r[0]['display_path']));
+ killme();
+ }
+ }
}
- if($allowed === (-1)) {
+ if($allowed === (-1))
$allowed = attach_can_view($r[0]['uid'],$observer_xchan,$photo);
- }
$channel = channelx_by_n($r[0]['uid']);
@@ -158,18 +181,21 @@ class Photo extends \Zotlabs\Web\Controller {
dbesc($photo),
intval($resolution)
);
-
+
$exists = (($e) ? true : false);
-
+
if($exists && $allowed) {
+ $expires = strtotime($e[0]['expires'] . 'Z');
$data = dbunescbin($e[0]['content']);
$filesize = $e[0]['filesize'];
$mimetype = $e[0]['mimetype'];
$modified = strtotime($e[0]['edited'] . 'Z');
- if(intval($e[0]['os_storage']))
+
+ if(intval($e[0]['os_storage'])) {
$streaming = $data;
+ }
if($e[0]['allow_cid'] != '' || $e[0]['allow_gid'] != '' || $e[0]['deny_gid'] != '' || $e[0]['deny_gid'] != '')
- $prvcachecontrol = true;
+ $prvcachecontrol = 'no-store, no-cache, must-revalidate';
}
else {
if(! $allowed) {
@@ -180,9 +206,9 @@ class Photo extends \Zotlabs\Web\Controller {
}
}
- } else {
+ }
+ else
http_status_exit(404,'not found');
- }
}
header_remove('Pragma');
@@ -225,24 +251,14 @@ class Photo extends \Zotlabs\Web\Controller {
$mimetype = $ph->getType();
}
}
-
- // @FIXME Seems never invoked
- // Writing in cachefile
- if (isset($cachefile) && $cachefile != '') {
- file_put_contents($cachefile, $data);
- $modified = filemtime($cachefile);
- }
-
- header("Content-type: " . $mimetype);
-
- if($prvcachecontrol) {
+ if(isset($prvcachecontrol)) {
// it is a private photo that they have no permission to view.
// tell the browser not to cache it, in case they authenticate
// and subsequently have permission to see it
- header("Cache-Control: no-store, no-cache, must-revalidate");
+ header("Cache-Control: " . $prvcachecontrol);
}
else {
@@ -255,18 +271,23 @@ class Photo extends \Zotlabs\Web\Controller {
// This has performance considerations but we highly recommend you
// leave it alone.
- $cache = get_config('system','photo_cache_time', 86400); // 1 day by default
+ $maxage = $cache_mode['age'];
- header("Expires: " . gmdate("D, d M Y H:i:s", time() + $cache) . " GMT");
- header("Cache-Control: max-age=" . $cache);
+ if($cache_mode['exp'] || (! isset($expires)) || (isset($expires) && $expires - 60 < time()))
+ $expires = time() + $maxage;
+ else
+ $maxage = $expires - time();
+
+ header("Expires: " . gmdate("D, d M Y H:i:s", $expires) . " GMT");
+ header("Cache-Control: max-age=" . $maxage);
}
+ header("Content-type: " . $mimetype);
header("Last-Modified: " . gmdate("D, d M Y H:i:s", $modified) . " GMT");
header("Content-Length: " . (isset($filesize) ? $filesize : strlen($data)));
// If it's a file resource, stream it.
-
if($streaming && $channel) {
if(strpos($streaming,'store') !== false)
$istream = fopen($streaming,'rb');
diff --git a/Zotlabs/Module/Ping.php b/Zotlabs/Module/Ping.php
index f660c3b55..12244d88c 100644
--- a/Zotlabs/Module/Ping.php
+++ b/Zotlabs/Module/Ping.php
@@ -330,6 +330,7 @@ class Ping extends \Zotlabs\Web\Controller {
$notifs[] = array(
'notify_link' => z_root() . '/mail/' . $zz['id'],
'name' => $zz['xchan_name'],
+ 'addr' => $zz['xchan_addr'],
'url' => $zz['xchan_url'],
'photo' => $zz['xchan_photo_s'],
'when' => relative_date($zz['created']),
@@ -383,6 +384,7 @@ class Ping extends \Zotlabs\Web\Controller {
$result[] = array(
'notify_link' => z_root() . '/connections/ifpending',
'name' => $rr['xchan_name'],
+ 'addr' => $rr['xchan_addr'],
'url' => $rr['xchan_url'],
'photo' => $rr['xchan_photo_s'],
'when' => relative_date($rr['abook_created']),
@@ -407,6 +409,7 @@ class Ping extends \Zotlabs\Web\Controller {
$result[] = array(
'notify_link' => z_root() . '/admin/accounts',
'name' => $rr['account_email'],
+ 'addr' => $rr['account_email'],
'url' => '',
'photo' => z_root() . '/' . get_default_profile_photo(48),
'when' => relative_date($rr['account_created']),
@@ -444,6 +447,7 @@ class Ping extends \Zotlabs\Web\Controller {
$result[] = array(
'notify_link' => z_root() . '/events', /// @FIXME this takes you to an edit page and it may not be yours, we really want to just view the single event --> '/events/event/' . $rr['event_hash'],
'name' => $rr['xchan_name'],
+ 'addr' => $rr['xchan_addr'],
'url' => $rr['xchan_url'],
'photo' => $rr['xchan_photo_s'],
'when' => $when,
@@ -460,7 +464,7 @@ class Ping extends \Zotlabs\Web\Controller {
if(argc() > 1 && (argv(1) === 'files')) {
$result = array();
- $r = q("SELECT item.created, xchan.xchan_name, xchan.xchan_url, xchan.xchan_photo_s FROM item
+ $r = q("SELECT item.created, xchan.xchan_name, xchan.xchan_addr, xchan.xchan_url, xchan.xchan_photo_s FROM item
LEFT JOIN xchan on author_xchan = xchan_hash
WHERE item.verb = '%s'
AND item.obj_type = '%s'
@@ -477,6 +481,7 @@ class Ping extends \Zotlabs\Web\Controller {
$result[] = array(
'notify_link' => z_root() . '/sharedwithme',
'name' => $rr['xchan_name'],
+ 'addr' => $rr['xchan_addr'],
'url' => $rr['xchan_url'],
'photo' => $rr['xchan_photo_s'],
'when' => relative_date($rr['created']),
@@ -658,6 +663,7 @@ class Ping extends \Zotlabs\Web\Controller {
if($r[0]['unseen']) {
$forums[$x]['notify_link'] = (($forums[$x]['private_forum']) ? $forums[$x]['xchan_url'] : z_root() . '/network/?f=&pf=1&unseen=1&cid=' . $forums[$x]['abook_id']);
$forums[$x]['name'] = $forums[$x]['xchan_name'];
+ $forums[$x]['addr'] = $forums[$x]['xchan_addr'];
$forums[$x]['url'] = $forums[$x]['xchan_url'];
$forums[$x]['photo'] = $forums[$x]['xchan_photo_s'];
$forums[$x]['unseen'] = $r[0]['unseen'];
diff --git a/Zotlabs/Module/Wfinger.php b/Zotlabs/Module/Wfinger.php
index e4591df12..03275abbc 100644
--- a/Zotlabs/Module/Wfinger.php
+++ b/Zotlabs/Module/Wfinger.php
@@ -43,6 +43,9 @@ class Wfinger extends \Zotlabs\Web\Controller {
if(strpos($resource,'acct:') === 0) {
$channel = str_replace('acct:','',$resource);
+ if(substr($channel,0,1) === '@' && strpos(substr($channel,1),'@')) {
+ $channel = substr($channel,1);
+ }
if(strpos($channel,'@') !== false) {
$host = substr($channel,strpos($channel,'@')+1);
diff --git a/Zotlabs/Update/_1228.php b/Zotlabs/Update/_1228.php
index f8a506bb4..9e6bf8047 100644
--- a/Zotlabs/Update/_1228.php
+++ b/Zotlabs/Update/_1228.php
@@ -11,8 +11,8 @@ class _1228 {
if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
$r1 = q("ALTER TABLE item ADD uuid text NOT NULL DEFAULT '' ");
- $r2 = q("create index \"uuid_idx\" on channel (\"uuid\")");
- $r3 = q("ALTER TABLE item add summary TEXT NOT NULL");
+ $r2 = q("create index \"uuid_idx\" on item (\"uuid\")");
+ $r3 = q("ALTER TABLE item add summary TEXT NOT NULL DEFAULT ''");
$r = ($r1 && $r2 && $r3);
}
diff --git a/Zotlabs/Update/_1229.php b/Zotlabs/Update/_1229.php
new file mode 100644
index 000000000..8e8711644
--- /dev/null
+++ b/Zotlabs/Update/_1229.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Zotlabs\Update;
+
+class _1229 {
+
+ function run() {
+
+ q("START TRANSACTION");
+
+ if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
+ $r1 = q("ALTER TABLE photo ADD expires timestamp NOT NULL DEFAULT '0001-01-01 00:00:00' ");
+ $r2 = q("create index \"photo_expires_idx\" on photo (\"expires\")");
+
+ $r = ($r1 && $r2);
+ }
+ else {
+ $r = q("ALTER TABLE `photo` ADD `expires` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' ,
+ ADD INDEX `expires` (`expires`)");
+ }
+
+ if($r) {
+ q("COMMIT");
+ return UPDATE_SUCCESS;
+ }
+
+ q("ROLLBACK");
+ return UPDATE_FAILED;
+
+ }
+
+}
diff --git a/Zotlabs/Widget/Notifications.php b/Zotlabs/Widget/Notifications.php
index 0f9f609e4..37d9139ec 100644
--- a/Zotlabs/Widget/Notifications.php
+++ b/Zotlabs/Widget/Notifications.php
@@ -24,7 +24,7 @@ class Notifications {
],
'filter' => [
'posts_label' => t('Show new posts only'),
- 'name_label' => t('Filter by name')
+ 'name_label' => t('Filter by name or address')
]
];
@@ -43,7 +43,7 @@ class Notifications {
],
'filter' => [
'posts_label' => t('Show new posts only'),
- 'name_label' => t('Filter by name')
+ 'name_label' => t('Filter by name or address')
]
];
@@ -119,7 +119,7 @@ class Notifications {
'label' => t('Forums'),
'title' => t('Forums'),
'filter' => [
- 'name_label' => t('Filter by name')
+ 'name_label' => t('Filter by name or address')
]
];
}
@@ -150,7 +150,7 @@ class Notifications {
],
'filter' => [
'posts_label' => t('Show new posts only'),
- 'name_label' => t('Filter by name')
+ 'name_label' => t('Filter by name or address')
]
];
}
diff --git a/boot.php b/boot.php
index c74309be0..e49134a55 100755
--- a/boot.php
+++ b/boot.php
@@ -53,7 +53,7 @@ define ( 'PLATFORM_NAME', 'hubzilla' );
define ( 'STD_VERSION', '3.9.5' );
define ( 'ZOT_REVISION', '6.0a' );
-define ( 'DB_UPDATE_VERSION', 1228 );
+define ( 'DB_UPDATE_VERSION', 1229 );
define ( 'PROJECT_BASE', __DIR__ );
@@ -217,6 +217,7 @@ define ( 'PHOTO_PROFILE', 0x0001 );
define ( 'PHOTO_XCHAN', 0x0002 );
define ( 'PHOTO_THING', 0x0004 );
define ( 'PHOTO_COVER', 0x0010 );
+define ( 'PHOTO_CACHE', 0x0020 );
define ( 'PHOTO_ADULT', 0x0008 );
define ( 'PHOTO_FLAG_OS', 0x4000 );
diff --git a/composer.json b/composer.json
index f117cc3b1..e6cefa241 100644
--- a/composer.json
+++ b/composer.json
@@ -40,7 +40,8 @@
"smarty/smarty": "~3.1",
"ramsey/uuid": "^3.8",
"twbs/bootstrap": "4.1.3",
- "blueimp/jquery-file-upload": "^9.25"
+ "blueimp/jquery-file-upload": "^9.25",
+ "desandro/imagesloaded": "^4.1"
},
"require-dev" : {
"phpunit/phpunit" : "@stable",
diff --git a/composer.lock b/composer.lock
index d7e8d11f6..bd95e8c78 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,20 +4,20 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "63d0e52cc07f8113059ec30d3637b850",
+ "content-hash": "fe5e71d7076eeddf1c174be4a5c052dd",
"packages": [
{
"name": "blueimp/jquery-file-upload",
- "version": "v9.25.1",
+ "version": "v9.28.0",
"source": {
"type": "git",
"url": "https://github.com/vkhramtsov/jQuery-File-Upload.git",
- "reference": "28891f9b2bc339bcc1ca8d548e5401e8563bf04b"
+ "reference": "ff5accfe2e5c4a522777faa980a90cf86a636d1d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/vkhramtsov/jQuery-File-Upload/zipball/28891f9b2bc339bcc1ca8d548e5401e8563bf04b",
- "reference": "28891f9b2bc339bcc1ca8d548e5401e8563bf04b",
+ "url": "https://api.github.com/repos/vkhramtsov/jQuery-File-Upload/zipball/ff5accfe2e5c4a522777faa980a90cf86a636d1d",
+ "reference": "ff5accfe2e5c4a522777faa980a90cf86a636d1d",
"shasum": ""
},
"type": "library",
@@ -59,7 +59,7 @@
"upload",
"widget"
],
- "time": "2018-10-26T07:21:48+00:00"
+ "time": "2018-11-13T05:41:39+00:00"
},
{
"name": "bshaffer/oauth2-server-php",
@@ -164,6 +164,45 @@
"time": "2017-12-29T00:13:05+00:00"
},
{
+ "name": "desandro/imagesloaded",
+ "version": "v4.1.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/desandro/imagesloaded.git",
+ "reference": "67c4e57453120935180c45c6820e7d3fbd2ea1f9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/desandro/imagesloaded/zipball/67c4e57453120935180c45c6820e7d3fbd2ea1f9",
+ "reference": "67c4e57453120935180c45c6820e7d3fbd2ea1f9",
+ "shasum": ""
+ },
+ "type": "component",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "David DeSandro",
+ "homepage": "http://desandro.com/",
+ "role": "developer"
+ }
+ ],
+ "description": "JavaScript is all like _You images done yet or what?_",
+ "homepage": "http://imagesloaded.desandro.com",
+ "keywords": [
+ "dom",
+ "images",
+ "javascript",
+ "jquery-plugin",
+ "library",
+ "loaded",
+ "ui"
+ ],
+ "time": "2018-01-02T16:53:35+00:00"
+ },
+ {
"name": "ezyang/htmlpurifier",
"version": "v4.10.0",
"source": {
@@ -446,16 +485,16 @@
},
{
"name": "psr/log",
- "version": "1.0.2",
+ "version": "1.1.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
- "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
+ "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
- "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
+ "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
"shasum": ""
},
"require": {
@@ -489,7 +528,7 @@
"psr",
"psr-3"
],
- "time": "2016-10-10T12:19:37+00:00"
+ "time": "2018-11-20T15:27:04+00:00"
},
{
"name": "ramsey/uuid",
@@ -1110,7 +1149,7 @@
},
{
"name": "symfony/polyfill-ctype",
- "version": "v1.9.0",
+ "version": "v1.10.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
@@ -2536,16 +2575,16 @@
},
{
"name": "phpunit/php-code-coverage",
- "version": "6.1.3",
+ "version": "6.1.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "4d3ae9b21a7d7e440bd0cf65565533117976859f"
+ "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4d3ae9b21a7d7e440bd0cf65565533117976859f",
- "reference": "4d3ae9b21a7d7e440bd0cf65565533117976859f",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
+ "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
"shasum": ""
},
"require": {
@@ -2595,7 +2634,7 @@
"testing",
"xunit"
],
- "time": "2018-10-23T05:59:32+00:00"
+ "time": "2018-10-31T16:06:48+00:00"
},
{
"name": "phpunit/php-file-iterator",
@@ -2788,16 +2827,16 @@
},
{
"name": "phpunit/phpunit",
- "version": "7.4.3",
+ "version": "7.4.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "c151651fb6ed264038d486ea262e243af72e5e64"
+ "reference": "b1be2c8530c4c29c3519a052c9fb6cee55053bbd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c151651fb6ed264038d486ea262e243af72e5e64",
- "reference": "c151651fb6ed264038d486ea262e243af72e5e64",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b1be2c8530c4c29c3519a052c9fb6cee55053bbd",
+ "reference": "b1be2c8530c4c29c3519a052c9fb6cee55053bbd",
"shasum": ""
},
"require": {
@@ -2868,7 +2907,7 @@
"testing",
"xunit"
],
- "time": "2018-10-23T05:57:41+00:00"
+ "time": "2018-11-14T16:52:02+00:00"
},
{
"name": "psr/container",
@@ -3534,7 +3573,7 @@
},
{
"name": "symfony/browser-kit",
- "version": "v4.1.6",
+ "version": "v4.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/browser-kit.git",
@@ -3591,16 +3630,16 @@
},
{
"name": "symfony/class-loader",
- "version": "v3.4.17",
+ "version": "v3.4.18",
"source": {
"type": "git",
"url": "https://github.com/symfony/class-loader.git",
- "reference": "f31333bdff54c7595f834d510a6d2325573ddb36"
+ "reference": "5605edec7b8f034ead2497ff4aab17bb70d558c1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/class-loader/zipball/f31333bdff54c7595f834d510a6d2325573ddb36",
- "reference": "f31333bdff54c7595f834d510a6d2325573ddb36",
+ "url": "https://api.github.com/repos/symfony/class-loader/zipball/5605edec7b8f034ead2497ff4aab17bb70d558c1",
+ "reference": "5605edec7b8f034ead2497ff4aab17bb70d558c1",
"shasum": ""
},
"require": {
@@ -3643,20 +3682,20 @@
],
"description": "Symfony ClassLoader Component",
"homepage": "https://symfony.com",
- "time": "2018-10-02T12:28:39+00:00"
+ "time": "2018-10-31T09:06:03+00:00"
},
{
"name": "symfony/config",
- "version": "v4.1.6",
+ "version": "v4.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
- "reference": "b3d4d7b567d7a49e6dfafb6d4760abc921177c96"
+ "reference": "991fec8bbe77367fc8b48ecbaa8a4bd6e905a238"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/config/zipball/b3d4d7b567d7a49e6dfafb6d4760abc921177c96",
- "reference": "b3d4d7b567d7a49e6dfafb6d4760abc921177c96",
+ "url": "https://api.github.com/repos/symfony/config/zipball/991fec8bbe77367fc8b48ecbaa8a4bd6e905a238",
+ "reference": "991fec8bbe77367fc8b48ecbaa8a4bd6e905a238",
"shasum": ""
},
"require": {
@@ -3706,20 +3745,20 @@
],
"description": "Symfony Config Component",
"homepage": "https://symfony.com",
- "time": "2018-09-08T13:24:10+00:00"
+ "time": "2018-10-31T09:09:42+00:00"
},
{
"name": "symfony/console",
- "version": "v4.1.6",
+ "version": "v4.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "dc7122fe5f6113cfaba3b3de575d31112c9aa60b"
+ "reference": "432122af37d8cd52fba1b294b11976e0d20df595"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/dc7122fe5f6113cfaba3b3de575d31112c9aa60b",
- "reference": "dc7122fe5f6113cfaba3b3de575d31112c9aa60b",
+ "url": "https://api.github.com/repos/symfony/console/zipball/432122af37d8cd52fba1b294b11976e0d20df595",
+ "reference": "432122af37d8cd52fba1b294b11976e0d20df595",
"shasum": ""
},
"require": {
@@ -3774,11 +3813,11 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
- "time": "2018-10-03T08:15:46+00:00"
+ "time": "2018-10-31T09:30:44+00:00"
},
{
"name": "symfony/css-selector",
- "version": "v3.4.17",
+ "version": "v3.4.18",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
@@ -3831,16 +3870,16 @@
},
{
"name": "symfony/dependency-injection",
- "version": "v4.1.6",
+ "version": "v4.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/dependency-injection.git",
- "reference": "f6b9d893ad28aefd8942dc0469c8397e2216fe30"
+ "reference": "e72ee2c23d952e4c368ee98610fa22b79b89b483"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f6b9d893ad28aefd8942dc0469c8397e2216fe30",
- "reference": "f6b9d893ad28aefd8942dc0469c8397e2216fe30",
+ "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e72ee2c23d952e4c368ee98610fa22b79b89b483",
+ "reference": "e72ee2c23d952e4c368ee98610fa22b79b89b483",
"shasum": ""
},
"require": {
@@ -3898,11 +3937,11 @@
],
"description": "Symfony DependencyInjection Component",
"homepage": "https://symfony.com",
- "time": "2018-10-02T12:40:59+00:00"
+ "time": "2018-10-31T10:54:16+00:00"
},
{
"name": "symfony/dom-crawler",
- "version": "v4.1.6",
+ "version": "v4.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
@@ -3959,16 +3998,16 @@
},
{
"name": "symfony/event-dispatcher",
- "version": "v4.1.6",
+ "version": "v4.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e"
+ "reference": "552541dad078c85d9414b09c041ede488b456cd5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/bfb30c2ad377615a463ebbc875eba64a99f6aa3e",
- "reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/552541dad078c85d9414b09c041ede488b456cd5",
+ "reference": "552541dad078c85d9414b09c041ede488b456cd5",
"shasum": ""
},
"require": {
@@ -4018,20 +4057,20 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
- "time": "2018-07-26T09:10:45+00:00"
+ "time": "2018-10-10T13:52:42+00:00"
},
{
"name": "symfony/filesystem",
- "version": "v4.1.6",
+ "version": "v4.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "596d12b40624055c300c8b619755b748ca5cf0b5"
+ "reference": "fd7bd6535beb1f0a0a9e3ee960666d0598546981"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/596d12b40624055c300c8b619755b748ca5cf0b5",
- "reference": "596d12b40624055c300c8b619755b748ca5cf0b5",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/fd7bd6535beb1f0a0a9e3ee960666d0598546981",
+ "reference": "fd7bd6535beb1f0a0a9e3ee960666d0598546981",
"shasum": ""
},
"require": {
@@ -4068,20 +4107,20 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
- "time": "2018-10-02T12:40:59+00:00"
+ "time": "2018-10-30T13:18:25+00:00"
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.9.0",
+ "version": "v1.10.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8"
+ "reference": "c79c051f5b3a46be09205c73b80b346e4153e494"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8",
- "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494",
+ "reference": "c79c051f5b3a46be09205c73b80b346e4153e494",
"shasum": ""
},
"require": {
@@ -4127,20 +4166,20 @@
"portable",
"shim"
],
- "time": "2018-08-06T14:22:27+00:00"
+ "time": "2018-09-21T13:07:52+00:00"
},
{
"name": "symfony/translation",
- "version": "v4.1.6",
+ "version": "v4.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
- "reference": "9f0b61e339160a466ebcde167a6c5521c810e304"
+ "reference": "aa04dc1c75b7d3da7bd7003104cd0cfc5dff635c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/translation/zipball/9f0b61e339160a466ebcde167a6c5521c810e304",
- "reference": "9f0b61e339160a466ebcde167a6c5521c810e304",
+ "url": "https://api.github.com/repos/symfony/translation/zipball/aa04dc1c75b7d3da7bd7003104cd0cfc5dff635c",
+ "reference": "aa04dc1c75b7d3da7bd7003104cd0cfc5dff635c",
"shasum": ""
},
"require": {
@@ -4196,11 +4235,11 @@
],
"description": "Symfony Translation Component",
"homepage": "https://symfony.com",
- "time": "2018-10-02T16:36:10+00:00"
+ "time": "2018-10-28T18:38:52+00:00"
},
{
"name": "symfony/yaml",
- "version": "v4.1.6",
+ "version": "v4.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
diff --git a/include/channel.php b/include/channel.php
index 1e5570f6b..95a3f96cf 100644
--- a/include/channel.php
+++ b/include/channel.php
@@ -2333,6 +2333,21 @@ function channelx_by_hash($hash) {
return(($r) ? $r[0] : false);
}
+
+/**
+ * @brief Get a channel array by a channel_hash.
+ *
+ * @param string $hash
+ * @return array|boolean false if channel ID not found, otherwise the channel array
+ */
+function channelx_by_portid($hash) {
+ $r = q("SELECT * FROM channel left join xchan on channel_portable_id = xchan_hash WHERE channel_portable_id = '%s' and channel_removed = 0 LIMIT 1",
+ dbesc($hash)
+ );
+
+ return(($r) ? $r[0] : false);
+}
+
/**
* @brief Get a channel array by a channel ID.
*
diff --git a/include/items.php b/include/items.php
index 2cee376d0..0cbca23fc 100755
--- a/include/items.php
+++ b/include/items.php
@@ -420,7 +420,7 @@ function post_activity_item($arr, $allow_code = false, $deliver = true) {
$arr['comment_policy'] = map_scope(PermissionLimits::Get($channel['channel_id'],'post_comments'));
if ((! $arr['plink']) && (intval($arr['item_thread_top']))) {
- $arr['plink'] = substr(z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . urlencode($arr['mid']),0,190);
+ $arr['plink'] = substr(z_root() . '/channel/' . $channel['channel_address'] . '/' . (filter_var($arr['mid'], FILTER_VALIDATE_URL) === false ? '?f=&mid=' : '') . urlencode($arr['mid']),0,190);
}
@@ -4629,10 +4629,10 @@ function fix_attached_photo_permissions($uid,$xchan_hash,$body,
if(! stristr($image,z_root() . '/photo/'))
continue;
$image_uri = substr($image,strrpos($image,'/') + 1);
- if(strpos($image_uri,'-') !== false)
- $image_uri = substr($image_uri,0, strpos($image_uri,'-'));
- if(strpos($image_uri,'.') !== false)
- $image_uri = substr($image_uri,0, strpos($image_uri,'.'));
+ if(strrpos($image_uri,'-') !== false)
+ $image_uri = substr($image_uri,0, strrpos($image_uri,'-'));
+ if(strrpos($image_uri,'.') !== false)
+ $image_uri = substr($image_uri,0, strrpos($image_uri,'.'));
if(! strlen($image_uri))
continue;
$srch = '<' . $xchan_hash . '>';
diff --git a/include/oembed.php b/include/oembed.php
index e5557dc11..426197c5f 100755
--- a/include/oembed.php
+++ b/include/oembed.php
@@ -221,7 +221,11 @@ function oembed_fetch_url($embedurl){
if(strpos(strtolower($embedurl),'.pdf') !== false) {
$action = 'allow';
- $j = [ 'html' => '<object data="' . $embedurl . '" type="application/pdf" width="500" height="720">' . '<a href="' . $embedurl . '">' . t('View PDF') . '</a></object>', 'width' => 500, 'height' => 720, 'type' => 'pdf' ];
+ $j = [
+ 'html' => '<object data="' . $embedurl . '" type="application/pdf" style="width: 100%; height: 300px;"></object>',
+ 'title' => t('View PDF'),
+ 'type' => 'pdf'
+ ];
}
diff --git a/include/photo/photo_driver.php b/include/photo/photo_driver.php
index b70a13622..9aeb2ef17 100644
--- a/include/photo/photo_driver.php
+++ b/include/photo/photo_driver.php
@@ -112,7 +112,7 @@ abstract class photo_driver {
public function saveImage($path) {
if(!$this->is_valid())
return FALSE;
- file_put_contents($path, $this->imageString());
+ return (file_put_contents($path, $this->imageString()) ? true : false);
}
@@ -330,9 +330,9 @@ abstract class photo_driver {
}
- public function save($arr) {
+ public function save($arr, $skipcheck = false) {
- if(! $this->is_valid()) {
+ if(! ($skipcheck || $this->is_valid())) {
logger('attempt to store invalid photo.');
return false;
}
@@ -344,6 +344,7 @@ abstract class photo_driver {
$p['xchan'] = (($arr['xchan']) ? $arr['xchan'] : '');
$p['resource_id'] = (($arr['resource_id']) ? $arr['resource_id'] : '');
$p['filename'] = (($arr['filename']) ? $arr['filename'] : '');
+ $p['mimetype'] = (($arr['mimetype']) ? $arr['mimetype'] : $this->getType());
$p['album'] = (($arr['album']) ? $arr['album'] : '');
$p['imgscale'] = ((intval($arr['imgscale'])) ? intval($arr['imgscale']) : 0);
$p['allow_cid'] = (($arr['allow_cid']) ? $arr['allow_cid'] : '');
@@ -360,6 +361,7 @@ abstract class photo_driver {
$p['display_path'] = (($arr['display_path']) ? $arr['display_path'] : '');
$p['width'] = (($arr['width']) ? $arr['width'] : $this->getWidth());
$p['height'] = (($arr['height']) ? $arr['height'] : $this->getHeight());
+ $p['expires'] = (($arr['expires']) ? $arr['expires'] : gmdate('Y-m-d H:i:s', time() + get_config('system','photo_cache_time', 86400)));
if(! intval($p['imgscale']))
logger('save: ' . print_r($arr,true), LOGGER_DATA);
@@ -397,17 +399,18 @@ abstract class photo_driver {
allow_cid = '%s',
allow_gid = '%s',
deny_cid = '%s',
- deny_gid = '%s'
+ deny_gid = '%s',
+ expires = '%s'
where id = %d",
intval($p['aid']),
intval($p['uid']),
dbesc($p['xchan']),
dbesc($p['resource_id']),
- dbesc($p['created']),
- dbesc($p['edited']),
+ dbescdate($p['created']),
+ dbescdate($p['edited']),
dbesc(basename($p['filename'])),
- dbesc($this->getType()),
+ dbesc($p['mimetype']),
dbesc($p['album']),
intval($p['height']),
intval($p['width']),
@@ -424,22 +427,23 @@ abstract class photo_driver {
dbesc($p['allow_gid']),
dbesc($p['deny_cid']),
dbesc($p['deny_gid']),
+ dbescdate($p['expires']),
intval($x[0]['id'])
);
}
else {
$p['created'] = (($arr['created']) ? $arr['created'] : $p['edited']);
$r = q("INSERT INTO photo
- ( aid, uid, xchan, resource_id, created, edited, filename, mimetype, album, height, width, content, os_storage, filesize, imgscale, photo_usage, title, description, os_path, display_path, allow_cid, allow_gid, deny_cid, deny_gid )
- VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )",
+ ( aid, uid, xchan, resource_id, created, edited, filename, mimetype, album, height, width, content, os_storage, filesize, imgscale, photo_usage, title, description, os_path, display_path, allow_cid, allow_gid, deny_cid, deny_gid, expires )
+ VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )",
intval($p['aid']),
intval($p['uid']),
dbesc($p['xchan']),
dbesc($p['resource_id']),
- dbesc($p['created']),
- dbesc($p['edited']),
+ dbescdate($p['created']),
+ dbescdate($p['edited']),
dbesc(basename($p['filename'])),
- dbesc($this->getType()),
+ dbesc($p['mimetype']),
dbesc($p['album']),
intval($p['height']),
intval($p['width']),
@@ -455,7 +459,8 @@ abstract class photo_driver {
dbesc($p['allow_cid']),
dbesc($p['allow_gid']),
dbesc($p['deny_cid']),
- dbesc($p['deny_gid'])
+ dbesc($p['deny_gid']),
+ dbescdate($p['expires'])
);
}
logger('photo save ' . $p['imgscale'] . ' returned ' . intval($r));
diff --git a/include/photo/photo_imagick.php b/include/photo/photo_imagick.php
index 89577e71e..f04c00245 100644
--- a/include/photo/photo_imagick.php
+++ b/include/photo/photo_imagick.php
@@ -31,8 +31,12 @@ class photo_imagick extends photo_driver {
if(! $data)
return;
- $this->image->readImageBlob($data);
-
+ try {
+ $this->image->readImageBlob($data);
+ }
+ catch (Exception $e) {
+ logger('imagick readImageBlob() exception:' . print_r($e,true));
+ }
/**
* Setup the image to the format it will be saved to
@@ -205,4 +209,4 @@ class photo_imagick extends photo_driver {
-} \ No newline at end of file
+}
diff --git a/include/text.php b/include/text.php
index 646bfe749..bd0d8048d 100644
--- a/include/text.php
+++ b/include/text.php
@@ -1105,23 +1105,33 @@ function linkify($s, $me = false) {
* to a local redirector which uses https and which redirects to the selected content
*
* @param string $s
+ * @param int $uid
* @returns string
*/
function sslify($s) {
+
+ // Local photo cache
+ $str = array(
+ 'body' => $s,
+ 'uid' => local_channel()
+ );
+ call_hooks('cache_body_hook', $str);
+
+ $s = $str['body'];
+
if (strpos(z_root(),'https:') === false)
return $s;
-
+
// By default we'll only sslify img tags because media files will probably choke.
// You can set sslify_everything if you want - but it will likely white-screen if it hits your php memory limit.
// The downside is that http: media files will likely be blocked by your browser
// Complain to your browser maker
$allow = get_config('system','sslify_everything');
-
- $pattern = (($allow) ? "/\<(.*?)src=\"(http\:.*?)\"(.*?)\>/" : "/\<img(.*?)src=\"(http\:.*?)\"(.*?)\>/" );
+ $pattern = (($allow) ? "/\<(.*?)src=[\"|'](http\:.*?)[\"|'](.*?)\>/" : "/\<img(.*?)src=[\"|'](http\:.*?)[\"|'](.*?)\>/" );
$matches = null;
- $cnt = preg_match_all($pattern,$s,$matches,PREG_SET_ORDER);
+ $cnt = preg_match_all($pattern, $s, $matches, PREG_SET_ORDER);
if ($cnt) {
foreach ($matches as $match) {
$filename = basename( parse_url($match[2], PHP_URL_PATH) );
@@ -3295,7 +3305,7 @@ function cleanup_bbcode($body) {
$body = preg_replace('/\[\/code\]\s*\[code\]/ism',"\n",$body);
- $body = scale_external_images($body,false);
+ $body = scale_external_images($body, false);
return $body;
}
@@ -3411,7 +3421,7 @@ function get_forum_channels($uid) {
$sql_extra = (($xf) ? " and ( xchan_hash in (" . $xf . ") or xchan_pubforum = 1 ) " : " and xchan_pubforum = 1 ");
- $r = q("select abook_id, xchan_hash, xchan_name, xchan_url, xchan_photo_s from abook left join xchan on abook_xchan = xchan_hash where xchan_deleted = 0 and abook_channel = %d and abook_pending = 0 and abook_ignored = 0 and abook_blocked = 0 and abook_archived = 0 $sql_extra order by xchan_name",
+ $r = q("select abook_id, xchan_hash, xchan_name, xchan_url, xchan_addr, xchan_photo_s from abook left join xchan on abook_xchan = xchan_hash where xchan_deleted = 0 and abook_channel = %d and abook_pending = 0 and abook_ignored = 0 and abook_blocked = 0 and abook_archived = 0 $sql_extra order by xchan_name",
intval($uid)
);
@@ -3467,6 +3477,28 @@ function print_val($v) {
}
+function array_path_exists($str,$arr) {
+
+ $ptr = $arr;
+ $search = explode('/', $str);
+
+ if($search) {
+ foreach($search as $s) {
+ if(array_key_exists($s,$ptr)) {
+ $ptr = $ptr[$s];
+ }
+ else {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ return false;
+
+}
+
+
/**
* @brief Generate a unique ID.
*
@@ -3482,3 +3514,4 @@ function new_uuid() {
return $hash;
}
+
diff --git a/install/schema_mysql.sql b/install/schema_mysql.sql
index 3e3e6fe88..49a2c476a 100644
--- a/install/schema_mysql.sql
+++ b/install/schema_mysql.sql
@@ -947,6 +947,7 @@ CREATE TABLE IF NOT EXISTS `photo` (
`resource_id` char(191) NOT NULL DEFAULT '',
`created` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
`edited` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
+ `expires` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
`title` char(191) NOT NULL DEFAULT '',
`description` text NOT NULL,
`album` char(191) NOT NULL DEFAULT '',
@@ -979,6 +980,7 @@ CREATE TABLE IF NOT EXISTS `photo` (
KEY `xchan` (`xchan`),
KEY `filesize` (`filesize`),
KEY `resource_id` (`resource_id`),
+ KEY `expires` (`expires`),
KEY `is_nsfw` (`is_nsfw`),
KEY `os_storage` (`os_storage`),
KEY `photo_usage` (`photo_usage`)
diff --git a/install/schema_postgres.sql b/install/schema_postgres.sql
index 44f98b944..1b6cab51b 100644
--- a/install/schema_postgres.sql
+++ b/install/schema_postgres.sql
@@ -928,6 +928,7 @@ CREATE TABLE "photo" (
"resource_id" text NOT NULL,
"created" timestamp NOT NULL,
"edited" timestamp NOT NULL,
+ "expires" timestamp NOT NULL,
"title" text NOT NULL,
"description" text NOT NULL,
"album" text NOT NULL,
@@ -961,6 +962,7 @@ create index "photo_aid" on photo ("aid");
create index "photo_xchan" on photo ("xchan");
create index "photo_filesize" on photo ("filesize");
create index "photo_resource_id" on photo ("resource_id");
+create index "photo_expires_idx" on photo ("expires");
create index "photo_usage" on photo ("photo_usage");
create index "photo_is_nsfw" on photo ("is_nsfw");
create index "photo_os_storage" on photo ("os_storage");
diff --git a/library/imagesloaded/imagesloaded.pkgd.min.js b/library/imagesloaded/imagesloaded.pkgd.min.js
deleted file mode 100644
index c3e71fadc..000000000
--- a/library/imagesloaded/imagesloaded.pkgd.min.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/*!
- * imagesLoaded PACKAGED v4.1.0
- * JavaScript is all like "You images are done yet or what?"
- * MIT License
- */
-
-!function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}(this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||[];return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=0,o=i[n];e=e||[];for(var r=this._onceEvents&&this._onceEvents[t];o;){var s=r&&r[o];s&&(this.off(t,o),delete r[o]),o.apply(this,e),n+=s?0:1,o=i[n]}return this}},t}),function(t,e){"use strict";"function"==typeof define&&define.amd?define(["ev-emitter/ev-emitter"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter")):t.imagesLoaded=e(t,t.EvEmitter)}(window,function(t,e){function i(t,e){for(var i in e)t[i]=e[i];return t}function n(t){var e=[];if(Array.isArray(t))e=t;else if("number"==typeof t.length)for(var i=0;i<t.length;i++)e.push(t[i]);else e.push(t);return e}function o(t,e,r){return this instanceof o?("string"==typeof t&&(t=document.querySelectorAll(t)),this.elements=n(t),this.options=i({},this.options),"function"==typeof e?r=e:i(this.options,e),r&&this.on("always",r),this.getImages(),h&&(this.jqDeferred=new h.Deferred),void setTimeout(function(){this.check()}.bind(this))):new o(t,e,r)}function r(t){this.img=t}function s(t,e){this.url=t,this.element=e,this.img=new Image}var h=t.jQuery,a=t.console;o.prototype=Object.create(e.prototype),o.prototype.options={},o.prototype.getImages=function(){this.images=[],this.elements.forEach(this.addElementImages,this)},o.prototype.addElementImages=function(t){"IMG"==t.nodeName&&this.addImage(t),this.options.background===!0&&this.addElementBackgroundImages(t);var e=t.nodeType;if(e&&d[e]){for(var i=t.querySelectorAll("img"),n=0;n<i.length;n++){var o=i[n];this.addImage(o)}if("string"==typeof this.options.background){var r=t.querySelectorAll(this.options.background);for(n=0;n<r.length;n++){var s=r[n];this.addElementBackgroundImages(s)}}}};var d={1:!0,9:!0,11:!0};return o.prototype.addElementBackgroundImages=function(t){var e=getComputedStyle(t);if(e)for(var i=/url\((['"])?(.*?)\1\)/gi,n=i.exec(e.backgroundImage);null!==n;){var o=n&&n[2];o&&this.addBackground(o,t),n=i.exec(e.backgroundImage)}},o.prototype.addImage=function(t){var e=new r(t);this.images.push(e)},o.prototype.addBackground=function(t,e){var i=new s(t,e);this.images.push(i)},o.prototype.check=function(){function t(t,i,n){setTimeout(function(){e.progress(t,i,n)})}var e=this;return this.progressedCount=0,this.hasAnyBroken=!1,this.images.length?void this.images.forEach(function(e){e.once("progress",t),e.check()}):void this.complete()},o.prototype.progress=function(t,e,i){this.progressedCount++,this.hasAnyBroken=this.hasAnyBroken||!t.isLoaded,this.emitEvent("progress",[this,t,e]),this.jqDeferred&&this.jqDeferred.notify&&this.jqDeferred.notify(this,t),this.progressedCount==this.images.length&&this.complete(),this.options.debug&&a&&a.log("progress: "+i,t,e)},o.prototype.complete=function(){var t=this.hasAnyBroken?"fail":"done";if(this.isComplete=!0,this.emitEvent(t,[this]),this.emitEvent("always",[this]),this.jqDeferred){var e=this.hasAnyBroken?"reject":"resolve";this.jqDeferred[e](this)}},r.prototype=Object.create(e.prototype),r.prototype.check=function(){var t=this.getIsImageComplete();return t?void this.confirm(0!==this.img.naturalWidth,"naturalWidth"):(this.proxyImage=new Image,this.proxyImage.addEventListener("load",this),this.proxyImage.addEventListener("error",this),this.img.addEventListener("load",this),this.img.addEventListener("error",this),void(this.proxyImage.src=this.img.src))},r.prototype.getIsImageComplete=function(){return this.img.complete&&void 0!==this.img.naturalWidth},r.prototype.confirm=function(t,e){this.isLoaded=t,this.emitEvent("progress",[this,this.img,e])},r.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},r.prototype.onload=function(){this.confirm(!0,"onload"),this.unbindEvents()},r.prototype.onerror=function(){this.confirm(!1,"onerror"),this.unbindEvents()},r.prototype.unbindEvents=function(){this.proxyImage.removeEventListener("load",this),this.proxyImage.removeEventListener("error",this),this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},s.prototype=Object.create(r.prototype),s.prototype.check=function(){this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.img.src=this.url;var t=this.getIsImageComplete();t&&(this.confirm(0!==this.img.naturalWidth,"naturalWidth"),this.unbindEvents())},s.prototype.unbindEvents=function(){this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},s.prototype.confirm=function(t,e){this.isLoaded=t,this.emitEvent("progress",[this,this.element,e])},o.makeJQueryPlugin=function(e){e=e||t.jQuery,e&&(h=e,h.fn.imagesLoaded=function(t,e){var i=new o(this,t,e);return i.jqDeferred.promise(h(this))})},o.makeJQueryPlugin(),o}); \ No newline at end of file
diff --git a/vendor/blueimp/jquery-file-upload/README.md b/vendor/blueimp/jquery-file-upload/README.md
index d2f104d5c..d9e16ed18 100644
--- a/vendor/blueimp/jquery-file-upload/README.md
+++ b/vendor/blueimp/jquery-file-upload/README.md
@@ -10,7 +10,7 @@ Supports cross-domain, chunked and resumable file uploads and client-side image
## ⚠️ Security Notice
Security related releases:
-* [v9.25.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/v9.25.1) Mitigates some [Potential vulnerabilities with PHP+ImageMagick](VULNERABILITIES.md#potential-vulnerabilities-with-php+imagemagick).
+* [v9.25.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/v9.25.1) Mitigates some [Potential vulnerabilities with PHP+ImageMagick](VULNERABILITIES.md#potential-vulnerabilities-with-php-imagemagick).
* [v9.24.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/v9.24.1) Fixes a [Remote code execution vulnerability in the PHP component](VULNERABILITIES.md#remote-code-execution-vulnerability-in-the-php-component).
* v[9.10.1](https://github.com/blueimp/jQuery-File-Upload/releases/tag/9.10.1) Fixes an [Open redirect vulnerability in the GAE components](VULNERABILITIES.md#open-redirect-vulnerability-in-the-gae-components).
* Commit [4175032](https://github.com/blueimp/jQuery-File-Upload/commit/41750323a464e848856dc4c5c940663498beb74a) (*fixed in all tagged releases*) Fixes a [Cross-site scripting vulnerability in the Iframe Transport](VULNERABILITIES.md#cross-site-scripting-vulnerability-in-the-iframe-transport).
diff --git a/vendor/blueimp/jquery-file-upload/SECURITY.md b/vendor/blueimp/jquery-file-upload/SECURITY.md
index db58f7dd7..86ffc163b 100644
--- a/vendor/blueimp/jquery-file-upload/SECURITY.md
+++ b/vendor/blueimp/jquery-file-upload/SECURITY.md
@@ -113,7 +113,7 @@ location ^~ /path/to/project/server/php/files {
```
## Secure image processing configurations
-The following configuration mitigates [potential image processing vulnerabilities with ImageMagick](VULNERABILITIES.md#potential-vulnerabilities-with-php+imagemagick) by limiting the attack vectors to a small subset of image types (`GIF/JPEG/PNG`).
+The following configuration mitigates [potential image processing vulnerabilities with ImageMagick](VULNERABILITIES.md#potential-vulnerabilities-with-php-imagemagick) by limiting the attack vectors to a small subset of image types (`GIF/JPEG/PNG`).
Please also consider using alternative, safer image processing libraries like [libvips](https://github.com/libvips/libvips) or [imageflow](https://github.com/imazen/imageflow).
diff --git a/vendor/blueimp/jquery-file-upload/angularjs.html b/vendor/blueimp/jquery-file-upload/angularjs.html
index 2051bbf79..e8b05e77f 100644
--- a/vendor/blueimp/jquery-file-upload/angularjs.html
+++ b/vendor/blueimp/jquery-file-upload/angularjs.html
@@ -22,7 +22,7 @@
<meta name="description" content="File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for AngularJS. Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Bootstrap styles -->
-<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
+<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Generic page styles -->
<link rel="stylesheet" href="css/style.css">
<!-- blueimp Gallery styles -->
@@ -177,8 +177,8 @@
<a class="play-pause"></a>
<ol class="indicator"></ol>
</div>
-<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
-<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
+<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" integrity="sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f" crossorigin="anonymous"></script>
+<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js" integrity="sha384-r6jjWwxAypHaESwS5an5J9dkfzwQuKVNV9FZM9B6fnt8PFuY0cVwLhV7BltCZhLy" crossorigin="anonymous"></script>
<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->
<script src="js/vendor/jquery.ui.widget.js"></script>
<!-- The Load Image plugin is included for the preview images and image resizing functionality -->
@@ -186,7 +186,7 @@
<!-- The Canvas to Blob plugin is included for image resizing functionality -->
<script src="https://blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js"></script>
<!-- Bootstrap JS is not required, but included for the responsive demo navigation -->
-<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
+<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<!-- blueimp Gallery script -->
<script src="https://blueimp.github.io/Gallery/js/jquery.blueimp-gallery.min.js"></script>
<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->
diff --git a/vendor/blueimp/jquery-file-upload/basic-plus.html b/vendor/blueimp/jquery-file-upload/basic-plus.html
index acee24843..6d53acdc1 100644
--- a/vendor/blueimp/jquery-file-upload/basic-plus.html
+++ b/vendor/blueimp/jquery-file-upload/basic-plus.html
@@ -20,7 +20,7 @@
<meta name="description" content="File Upload widget with multiple file selection, drag&amp;drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Bootstrap styles -->
-<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
+<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Generic page styles -->
<link rel="stylesheet" href="css/style.css">
<!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->
@@ -96,15 +96,15 @@
</div>
</div>
</div>
-<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
+<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" integrity="sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f" crossorigin="anonymous"></script>
<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->
<script src="js/vendor/jquery.ui.widget.js"></script>
<!-- The Load Image plugin is included for the preview images and image resizing functionality -->
-<script src="https://blueimp.github.io/JavaScript-Load-Image/js/load-image.all.min.js"></script>
+<script src="https://blueimp.github.io/JavaScript-Load-Image/js/load-image.all.min.js"></script>
<!-- The Canvas to Blob plugin is included for image resizing functionality -->
<script src="https://blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js"></script>
<!-- Bootstrap JS is not required, but included for the responsive demo navigation -->
-<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
+<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->
<script src="js/jquery.iframe-transport.js"></script>
<!-- The basic File Upload plugin -->
diff --git a/vendor/blueimp/jquery-file-upload/basic.html b/vendor/blueimp/jquery-file-upload/basic.html
index 232a24624..a9ef6273e 100644
--- a/vendor/blueimp/jquery-file-upload/basic.html
+++ b/vendor/blueimp/jquery-file-upload/basic.html
@@ -20,7 +20,7 @@
<meta name="description" content="File Upload widget with multiple file selection, drag&amp;drop support and progress bar for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Bootstrap styles -->
-<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
+<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Generic page styles -->
<link rel="stylesheet" href="css/style.css">
<!-- CSS to style the file input field as button and adjust the Bootstrap progress bars -->
@@ -96,7 +96,7 @@
</div>
</div>
</div>
-<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
+<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" integrity="sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f" crossorigin="anonymous"></script>
<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->
<script src="js/vendor/jquery.ui.widget.js"></script>
<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->
@@ -104,7 +104,7 @@
<!-- The basic File Upload plugin -->
<script src="js/jquery.fileupload.js"></script>
<!-- Bootstrap JS is not required, but included for the responsive demo navigation -->
-<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
+<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script>
/*jslint unparam: true */
/*global window, $ */
diff --git a/vendor/blueimp/jquery-file-upload/bower-version-update.js b/vendor/blueimp/jquery-file-upload/bower-version-update.js
index 09ce3927e..09ce3927e 100755..100644
--- a/vendor/blueimp/jquery-file-upload/bower-version-update.js
+++ b/vendor/blueimp/jquery-file-upload/bower-version-update.js
diff --git a/vendor/blueimp/jquery-file-upload/bower.json b/vendor/blueimp/jquery-file-upload/bower.json
index 34594a32f..2a56262a1 100644
--- a/vendor/blueimp/jquery-file-upload/bower.json
+++ b/vendor/blueimp/jquery-file-upload/bower.json
@@ -1,6 +1,6 @@
{
"name": "blueimp-file-upload",
- "version": "9.25.1",
+ "version": "9.28.0",
"title": "jQuery File Upload",
"description": "File Upload widget with multiple file selection, drag&amp;drop support, progress bar, validation and preview images.",
"keywords": [
diff --git a/vendor/blueimp/jquery-file-upload/cors/postmessage.html b/vendor/blueimp/jquery-file-upload/cors/postmessage.html
index 6a56cf0b6..381a8e0cd 100644
--- a/vendor/blueimp/jquery-file-upload/cors/postmessage.html
+++ b/vendor/blueimp/jquery-file-upload/cors/postmessage.html
@@ -15,7 +15,7 @@
<head>
<meta charset="utf-8">
<title>jQuery File Upload Plugin postMessage API</title>
-<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
+<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" integrity="sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f" crossorigin="anonymous"></script>
</head>
<body>
<script>
diff --git a/vendor/blueimp/jquery-file-upload/index.html b/vendor/blueimp/jquery-file-upload/index.html
index c8c66ad8b..37e08a7cb 100644
--- a/vendor/blueimp/jquery-file-upload/index.html
+++ b/vendor/blueimp/jquery-file-upload/index.html
@@ -22,7 +22,7 @@
<meta name="description" content="File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Bootstrap styles -->
-<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
+<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Generic page styles -->
<link rel="stylesheet" href="css/style.css">
<!-- blueimp Gallery styles -->
@@ -216,7 +216,7 @@
</tr>
{% } %}
</script>
-<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
+<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" integrity="sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f" crossorigin="anonymous"></script>
<!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included -->
<script src="js/vendor/jquery.ui.widget.js"></script>
<!-- The Templates plugin is included to render the upload/download listings -->
@@ -226,7 +226,7 @@
<!-- The Canvas to Blob plugin is included for image resizing functionality -->
<script src="https://blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js"></script>
<!-- Bootstrap JS is not required, but included for the responsive demo navigation -->
-<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
+<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<!-- blueimp Gallery script -->
<script src="https://blueimp.github.io/Gallery/js/jquery.blueimp-gallery.min.js"></script>
<!-- The Iframe Transport is required for browsers without support for XHR file uploads -->
diff --git a/vendor/blueimp/jquery-file-upload/jquery-ui.html b/vendor/blueimp/jquery-file-upload/jquery-ui.html
index 842dd4ca7..e44d41e89 100644
--- a/vendor/blueimp/jquery-file-upload/jquery-ui.html
+++ b/vendor/blueimp/jquery-file-upload/jquery-ui.html
@@ -22,7 +22,7 @@
<meta name="description" content="File Upload widget with multiple file selection, drag&amp;drop support, progress bars, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads and client-side image resizing. Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- jQuery UI styles -->
-<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/dark-hive/jquery-ui.css" id="theme">
+<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/dark-hive/jquery-ui.css" integrity="sha384-ufZtQaOYGuy/CibAC5jmelOpBu3H78Js7HrXSLo4LGccHUrGGHXt+uaTcDbio3kI" crossorigin="anonymous">
<!-- Generic page styles -->
<link rel="stylesheet" href="css/style.css">
<!-- Demo styles -->
@@ -201,8 +201,8 @@
</tr>
{% } %}
</script>
-<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
-<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
+<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" integrity="sha384-xBuQ/xzmlsLoJpyjoggmTEz8OWUFM0/RC5BsqQBDX2v5cMvDHcMakNTNrHIW2I5f" crossorigin="anonymous"></script>
+<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" integrity="sha384-Dziy8F2VlJQLMShA6FHWNul/veM9bCkRUaLqr199K94ntO5QUrLJBEbYegdSkkqX" crossorigin="anonymous"></script>
<!-- The Templates plugin is included to render the upload/download listings -->
<script src="https://blueimp.github.io/JavaScript-Templates/js/tmpl.min.js"></script>
<!-- The Load Image plugin is included for the preview images and image resizing functionality -->
diff --git a/vendor/blueimp/jquery-file-upload/package.json b/vendor/blueimp/jquery-file-upload/package.json
index 4b33a0362..0a635397c 100644
--- a/vendor/blueimp/jquery-file-upload/package.json
+++ b/vendor/blueimp/jquery-file-upload/package.json
@@ -1,6 +1,6 @@
{
"name": "blueimp-file-upload",
- "version": "9.25.1",
+ "version": "9.28.0",
"title": "jQuery File Upload",
"description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.",
"keywords": [
diff --git a/vendor/blueimp/jquery-file-upload/server/php/UploadHandler.php b/vendor/blueimp/jquery-file-upload/server/php/UploadHandler.php
index e44004395..5215e4c0f 100755..100644
--- a/vendor/blueimp/jquery-file-upload/server/php/UploadHandler.php
+++ b/vendor/blueimp/jquery-file-upload/server/php/UploadHandler.php
@@ -38,9 +38,9 @@ class UploadHandler
'image_resize' => 'Failed to resize image'
);
- protected const IMAGETYPE_GIF = 1;
- protected const IMAGETYPE_JPEG = 2;
- protected const IMAGETYPE_PNG = 3;
+ const IMAGETYPE_GIF = 1;
+ const IMAGETYPE_JPEG = 2;
+ const IMAGETYPE_PNG = 3;
protected $image_objects = array();
@@ -1047,13 +1047,18 @@ class UploadHandler
}
protected function create_scaled_image($file_name, $version, $options) {
- if ($this->options['image_library'] === 2) {
- return $this->imagemagick_create_scaled_image($file_name, $version, $options);
- }
- if ($this->options['image_library'] && extension_loaded('imagick')) {
- return $this->imagick_create_scaled_image($file_name, $version, $options);
+ try {
+ if ($this->options['image_library'] === 2) {
+ return $this->imagemagick_create_scaled_image($file_name, $version, $options);
+ }
+ if ($this->options['image_library'] && extension_loaded('imagick')) {
+ return $this->imagick_create_scaled_image($file_name, $version, $options);
+ }
+ return $this->gd_create_scaled_image($file_name, $version, $options);
+ } catch (\Exception $e) {
+ error_log($e->getMessage());
+ return false;
}
- return $this->gd_create_scaled_image($file_name, $version, $options);
}
protected function destroy_image_object($file_path) {
@@ -1066,12 +1071,12 @@ class UploadHandler
$fp = fopen($file_path, 'r');
$data = fread($fp, 4);
fclose($fp);
- // GIF: 47 49 46
- if (substr($data, 0, 3) === 'GIF') {
+ // GIF: 47 49 46 38
+ if ($data === 'GIF8') {
return self::IMAGETYPE_GIF;
}
- // JPG: FF D8
- if (bin2hex(substr($data, 0, 2)) === 'ffd8') {
+ // JPG: FF D8 FF
+ if (bin2hex(substr($data, 0, 3)) === 'ffd8ff') {
return self::IMAGETYPE_JPEG;
}
// PNG: 89 50 4E 47
@@ -1082,6 +1087,9 @@ class UploadHandler
}
protected function is_valid_image_file($file_path) {
+ if (!preg_match('/\.(gif|jpe?g|png)$/i', $file_path)) {
+ return false;
+ }
return !!$this->imagetype($file_path);
}
diff --git a/vendor/blueimp/jquery-file-upload/server/php/index.php b/vendor/blueimp/jquery-file-upload/server/php/index.php
index 9c2cfb8eb..6caabb710 100644
--- a/vendor/blueimp/jquery-file-upload/server/php/index.php
+++ b/vendor/blueimp/jquery-file-upload/server/php/index.php
@@ -9,7 +9,7 @@
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
-exit;
+
error_reporting(E_ALL | E_STRICT);
require('UploadHandler.php');
$upload_handler = new UploadHandler();
diff --git a/vendor/blueimp/jquery-file-upload/test/index.html b/vendor/blueimp/jquery-file-upload/test/index.html
index 0b5cf57b7..b8c585df5 100644
--- a/vendor/blueimp/jquery-file-upload/test/index.html
+++ b/vendor/blueimp/jquery-file-upload/test/index.html
@@ -20,7 +20,7 @@
<meta charset="utf-8">
<title>jQuery File Upload Plugin Test</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
-<link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-1.23.1.css">
+<link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-1.23.1.css" integrity="sha384-RW07PgMHO3eNYL7ddFK/okEi1rjvSeJ3Ck/TxGUHkmzSlGmw4R9/KGJYUD3OicMd" crossorigin="anonymous">
</head>
<body>
<h1 id="qunit-header">jQuery File Upload Plugin Test</h1>
@@ -145,7 +145,7 @@
</tr>
{% } %}
</script>
-<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
+<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js" integrity="sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ" crossorigin="anonymous"></script>
<script src="../js/vendor/jquery.ui.widget.js"></script>
<script src="https://blueimp.github.io/JavaScript-Templates/js/tmpl.min.js"></script>
<script src="https://blueimp.github.io/JavaScript-Load-Image/js/load-image.all.min.js"></script>
@@ -166,7 +166,7 @@ window.testBasicWidget = $.blueimp.fileupload;
/* global window, $ */
window.testUIWidget = $.blueimp.fileupload;
</script>
-<script src="https://code.jquery.com/qunit/qunit-1.23.1.js"></script>
+<script src="https://code.jquery.com/qunit/qunit-1.23.1.js" integrity="sha384-FJbPWND3tHbuhP8PhCp3Kn0bEtCxaIq+sfkmiJ+Su0jchKFnVbPQTTyPiuwqbkXa" crossorigin="anonymous"></script>
<script src="test.js"></script>
</body>
</html>
diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php
index 95f7e0978..fce8549f0 100644
--- a/vendor/composer/ClassLoader.php
+++ b/vendor/composer/ClassLoader.php
@@ -279,7 +279,7 @@ class ClassLoader
*/
public function setApcuPrefix($apcuPrefix)
{
- $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
+ $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}
/**
diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE
index f0157a6ed..f27399a04 100644
--- a/vendor/composer/LICENSE
+++ b/vendor/composer/LICENSE
@@ -1,56 +1,21 @@
-Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
-Upstream-Name: Composer
-Upstream-Contact: Jordi Boggiano <j.boggiano@seld.be>
-Source: https://github.com/composer/composer
-Files: *
-Copyright: 2016, Nils Adermann <naderman@naderman.de>
- 2016, Jordi Boggiano <j.boggiano@seld.be>
-License: Expat
+Copyright (c) Nils Adermann, Jordi Boggiano
-Files: src/Composer/Util/TlsHelper.php
-Copyright: 2016, Nils Adermann <naderman@naderman.de>
- 2016, Jordi Boggiano <j.boggiano@seld.be>
- 2013, Evan Coury <me@evancoury.com>
-License: Expat and BSD-2-Clause
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
-License: BSD-2-Clause
- Redistribution and use in source and binary forms, with or without modification,
- are permitted provided that the following conditions are met:
- .
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- .
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- .
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
-License: Expat
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is furnished
- to do so, subject to the following conditions:
- .
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
- .
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php
index f3c814e02..86acbb152 100644
--- a/vendor/composer/autoload_classmap.php
+++ b/vendor/composer/autoload_classmap.php
@@ -380,6 +380,9 @@ return array(
'Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerInterface.php',
'Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerTrait.php',
'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php',
+ 'Psr\\Log\\Test\\DummyTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
+ 'Psr\\Log\\Test\\LoggerInterfaceTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
+ 'Psr\\Log\\Test\\TestLogger' => $vendorDir . '/psr/log/Psr/Log/Test/TestLogger.php',
'Ramsey\\Uuid\\BinaryUtils' => $vendorDir . '/ramsey/uuid/src/BinaryUtils.php',
'Ramsey\\Uuid\\Builder\\DefaultUuidBuilder' => $vendorDir . '/ramsey/uuid/src/Builder/DefaultUuidBuilder.php',
'Ramsey\\Uuid\\Builder\\DegradedUuidBuilder' => $vendorDir . '/ramsey/uuid/src/Builder/DegradedUuidBuilder.php',
@@ -981,7 +984,6 @@ return array(
'Zotlabs\\Module\\Mood' => $baseDir . '/Zotlabs/Module/Mood.php',
'Zotlabs\\Module\\Network' => $baseDir . '/Zotlabs/Module/Network.php',
'Zotlabs\\Module\\New_channel' => $baseDir . '/Zotlabs/Module/New_channel.php',
- 'Zotlabs\\Module\\Nojs' => $baseDir . '/Zotlabs/Module/Nojs.php',
'Zotlabs\\Module\\Notes' => $baseDir . '/Zotlabs/Module/Notes.php',
'Zotlabs\\Module\\Notifications' => $baseDir . '/Zotlabs/Module/Notifications.php',
'Zotlabs\\Module\\Notify' => $baseDir . '/Zotlabs/Module/Notify.php',
@@ -1337,7 +1339,10 @@ return array(
'Zotlabs\\Update\\_1222' => $baseDir . '/Zotlabs/Update/_1222.php',
'Zotlabs\\Update\\_1223' => $baseDir . '/Zotlabs/Update/_1223.php',
'Zotlabs\\Update\\_1224' => $baseDir . '/Zotlabs/Update/_1224.php',
- 'Zotlabs\\Web\\CheckJS' => $baseDir . '/Zotlabs/Web/CheckJS.php',
+ 'Zotlabs\\Update\\_1225' => $baseDir . '/Zotlabs/Update/_1225.php',
+ 'Zotlabs\\Update\\_1226' => $baseDir . '/Zotlabs/Update/_1226.php',
+ 'Zotlabs\\Update\\_1227' => $baseDir . '/Zotlabs/Update/_1227.php',
+ 'Zotlabs\\Update\\_1228' => $baseDir . '/Zotlabs/Update/_1228.php',
'Zotlabs\\Web\\Controller' => $baseDir . '/Zotlabs/Web/Controller.php',
'Zotlabs\\Web\\HTTPHeaders' => $baseDir . '/Zotlabs/Web/HTTPHeaders.php',
'Zotlabs\\Web\\HTTPSig' => $baseDir . '/Zotlabs/Web/HTTPSig.php',
diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php
index ce0232306..ea23de753 100644
--- a/vendor/composer/autoload_static.php
+++ b/vendor/composer/autoload_static.php
@@ -548,6 +548,9 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
'Psr\\Log\\LoggerInterface' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerInterface.php',
'Psr\\Log\\LoggerTrait' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerTrait.php',
'Psr\\Log\\NullLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/NullLogger.php',
+ 'Psr\\Log\\Test\\DummyTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
+ 'Psr\\Log\\Test\\LoggerInterfaceTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
+ 'Psr\\Log\\Test\\TestLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/TestLogger.php',
'Ramsey\\Uuid\\BinaryUtils' => __DIR__ . '/..' . '/ramsey/uuid/src/BinaryUtils.php',
'Ramsey\\Uuid\\Builder\\DefaultUuidBuilder' => __DIR__ . '/..' . '/ramsey/uuid/src/Builder/DefaultUuidBuilder.php',
'Ramsey\\Uuid\\Builder\\DegradedUuidBuilder' => __DIR__ . '/..' . '/ramsey/uuid/src/Builder/DegradedUuidBuilder.php',
@@ -1149,7 +1152,6 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
'Zotlabs\\Module\\Mood' => __DIR__ . '/../..' . '/Zotlabs/Module/Mood.php',
'Zotlabs\\Module\\Network' => __DIR__ . '/../..' . '/Zotlabs/Module/Network.php',
'Zotlabs\\Module\\New_channel' => __DIR__ . '/../..' . '/Zotlabs/Module/New_channel.php',
- 'Zotlabs\\Module\\Nojs' => __DIR__ . '/../..' . '/Zotlabs/Module/Nojs.php',
'Zotlabs\\Module\\Notes' => __DIR__ . '/../..' . '/Zotlabs/Module/Notes.php',
'Zotlabs\\Module\\Notifications' => __DIR__ . '/../..' . '/Zotlabs/Module/Notifications.php',
'Zotlabs\\Module\\Notify' => __DIR__ . '/../..' . '/Zotlabs/Module/Notify.php',
@@ -1506,7 +1508,9 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
'Zotlabs\\Update\\_1223' => __DIR__ . '/../..' . '/Zotlabs/Update/_1223.php',
'Zotlabs\\Update\\_1224' => __DIR__ . '/../..' . '/Zotlabs/Update/_1224.php',
'Zotlabs\\Update\\_1225' => __DIR__ . '/../..' . '/Zotlabs/Update/_1225.php',
- 'Zotlabs\\Web\\CheckJS' => __DIR__ . '/../..' . '/Zotlabs/Web/CheckJS.php',
+ 'Zotlabs\\Update\\_1226' => __DIR__ . '/../..' . '/Zotlabs/Update/_1226.php',
+ 'Zotlabs\\Update\\_1227' => __DIR__ . '/../..' . '/Zotlabs/Update/_1227.php',
+ 'Zotlabs\\Update\\_1228' => __DIR__ . '/../..' . '/Zotlabs/Update/_1228.php',
'Zotlabs\\Web\\Controller' => __DIR__ . '/../..' . '/Zotlabs/Web/Controller.php',
'Zotlabs\\Web\\HTTPHeaders' => __DIR__ . '/../..' . '/Zotlabs/Web/HTTPHeaders.php',
'Zotlabs\\Web\\HTTPSig' => __DIR__ . '/../..' . '/Zotlabs/Web/HTTPSig.php',
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index af845828e..d2f86ea99 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -1,20 +1,20 @@
[
{
"name": "blueimp/jquery-file-upload",
- "version": "v9.25.1",
- "version_normalized": "9.25.1.0",
+ "version": "v9.28.0",
+ "version_normalized": "9.28.0.0",
"source": {
"type": "git",
"url": "https://github.com/vkhramtsov/jQuery-File-Upload.git",
- "reference": "28891f9b2bc339bcc1ca8d548e5401e8563bf04b"
+ "reference": "ff5accfe2e5c4a522777faa980a90cf86a636d1d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/vkhramtsov/jQuery-File-Upload/zipball/28891f9b2bc339bcc1ca8d548e5401e8563bf04b",
- "reference": "28891f9b2bc339bcc1ca8d548e5401e8563bf04b",
+ "url": "https://api.github.com/repos/vkhramtsov/jQuery-File-Upload/zipball/ff5accfe2e5c4a522777faa980a90cf86a636d1d",
+ "reference": "ff5accfe2e5c4a522777faa980a90cf86a636d1d",
"shasum": ""
},
- "time": "2018-10-26T07:21:48+00:00",
+ "time": "2018-11-13T05:41:39+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -163,6 +163,47 @@
"description": "Internationalization library powered by CLDR data."
},
{
+ "name": "desandro/imagesloaded",
+ "version": "v4.1.4",
+ "version_normalized": "4.1.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/desandro/imagesloaded.git",
+ "reference": "67c4e57453120935180c45c6820e7d3fbd2ea1f9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/desandro/imagesloaded/zipball/67c4e57453120935180c45c6820e7d3fbd2ea1f9",
+ "reference": "67c4e57453120935180c45c6820e7d3fbd2ea1f9",
+ "shasum": ""
+ },
+ "time": "2018-01-02T16:53:35+00:00",
+ "type": "component",
+ "installation-source": "dist",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "David DeSandro",
+ "homepage": "http://desandro.com/",
+ "role": "developer"
+ }
+ ],
+ "description": "JavaScript is all like _You images done yet or what?_",
+ "homepage": "http://imagesloaded.desandro.com",
+ "keywords": [
+ "dom",
+ "images",
+ "javascript",
+ "jquery-plugin",
+ "library",
+ "loaded",
+ "ui"
+ ]
+ },
+ {
"name": "ezyang/htmlpurifier",
"version": "v4.10.0",
"version_normalized": "4.10.0.0",
@@ -457,23 +498,23 @@
},
{
"name": "psr/log",
- "version": "1.0.2",
- "version_normalized": "1.0.2.0",
+ "version": "1.1.0",
+ "version_normalized": "1.1.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
- "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
+ "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
- "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
+ "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
- "time": "2016-10-10T12:19:37+00:00",
+ "time": "2018-11-20T15:27:04+00:00",
"type": "library",
"extra": {
"branch-alias": {
@@ -1141,8 +1182,8 @@
},
{
"name": "symfony/polyfill-ctype",
- "version": "v1.9.0",
- "version_normalized": "1.9.0.0",
+ "version": "v1.10.0",
+ "version_normalized": "1.10.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
diff --git a/vendor/desandro/imagesloaded/.gitignore b/vendor/desandro/imagesloaded/.gitignore
new file mode 100644
index 000000000..2486eb53d
--- /dev/null
+++ b/vendor/desandro/imagesloaded/.gitignore
@@ -0,0 +1,5 @@
+bower_components/
+node_modules/
+_site/
+build/
+package-lock.json
diff --git a/vendor/desandro/imagesloaded/.jshintrc b/vendor/desandro/imagesloaded/.jshintrc
new file mode 100644
index 000000000..78aa4af7b
--- /dev/null
+++ b/vendor/desandro/imagesloaded/.jshintrc
@@ -0,0 +1,12 @@
+{
+ "browser": true,
+ "curly": true,
+ "newcap": false,
+ "strict": true,
+ "undef": true,
+ "unused": true,
+ "globals": {
+ "imagesLoaded": false,
+ "QUnit": false
+ }
+}
diff --git a/vendor/desandro/imagesloaded/README.md b/vendor/desandro/imagesloaded/README.md
new file mode 100644
index 000000000..67b799dfd
--- /dev/null
+++ b/vendor/desandro/imagesloaded/README.md
@@ -0,0 +1,362 @@
+# imagesLoaded
+
+<p class="tagline">JavaScript is all like "You images done yet or what?"</p>
+
+[imagesloaded.desandro.com](http://imagesloaded.desandro.com)
+
+Detect when images have been loaded.
+
+## Install
+
+### Download
+
++ [imagesloaded.pkgd.min.js](https://unpkg.com/imagesloaded@4/imagesloaded.pkgd.min.js) minified
++ [imagesloaded.pkgd.js](https://unpkg.com/imagesloaded@4/imagesloaded.pkgd.js) un-minified
+
+### CDN
+
+``` html
+<script src="https://unpkg.com/imagesloaded@4/imagesloaded.pkgd.min.js"></script>
+<!-- or -->
+<script src="https://unpkg.com/imagesloaded@4/imagesloaded.pkgd.js"></script>
+```
+
+### Package managers
+
+Install via [npm](https://www.npmjs.com/package/imagesloaded): `npm install imagesloaded`
+
+Install via [Bower](http://bower.io): `bower install imagesloaded --save`
+
+## jQuery
+
+You can use imagesLoaded as a jQuery Plugin.
+
+``` js
+$('#container').imagesLoaded( function() {
+ // images have loaded
+});
+
+// options
+$('#container').imagesLoaded( {
+ // options...
+ },
+ function() {
+ // images have loaded
+ }
+);
+```
+
+`.imagesLoaded()` returns a [jQuery Deferred object](http://api.jquery.com/category/deferred-object/). This allows you to use `.always()`, `.done()`, `.fail()` and `.progress()`.
+
+``` js
+$('#container').imagesLoaded()
+ .always( function( instance ) {
+ console.log('all images loaded');
+ })
+ .done( function( instance ) {
+ console.log('all images successfully loaded');
+ })
+ .fail( function() {
+ console.log('all images loaded, at least one is broken');
+ })
+ .progress( function( instance, image ) {
+ var result = image.isLoaded ? 'loaded' : 'broken';
+ console.log( 'image is ' + result + ' for ' + image.img.src );
+ });
+```
+
+## Vanilla JavaScript
+
+You can use imagesLoaded with vanilla JS.
+
+``` js
+imagesLoaded( elem, callback )
+// options
+imagesLoaded( elem, options, callback )
+// you can use `new` if you like
+new imagesLoaded( elem, callback )
+```
+
++ `elem` _Element, NodeList, Array, or Selector String_
++ `options` _Object_
++ `callback` _Function_ - function triggered after all images have been loaded
+
+Using a callback function is the same as binding it to the `always` event (see below).
+
+``` js
+// element
+imagesLoaded( document.querySelector('#container'), function( instance ) {
+ console.log('all images are loaded');
+});
+// selector string
+imagesLoaded( '#container', function() {...});
+// multiple elements
+var posts = document.querySelectorAll('.post');
+imagesLoaded( posts, function() {...});
+```
+
+Bind events with vanilla JS with .on(), .off(), and .once() methods.
+
+``` js
+var imgLoad = imagesLoaded( elem );
+function onAlways( instance ) {
+ console.log('all images are loaded');
+}
+// bind with .on()
+imgLoad.on( 'always', onAlways );
+// unbind with .off()
+imgLoad.off( 'always', onAlways );
+```
+
+## Background
+
+Detect when background images have loaded, in addition to `<img>`s.
+
+Set `{ background: true }` to detect when the element's background image has loaded.
+
+``` js
+// jQuery
+$('#container').imagesLoaded( { background: true }, function() {
+ console.log('#container background image loaded');
+});
+
+// vanilla JS
+imagesLoaded( '#container', { background: true }, function() {
+ console.log('#container background image loaded');
+});
+```
+
+[See jQuery demo](http://codepen.io/desandro/pen/pjVMPB) or [vanilla JS demo](http://codepen.io/desandro/pen/avKooW) on CodePen.
+
+Set to a selector string like `{ background: '.item' }` to detect when the background images of child elements have loaded.
+
+``` js
+// jQuery
+$('#container').imagesLoaded( { background: '.item' }, function() {
+ console.log('all .item background images loaded');
+});
+
+// vanilla JS
+imagesLoaded( '#container', { background: '.item' }, function() {
+ console.log('all .item background images loaded');
+});
+```
+
+[See jQuery demo](http://codepen.io/desandro/pen/avKoZL) or [vanilla JS demo](http://codepen.io/desandro/pen/vNrBGz) on CodePen.
+
+## Events
+
+### always
+
+``` js
+// jQuery
+$('#container').imagesLoaded().always( function( instance ) {
+ console.log('ALWAYS - all images have been loaded');
+});
+
+// vanilla JS
+imgLoad.on( 'always', function( instance ) {
+ console.log('ALWAYS - all images have been loaded');
+});
+```
+
+Triggered after all images have been either loaded or confirmed broken.
+
++ `instance` _imagesLoaded_ - the imagesLoaded instance
+
+### done
+
+``` js
+// jQuery
+$('#container').imagesLoaded().done( function( instance ) {
+ console.log('DONE - all images have been successfully loaded');
+});
+
+// vanilla JS
+imgLoad.on( 'done', function( instance ) {
+ console.log('DONE - all images have been successfully loaded');
+});
+```
+
+Triggered after all images have successfully loaded without any broken images.
+
+### fail
+
+``` js
+$('#container').imagesLoaded().fail( function( instance ) {
+ console.log('FAIL - all images loaded, at least one is broken');
+});
+
+// vanilla JS
+imgLoad.on( 'fail', function( instance ) {
+ console.log('FAIL - all images loaded, at least one is broken');
+});
+```
+
+Triggered after all images have been loaded with at least one broken image.
+
+### progress
+
+``` js
+imgLoad.on( 'progress', function( instance, image ) {
+ var result = image.isLoaded ? 'loaded' : 'broken';
+ console.log( 'image is ' + result + ' for ' + image.img.src );
+});
+```
+
+Triggered after each image has been loaded.
+
++ `instance` _imagesLoaded_ - the imagesLoaded instance
++ `image` _LoadingImage_ - the LoadingImage instance of the loaded image
+
+<!-- sponsored -->
+
+## Properties
+
+### LoadingImage.img
+
+_Image_ - The `img` element
+
+### LoadingImage.isLoaded
+
+_Boolean_ - `true` when the image has successfully loaded
+
+### imagesLoaded.images
+
+Array of _LoadingImage_ instances for each image detected
+
+``` js
+var imgLoad = imagesLoaded('#container');
+imgLoad.on( 'always', function() {
+ console.log( imgLoad.images.length + ' images loaded' );
+ // detect which image is broken
+ for ( var i = 0, len = imgLoad.images.length; i < len; i++ ) {
+ var image = imgLoad.images[i];
+ var result = image.isLoaded ? 'loaded' : 'broken';
+ console.log( 'image is ' + result + ' for ' + image.img.src );
+ }
+});
+```
+
+## Browserify
+
+imagesLoaded works with [Browserify](http://browserify.org/).
+
+``` bash
+npm install imagesloaded --save
+```
+
+``` js
+var imagesLoaded = require('imagesloaded');
+
+imagesLoaded( elem, function() {...} );
+```
+
+Use `.makeJQueryPlugin` to make to use `.imagesLoaded()` jQuery plugin.
+
+``` js
+var $ = require('jquery');
+var imagesLoaded = require('imagesloaded');
+
+// provide jQuery argument
+imagesLoaded.makeJQueryPlugin( $ );
+// now use .imagesLoaded() jQuery plugin
+$('#container').imagesLoaded( function() {...});
+```
+
+## Webpack
+
+Install imagesLoaded with npm.
+
+``` bash
+npm install imagesloaded
+```
+
+You can then `require('imagesloaded')`.
+
+``` js
+// main.js
+var imagesLoaded = require('imagesloaded');
+
+imagesLoaded( '#container', function() {
+ // images have loaded
+});
+```
+
+Use `.makeJQueryPlugin` to make `.imagesLoaded()` jQuery plugin.
+
+``` js
+// main.js
+var imagesLoaded = require('imagesloaded');
+var $ = require('jquery');
+
+// provide jQuery argument
+imagesLoaded.makeJQueryPlugin( $ );
+// now use .imagesLoaded() jQuery plugin
+$('#container').imagesLoaded( function() {...});
+```
+
+Run webpack.
+
+``` bash
+webpack main.js bundle.js
+```
+
+## RequireJS
+
+imagesLoaded works with [RequireJS](http://requirejs.org).
+
+You can require [imagesloaded.pkgd.js](http://imagesloaded.desandro.com/imagesloaded.pkgd.js).
+
+``` js
+requirejs( [
+ 'path/to/imagesloaded.pkgd.js',
+], function( imagesLoaded ) {
+ imagesLoaded( '#container', function() { ... });
+});
+```
+
+Use `.makeJQueryPlugin` to make `.imagesLoaded()` jQuery plugin.
+
+``` js
+requirejs( [
+ 'jquery',
+ 'path/to/imagesloaded.pkgd.js',
+], function( $, imagesLoaded ) {
+ // provide jQuery argument
+ imagesLoaded.makeJQueryPlugin( $ );
+ // now use .imagesLoaded() jQuery plugin
+ $('#container').imagesLoaded( function() {...});
+});
+```
+
+You can manage dependencies with [Bower](http://bower.io). Set `baseUrl` to `bower_components` and set a path config for all your application code.
+
+``` js
+requirejs.config({
+ baseUrl: 'bower_components/',
+ paths: { // path to your app
+ app: '../'
+ }
+});
+
+requirejs( [
+ 'imagesloaded/imagesloaded',
+ 'app/my-component.js'
+], function( imagesLoaded, myComp ) {
+ imagesLoaded( '#container', function() { ... });
+});
+```
+
+## Browser support
+
++ IE9+
++ Android 2.3+
++ iOS Safari 4+
++ All other modern browsers
+
+Use [imagesLoaded v3](http://imagesloaded.desandro.com/v3/) for IE8 support.
+
+## MIT License
+
+imagesLoaded is released under the [MIT License](http://desandro.mit-license.org/). Have at it.
diff --git a/vendor/desandro/imagesloaded/bower.json b/vendor/desandro/imagesloaded/bower.json
new file mode 100644
index 000000000..795c69f07
--- /dev/null
+++ b/vendor/desandro/imagesloaded/bower.json
@@ -0,0 +1,37 @@
+{
+ "name": "imagesloaded",
+ "description": "JavaScript is all like _You images done yet or what?_",
+ "main": "imagesloaded.js",
+ "dependencies": {
+ "ev-emitter": "^1.0.0"
+ },
+ "devDependencies": {
+ "jquery": ">=1.9 <4.0",
+ "qunit": "^2.0.0"
+ },
+ "ignore": [
+ "**/.*",
+ "test",
+ "package.json",
+ "composer.json",
+ "node_modules",
+ "bower_components",
+ "tests",
+ "sandbox/",
+ "gulpfile.js",
+ "contributing.md"
+ ],
+ "homepage": "http://imagesloaded.desandro.com",
+ "authors": [
+ "David DeSandro"
+ ],
+ "moduleType": [
+ "amd",
+ "globals",
+ "node"
+ ],
+ "keywords": [
+ "images"
+ ],
+ "license": "MIT"
+}
diff --git a/vendor/desandro/imagesloaded/composer.json b/vendor/desandro/imagesloaded/composer.json
new file mode 100644
index 000000000..95ba64c4a
--- /dev/null
+++ b/vendor/desandro/imagesloaded/composer.json
@@ -0,0 +1,15 @@
+{
+ "name": "desandro/imagesloaded",
+ "description": "JavaScript is all like _You images done yet or what?_",
+ "type": "component",
+ "keywords": ["javascript", "library", "images", "loaded", "dom", "ui", "jquery-plugin"],
+ "homepage": "http://imagesloaded.desandro.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "David DeSandro",
+ "homepage": "http://desandro.com/",
+ "role": "developer"
+ }
+ ]
+}
diff --git a/vendor/desandro/imagesloaded/contributing.md b/vendor/desandro/imagesloaded/contributing.md
new file mode 100644
index 000000000..acac280cc
--- /dev/null
+++ b/vendor/desandro/imagesloaded/contributing.md
@@ -0,0 +1,20 @@
+## Submitting issues
+
+### Reduced test case required
+
+All bug reports and problem issues require a [**reduced test case**](http://css-tricks.com/reduced-test-cases/).
+
++ A reduced test case clearly demonstrates the bug or issue.
++ It contains the bare minimum HTML, CSS, and JavaScript required to demonstrate the bug.
++ A link to your production site is **not** a reduced test case.
+
+Create a test case by forking a [CodePen demos](http://codepen.io/desandro/pens/tags/?selected_tag=imagesloaded-docs).
+
++ [progress with jQuery](http://codepen.io/desandro/pen/bIFyl)
++ [progress with vanilla JS](http://codepen.io/desandro/pen/hlzaw)
++ [`{ background: true }` with jQuery](http://codepen.io/desandro/pen/pjVMPB)
++ [`{ background: true }` with vanilla JS](http://codepen.io/desandro/pen/avKooW)
++ [`{ background: '.selector' }` with jQuery](http://codepen.io/desandro/pen/avKoZL)
++ [`{ background: '.selector' }` with vanilla JS](http://codepen.io/desandro/pen/vNrBGz)
+
+Providing a reduced test case is the best way to get your issue addressed. They help you point out the problem. They help me verify and debug the problem. They help others understand the problem. Without a reduced test case, your issue may be closed.
diff --git a/vendor/desandro/imagesloaded/gulpfile.js b/vendor/desandro/imagesloaded/gulpfile.js
new file mode 100644
index 000000000..66f775f3d
--- /dev/null
+++ b/vendor/desandro/imagesloaded/gulpfile.js
@@ -0,0 +1,128 @@
+/*jshint node: true, strict: false */
+
+var fs = require('fs');
+var gulp = require('gulp');
+var rename = require('gulp-rename');
+var replace = require('gulp-replace');
+
+// ----- hint ----- //
+
+var jshint = require('gulp-jshint');
+
+gulp.task( 'hint-js', function() {
+ return gulp.src('imagesloaded.js')
+ .pipe( jshint() )
+ .pipe( jshint.reporter('default') );
+});
+
+gulp.task( 'hint-test', function() {
+ return gulp.src('test/unit/*.js')
+ .pipe( jshint() )
+ .pipe( jshint.reporter('default') );
+});
+
+gulp.task( 'hint-task', function() {
+ return gulp.src('gulpfile.js')
+ .pipe( jshint() )
+ .pipe( jshint.reporter('default') );
+});
+
+var jsonlint = require('gulp-json-lint');
+
+gulp.task( 'jsonlint', function() {
+ return gulp.src( '*.json' )
+ .pipe( jsonlint() )
+ .pipe( jsonlint.report('verbose') );
+});
+
+gulp.task( 'hint', [ 'hint-js', 'hint-test', 'hint-task', 'jsonlint' ]);
+
+// -------------------------- RequireJS makes pkgd -------------------------- //
+
+// refactored from gulp-requirejs-optimize
+// https://www.npmjs.com/package/gulp-requirejs-optimize/
+
+var gutil = require('gulp-util');
+var chalk = require('chalk');
+var rjsOptimize = require('gulp-requirejs-optimize');
+
+// regex for banner comment
+var reBannerComment = new RegExp('^\\s*(?:\\/\\*[\\s\\S]*?\\*\\/)\\s*');
+
+function getBanner() {
+ var src = fs.readFileSync( 'imagesloaded.js', 'utf8' );
+ var matches = src.match( reBannerComment );
+ var banner = matches[0].replace( 'imagesLoaded', 'imagesLoaded PACKAGED' );
+ return banner;
+}
+
+function addBanner( str ) {
+ return replace( /^/, str );
+}
+
+gulp.task( 'requirejs', function() {
+ var banner = getBanner();
+ // HACK src is not needed
+ // should refactor rjsOptimize to produce src
+ return gulp.src('imagesloaded.js')
+ .pipe( rjsOptimize({
+ baseUrl: 'bower_components',
+ optimize: 'none',
+ include: [
+ '../imagesloaded'
+ ]
+ }) )
+ // remove named module
+ .pipe( replace( "'../imagesloaded',", '' ) )
+ // add banner
+ .pipe( addBanner( banner ) )
+ .pipe( rename('imagesloaded.pkgd.js') )
+ .pipe( gulp.dest('.') );
+});
+
+
+// ----- uglify ----- //
+
+var uglify = require('gulp-uglify');
+
+gulp.task( 'uglify', [ 'requirejs' ], function() {
+ var banner = getBanner();
+ gulp.src('imagesloaded.pkgd.js')
+ .pipe( uglify() )
+ // add banner
+ .pipe( addBanner( banner ) )
+ .pipe( rename('imagesloaded.pkgd.min.js') )
+ .pipe( gulp.dest('.') );
+});
+
+// ----- version ----- //
+
+// set version in source files
+
+var minimist = require('minimist');
+
+// use gulp version -t 1.2.3
+gulp.task( 'version', function() {
+ var args = minimist( process.argv.slice(3) );
+ var version = args.t;
+ if ( !version || !/\d+\.\d+\.\d+/.test( version ) ) {
+ gutil.log( 'invalid version: ' + chalk.red( version ) );
+ return;
+ }
+ gutil.log( 'ticking version to ' + chalk.green( version ) );
+
+ gulp.src('imagesloaded.js')
+ .pipe( replace( /imagesLoaded v\d+\.\d+\.\d+/, 'imagesLoaded v' + version ) )
+ .pipe( gulp.dest('.') );
+
+ gulp.src( [ 'bower.json', 'package.json' ] )
+ .pipe( replace( /"version": "\d+\.\d+\.\d+"/, '"version": "' + version + '"' ) )
+ .pipe( gulp.dest('.') );
+});
+
+// ----- default ----- //
+
+gulp.task( 'default', [
+ 'hint',
+ 'uglify'
+]);
diff --git a/vendor/desandro/imagesloaded/imagesloaded.js b/vendor/desandro/imagesloaded/imagesloaded.js
new file mode 100644
index 000000000..f527a71e9
--- /dev/null
+++ b/vendor/desandro/imagesloaded/imagesloaded.js
@@ -0,0 +1,377 @@
+/*!
+ * imagesLoaded v4.1.4
+ * JavaScript is all like "You images are done yet or what?"
+ * MIT License
+ */
+
+( function( window, factory ) { 'use strict';
+ // universal module definition
+
+ /*global define: false, module: false, require: false */
+
+ if ( typeof define == 'function' && define.amd ) {
+ // AMD
+ define( [
+ 'ev-emitter/ev-emitter'
+ ], function( EvEmitter ) {
+ return factory( window, EvEmitter );
+ });
+ } else if ( typeof module == 'object' && module.exports ) {
+ // CommonJS
+ module.exports = factory(
+ window,
+ require('ev-emitter')
+ );
+ } else {
+ // browser global
+ window.imagesLoaded = factory(
+ window,
+ window.EvEmitter
+ );
+ }
+
+})( typeof window !== 'undefined' ? window : this,
+
+// -------------------------- factory -------------------------- //
+
+function factory( window, EvEmitter ) {
+
+'use strict';
+
+var $ = window.jQuery;
+var console = window.console;
+
+// -------------------------- helpers -------------------------- //
+
+// extend objects
+function extend( a, b ) {
+ for ( var prop in b ) {
+ a[ prop ] = b[ prop ];
+ }
+ return a;
+}
+
+var arraySlice = Array.prototype.slice;
+
+// turn element or nodeList into an array
+function makeArray( obj ) {
+ if ( Array.isArray( obj ) ) {
+ // use object if already an array
+ return obj;
+ }
+
+ var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
+ if ( isArrayLike ) {
+ // convert nodeList to array
+ return arraySlice.call( obj );
+ }
+
+ // array of single index
+ return [ obj ];
+}
+
+// -------------------------- imagesLoaded -------------------------- //
+
+/**
+ * @param {Array, Element, NodeList, String} elem
+ * @param {Object or Function} options - if function, use as callback
+ * @param {Function} onAlways - callback function
+ */
+function ImagesLoaded( elem, options, onAlways ) {
+ // coerce ImagesLoaded() without new, to be new ImagesLoaded()
+ if ( !( this instanceof ImagesLoaded ) ) {
+ return new ImagesLoaded( elem, options, onAlways );
+ }
+ // use elem as selector string
+ var queryElem = elem;
+ if ( typeof elem == 'string' ) {
+ queryElem = document.querySelectorAll( elem );
+ }
+ // bail if bad element
+ if ( !queryElem ) {
+ console.error( 'Bad element for imagesLoaded ' + ( queryElem || elem ) );
+ return;
+ }
+
+ this.elements = makeArray( queryElem );
+ this.options = extend( {}, this.options );
+ // shift arguments if no options set
+ if ( typeof options == 'function' ) {
+ onAlways = options;
+ } else {
+ extend( this.options, options );
+ }
+
+ if ( onAlways ) {
+ this.on( 'always', onAlways );
+ }
+
+ this.getImages();
+
+ if ( $ ) {
+ // add jQuery Deferred object
+ this.jqDeferred = new $.Deferred();
+ }
+
+ // HACK check async to allow time to bind listeners
+ setTimeout( this.check.bind( this ) );
+}
+
+ImagesLoaded.prototype = Object.create( EvEmitter.prototype );
+
+ImagesLoaded.prototype.options = {};
+
+ImagesLoaded.prototype.getImages = function() {
+ this.images = [];
+
+ // filter & find items if we have an item selector
+ this.elements.forEach( this.addElementImages, this );
+};
+
+/**
+ * @param {Node} element
+ */
+ImagesLoaded.prototype.addElementImages = function( elem ) {
+ // filter siblings
+ if ( elem.nodeName == 'IMG' ) {
+ this.addImage( elem );
+ }
+ // get background image on element
+ if ( this.options.background === true ) {
+ this.addElementBackgroundImages( elem );
+ }
+
+ // find children
+ // no non-element nodes, #143
+ var nodeType = elem.nodeType;
+ if ( !nodeType || !elementNodeTypes[ nodeType ] ) {
+ return;
+ }
+ var childImgs = elem.querySelectorAll('img');
+ // concat childElems to filterFound array
+ for ( var i=0; i < childImgs.length; i++ ) {
+ var img = childImgs[i];
+ this.addImage( img );
+ }
+
+ // get child background images
+ if ( typeof this.options.background == 'string' ) {
+ var children = elem.querySelectorAll( this.options.background );
+ for ( i=0; i < children.length; i++ ) {
+ var child = children[i];
+ this.addElementBackgroundImages( child );
+ }
+ }
+};
+
+var elementNodeTypes = {
+ 1: true,
+ 9: true,
+ 11: true
+};
+
+ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {
+ var style = getComputedStyle( elem );
+ if ( !style ) {
+ // Firefox returns null if in a hidden iframe https://bugzil.la/548397
+ return;
+ }
+ // get url inside url("...")
+ var reURL = /url\((['"])?(.*?)\1\)/gi;
+ var matches = reURL.exec( style.backgroundImage );
+ while ( matches !== null ) {
+ var url = matches && matches[2];
+ if ( url ) {
+ this.addBackground( url, elem );
+ }
+ matches = reURL.exec( style.backgroundImage );
+ }
+};
+
+/**
+ * @param {Image} img
+ */
+ImagesLoaded.prototype.addImage = function( img ) {
+ var loadingImage = new LoadingImage( img );
+ this.images.push( loadingImage );
+};
+
+ImagesLoaded.prototype.addBackground = function( url, elem ) {
+ var background = new Background( url, elem );
+ this.images.push( background );
+};
+
+ImagesLoaded.prototype.check = function() {
+ var _this = this;
+ this.progressedCount = 0;
+ this.hasAnyBroken = false;
+ // complete if no images
+ if ( !this.images.length ) {
+ this.complete();
+ return;
+ }
+
+ function onProgress( image, elem, message ) {
+ // HACK - Chrome triggers event before object properties have changed. #83
+ setTimeout( function() {
+ _this.progress( image, elem, message );
+ });
+ }
+
+ this.images.forEach( function( loadingImage ) {
+ loadingImage.once( 'progress', onProgress );
+ loadingImage.check();
+ });
+};
+
+ImagesLoaded.prototype.progress = function( image, elem, message ) {
+ this.progressedCount++;
+ this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
+ // progress event
+ this.emitEvent( 'progress', [ this, image, elem ] );
+ if ( this.jqDeferred && this.jqDeferred.notify ) {
+ this.jqDeferred.notify( this, image );
+ }
+ // check if completed
+ if ( this.progressedCount == this.images.length ) {
+ this.complete();
+ }
+
+ if ( this.options.debug && console ) {
+ console.log( 'progress: ' + message, image, elem );
+ }
+};
+
+ImagesLoaded.prototype.complete = function() {
+ var eventName = this.hasAnyBroken ? 'fail' : 'done';
+ this.isComplete = true;
+ this.emitEvent( eventName, [ this ] );
+ this.emitEvent( 'always', [ this ] );
+ if ( this.jqDeferred ) {
+ var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';
+ this.jqDeferred[ jqMethod ]( this );
+ }
+};
+
+// -------------------------- -------------------------- //
+
+function LoadingImage( img ) {
+ this.img = img;
+}
+
+LoadingImage.prototype = Object.create( EvEmitter.prototype );
+
+LoadingImage.prototype.check = function() {
+ // If complete is true and browser supports natural sizes,
+ // try to check for image status manually.
+ var isComplete = this.getIsImageComplete();
+ if ( isComplete ) {
+ // report based on naturalWidth
+ this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
+ return;
+ }
+
+ // If none of the checks above matched, simulate loading on detached element.
+ this.proxyImage = new Image();
+ this.proxyImage.addEventListener( 'load', this );
+ this.proxyImage.addEventListener( 'error', this );
+ // bind to image as well for Firefox. #191
+ this.img.addEventListener( 'load', this );
+ this.img.addEventListener( 'error', this );
+ this.proxyImage.src = this.img.src;
+};
+
+LoadingImage.prototype.getIsImageComplete = function() {
+ // check for non-zero, non-undefined naturalWidth
+ // fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671
+ return this.img.complete && this.img.naturalWidth;
+};
+
+LoadingImage.prototype.confirm = function( isLoaded, message ) {
+ this.isLoaded = isLoaded;
+ this.emitEvent( 'progress', [ this, this.img, message ] );
+};
+
+// ----- events ----- //
+
+// trigger specified handler for event type
+LoadingImage.prototype.handleEvent = function( event ) {
+ var method = 'on' + event.type;
+ if ( this[ method ] ) {
+ this[ method ]( event );
+ }
+};
+
+LoadingImage.prototype.onload = function() {
+ this.confirm( true, 'onload' );
+ this.unbindEvents();
+};
+
+LoadingImage.prototype.onerror = function() {
+ this.confirm( false, 'onerror' );
+ this.unbindEvents();
+};
+
+LoadingImage.prototype.unbindEvents = function() {
+ this.proxyImage.removeEventListener( 'load', this );
+ this.proxyImage.removeEventListener( 'error', this );
+ this.img.removeEventListener( 'load', this );
+ this.img.removeEventListener( 'error', this );
+};
+
+// -------------------------- Background -------------------------- //
+
+function Background( url, element ) {
+ this.url = url;
+ this.element = element;
+ this.img = new Image();
+}
+
+// inherit LoadingImage prototype
+Background.prototype = Object.create( LoadingImage.prototype );
+
+Background.prototype.check = function() {
+ this.img.addEventListener( 'load', this );
+ this.img.addEventListener( 'error', this );
+ this.img.src = this.url;
+ // check if image is already complete
+ var isComplete = this.getIsImageComplete();
+ if ( isComplete ) {
+ this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
+ this.unbindEvents();
+ }
+};
+
+Background.prototype.unbindEvents = function() {
+ this.img.removeEventListener( 'load', this );
+ this.img.removeEventListener( 'error', this );
+};
+
+Background.prototype.confirm = function( isLoaded, message ) {
+ this.isLoaded = isLoaded;
+ this.emitEvent( 'progress', [ this, this.element, message ] );
+};
+
+// -------------------------- jQuery -------------------------- //
+
+ImagesLoaded.makeJQueryPlugin = function( jQuery ) {
+ jQuery = jQuery || window.jQuery;
+ if ( !jQuery ) {
+ return;
+ }
+ // set local variable
+ $ = jQuery;
+ // $().imagesLoaded()
+ $.fn.imagesLoaded = function( options, callback ) {
+ var instance = new ImagesLoaded( this, options, callback );
+ return instance.jqDeferred.promise( $(this) );
+ };
+};
+// try making plugin
+ImagesLoaded.makeJQueryPlugin();
+
+// -------------------------- -------------------------- //
+
+return ImagesLoaded;
+
+});
diff --git a/library/imagesloaded/imagesloaded.pkgd.js b/vendor/desandro/imagesloaded/imagesloaded.pkgd.js
index ef23971be..a230750b3 100644
--- a/library/imagesloaded/imagesloaded.pkgd.js
+++ b/vendor/desandro/imagesloaded/imagesloaded.pkgd.js
@@ -1,11 +1,11 @@
/*!
- * imagesLoaded PACKAGED v4.1.0
+ * imagesLoaded PACKAGED v4.1.4
* JavaScript is all like "You images are done yet or what?"
* MIT License
*/
/**
- * EvEmitter v1.0.1
+ * EvEmitter v1.1.0
* Lil' event emitter
* MIT License
*/
@@ -14,7 +14,7 @@
( function( global, factory ) {
// universal module definition
- /* jshint strict: false */ /* globals define, module */
+ /* jshint strict: false */ /* globals define, module, window */
if ( typeof define == 'function' && define.amd ) {
// AMD - RequireJS
define( 'ev-emitter/ev-emitter',factory );
@@ -26,7 +26,7 @@
global.EvEmitter = factory();
}
-}( this, function() {
+}( typeof window != 'undefined' ? window : this, function() {
@@ -59,8 +59,8 @@ proto.once = function( eventName, listener ) {
// set once flag
// set onceEvents hash
var onceEvents = this._onceEvents = this._onceEvents || {};
- // set onceListeners array
- var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || [];
+ // set onceListeners object
+ var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
// set flag
onceListeners[ listener ] = true;
@@ -85,13 +85,14 @@ proto.emitEvent = function( eventName, args ) {
if ( !listeners || !listeners.length ) {
return;
}
- var i = 0;
- var listener = listeners[i];
+ // copy over to avoid interference if .off() in listener
+ listeners = listeners.slice(0);
args = args || [];
// once stuff
var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
- while ( listener ) {
+ for ( var i=0; i < listeners.length; i++ ) {
+ var listener = listeners[i]
var isOnce = onceListeners && onceListeners[ listener ];
if ( isOnce ) {
// remove listener
@@ -102,20 +103,22 @@ proto.emitEvent = function( eventName, args ) {
}
// trigger listener
listener.apply( this, args );
- // get next listener
- i += isOnce ? 0 : 1;
- listener = listeners[i];
}
return this;
};
+proto.allOff = function() {
+ delete this._events;
+ delete this._onceEvents;
+};
+
return EvEmitter;
}));
/*!
- * imagesLoaded v4.1.0
+ * imagesLoaded v4.1.4
* JavaScript is all like "You images are done yet or what?"
* MIT License
*/
@@ -146,7 +149,7 @@ return EvEmitter;
);
}
-})( window,
+})( typeof window !== 'undefined' ? window : this,
// -------------------------- factory -------------------------- //
@@ -167,22 +170,23 @@ function extend( a, b ) {
return a;
}
+var arraySlice = Array.prototype.slice;
+
// turn element or nodeList into an array
function makeArray( obj ) {
- var ary = [];
if ( Array.isArray( obj ) ) {
// use object if already an array
- ary = obj;
- } else if ( typeof obj.length == 'number' ) {
+ return obj;
+ }
+
+ var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
+ if ( isArrayLike ) {
// convert nodeList to array
- for ( var i=0; i < obj.length; i++ ) {
- ary.push( obj[i] );
- }
- } else {
- // array of single index
- ary.push( obj );
+ return arraySlice.call( obj );
}
- return ary;
+
+ // array of single index
+ return [ obj ];
}
// -------------------------- imagesLoaded -------------------------- //
@@ -198,13 +202,19 @@ function ImagesLoaded( elem, options, onAlways ) {
return new ImagesLoaded( elem, options, onAlways );
}
// use elem as selector string
+ var queryElem = elem;
if ( typeof elem == 'string' ) {
- elem = document.querySelectorAll( elem );
+ queryElem = document.querySelectorAll( elem );
+ }
+ // bail if bad element
+ if ( !queryElem ) {
+ console.error( 'Bad element for imagesLoaded ' + ( queryElem || elem ) );
+ return;
}
- this.elements = makeArray( elem );
+ this.elements = makeArray( queryElem );
this.options = extend( {}, this.options );
-
+ // shift arguments if no options set
if ( typeof options == 'function' ) {
onAlways = options;
} else {
@@ -223,9 +233,7 @@ function ImagesLoaded( elem, options, onAlways ) {
}
// HACK check async to allow time to bind listeners
- setTimeout( function() {
- this.check();
- }.bind( this ));
+ setTimeout( this.check.bind( this ) );
}
ImagesLoaded.prototype = Object.create( EvEmitter.prototype );
@@ -393,7 +401,9 @@ LoadingImage.prototype.check = function() {
};
LoadingImage.prototype.getIsImageComplete = function() {
- return this.img.complete && this.img.naturalWidth !== undefined;
+ // check for non-zero, non-undefined naturalWidth
+ // fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671
+ return this.img.complete && this.img.naturalWidth;
};
LoadingImage.prototype.confirm = function( isLoaded, message ) {
diff --git a/vendor/desandro/imagesloaded/imagesloaded.pkgd.min.js b/vendor/desandro/imagesloaded/imagesloaded.pkgd.min.js
new file mode 100644
index 000000000..e443a77d6
--- /dev/null
+++ b/vendor/desandro/imagesloaded/imagesloaded.pkgd.min.js
@@ -0,0 +1,7 @@
+/*!
+ * imagesLoaded PACKAGED v4.1.4
+ * JavaScript is all like "You images are done yet or what?"
+ * MIT License
+ */
+
+!function(e,t){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",t):"object"==typeof module&&module.exports?module.exports=t():e.EvEmitter=t()}("undefined"!=typeof window?window:this,function(){function e(){}var t=e.prototype;return t.on=function(e,t){if(e&&t){var i=this._events=this._events||{},n=i[e]=i[e]||[];return n.indexOf(t)==-1&&n.push(t),this}},t.once=function(e,t){if(e&&t){this.on(e,t);var i=this._onceEvents=this._onceEvents||{},n=i[e]=i[e]||{};return n[t]=!0,this}},t.off=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){var n=i.indexOf(t);return n!=-1&&i.splice(n,1),this}},t.emitEvent=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){i=i.slice(0),t=t||[];for(var n=this._onceEvents&&this._onceEvents[e],o=0;o<i.length;o++){var r=i[o],s=n&&n[r];s&&(this.off(e,r),delete n[r]),r.apply(this,t)}return this}},t.allOff=function(){delete this._events,delete this._onceEvents},e}),function(e,t){"use strict";"function"==typeof define&&define.amd?define(["ev-emitter/ev-emitter"],function(i){return t(e,i)}):"object"==typeof module&&module.exports?module.exports=t(e,require("ev-emitter")):e.imagesLoaded=t(e,e.EvEmitter)}("undefined"!=typeof window?window:this,function(e,t){function i(e,t){for(var i in t)e[i]=t[i];return e}function n(e){if(Array.isArray(e))return e;var t="object"==typeof e&&"number"==typeof e.length;return t?d.call(e):[e]}function o(e,t,r){if(!(this instanceof o))return new o(e,t,r);var s=e;return"string"==typeof e&&(s=document.querySelectorAll(e)),s?(this.elements=n(s),this.options=i({},this.options),"function"==typeof t?r=t:i(this.options,t),r&&this.on("always",r),this.getImages(),h&&(this.jqDeferred=new h.Deferred),void setTimeout(this.check.bind(this))):void a.error("Bad element for imagesLoaded "+(s||e))}function r(e){this.img=e}function s(e,t){this.url=e,this.element=t,this.img=new Image}var h=e.jQuery,a=e.console,d=Array.prototype.slice;o.prototype=Object.create(t.prototype),o.prototype.options={},o.prototype.getImages=function(){this.images=[],this.elements.forEach(this.addElementImages,this)},o.prototype.addElementImages=function(e){"IMG"==e.nodeName&&this.addImage(e),this.options.background===!0&&this.addElementBackgroundImages(e);var t=e.nodeType;if(t&&u[t]){for(var i=e.querySelectorAll("img"),n=0;n<i.length;n++){var o=i[n];this.addImage(o)}if("string"==typeof this.options.background){var r=e.querySelectorAll(this.options.background);for(n=0;n<r.length;n++){var s=r[n];this.addElementBackgroundImages(s)}}}};var u={1:!0,9:!0,11:!0};return o.prototype.addElementBackgroundImages=function(e){var t=getComputedStyle(e);if(t)for(var i=/url\((['"])?(.*?)\1\)/gi,n=i.exec(t.backgroundImage);null!==n;){var o=n&&n[2];o&&this.addBackground(o,e),n=i.exec(t.backgroundImage)}},o.prototype.addImage=function(e){var t=new r(e);this.images.push(t)},o.prototype.addBackground=function(e,t){var i=new s(e,t);this.images.push(i)},o.prototype.check=function(){function e(e,i,n){setTimeout(function(){t.progress(e,i,n)})}var t=this;return this.progressedCount=0,this.hasAnyBroken=!1,this.images.length?void this.images.forEach(function(t){t.once("progress",e),t.check()}):void this.complete()},o.prototype.progress=function(e,t,i){this.progressedCount++,this.hasAnyBroken=this.hasAnyBroken||!e.isLoaded,this.emitEvent("progress",[this,e,t]),this.jqDeferred&&this.jqDeferred.notify&&this.jqDeferred.notify(this,e),this.progressedCount==this.images.length&&this.complete(),this.options.debug&&a&&a.log("progress: "+i,e,t)},o.prototype.complete=function(){var e=this.hasAnyBroken?"fail":"done";if(this.isComplete=!0,this.emitEvent(e,[this]),this.emitEvent("always",[this]),this.jqDeferred){var t=this.hasAnyBroken?"reject":"resolve";this.jqDeferred[t](this)}},r.prototype=Object.create(t.prototype),r.prototype.check=function(){var e=this.getIsImageComplete();return e?void this.confirm(0!==this.img.naturalWidth,"naturalWidth"):(this.proxyImage=new Image,this.proxyImage.addEventListener("load",this),this.proxyImage.addEventListener("error",this),this.img.addEventListener("load",this),this.img.addEventListener("error",this),void(this.proxyImage.src=this.img.src))},r.prototype.getIsImageComplete=function(){return this.img.complete&&this.img.naturalWidth},r.prototype.confirm=function(e,t){this.isLoaded=e,this.emitEvent("progress",[this,this.img,t])},r.prototype.handleEvent=function(e){var t="on"+e.type;this[t]&&this[t](e)},r.prototype.onload=function(){this.confirm(!0,"onload"),this.unbindEvents()},r.prototype.onerror=function(){this.confirm(!1,"onerror"),this.unbindEvents()},r.prototype.unbindEvents=function(){this.proxyImage.removeEventListener("load",this),this.proxyImage.removeEventListener("error",this),this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},s.prototype=Object.create(r.prototype),s.prototype.check=function(){this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.img.src=this.url;var e=this.getIsImageComplete();e&&(this.confirm(0!==this.img.naturalWidth,"naturalWidth"),this.unbindEvents())},s.prototype.unbindEvents=function(){this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},s.prototype.confirm=function(e,t){this.isLoaded=e,this.emitEvent("progress",[this,this.element,t])},o.makeJQueryPlugin=function(t){t=t||e.jQuery,t&&(h=t,h.fn.imagesLoaded=function(e,t){var i=new o(this,e,t);return i.jqDeferred.promise(h(this))})},o.makeJQueryPlugin(),o}); \ No newline at end of file
diff --git a/vendor/desandro/imagesloaded/package.json b/vendor/desandro/imagesloaded/package.json
new file mode 100644
index 000000000..ced516d8e
--- /dev/null
+++ b/vendor/desandro/imagesloaded/package.json
@@ -0,0 +1,48 @@
+{
+ "name": "imagesloaded",
+ "version": "4.1.4",
+ "description": "JavaScript is all like _You images done yet or what?_",
+ "main": "imagesloaded.js",
+ "dependencies": {
+ "ev-emitter": "^1.0.0"
+ },
+ "devDependencies": {
+ "chalk": "^1.1.1",
+ "cheerio": "^0.19.0",
+ "gulp": "^3.9.0",
+ "gulp-jshint": "^1.11.2",
+ "gulp-json-lint": "^0.1.0",
+ "gulp-rename": "^1.2.2",
+ "gulp-replace": "^0.5.4",
+ "gulp-requirejs-optimize": "github:metafizzy/gulp-requirejs-optimize",
+ "gulp-uglify": "^1.4.2",
+ "gulp-util": "^3.0.7",
+ "highlight.js": "^8.9.1",
+ "marked": "^0.3.5",
+ "minimist": "^1.2.0",
+ "transfob": "^1.0.0"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/desandro/imagesloaded.git"
+ },
+ "keywords": [
+ "images",
+ "loaded",
+ "ui",
+ "dom",
+ "jquery-plugin"
+ ],
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/desandro/imagesloaded/issues"
+ },
+ "homepage": "https://github.com/desandro/imagesloaded",
+ "directories": {
+ "test": "test"
+ },
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "David DeSandro"
+}
diff --git a/vendor/desandro/imagesloaded/sandbox/background/css/background.css b/vendor/desandro/imagesloaded/sandbox/background/css/background.css
new file mode 100644
index 000000000..509966a7d
--- /dev/null
+++ b/vendor/desandro/imagesloaded/sandbox/background/css/background.css
@@ -0,0 +1,29 @@
+.box {
+ width: 300px;
+ height: 300px;
+ margin: 0 20px 20px 0;
+ border: 1px solid;
+ display: inline-block;
+}
+
+.orange-tree {
+ background: url('http://i.imgur.com/bwy74ok.jpg');
+ background-size: cover;
+}
+
+.thunder-cloud {
+ background: url('../../../test/img/thunder-cloud.jpg');
+ background-size: contain;
+}
+
+.multi1 {
+ background:
+ url("http://i.imgur.com/ZAVN3.png"),
+ url('http://i.imgur.com/6UdOxeB.png') bottom right,
+ url(http://i.imgur.com/LkmcILl.jpg);
+ background-size: cover;
+}
+
+.blue {
+ background: #09F;
+} \ No newline at end of file
diff --git a/vendor/desandro/imagesloaded/sandbox/background/index.html b/vendor/desandro/imagesloaded/sandbox/background/index.html
new file mode 100644
index 000000000..853f8ff35
--- /dev/null
+++ b/vendor/desandro/imagesloaded/sandbox/background/index.html
@@ -0,0 +1,51 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width" />
+
+ <title>background</title>
+
+ <!-- put in separate folder so JS path is different from CSS path -->
+ <link rel="stylesheet" href="css/background.css" >
+
+</head>
+<body>
+
+ <h1>background</h1>
+
+<div class="box orange-tree"></div>
+
+<div class="box thunder-cloud"></div>
+
+<div class="box multi1"></div>
+
+<div class="box blue"></div>
+
+<script src="../../bower_components/ev-emitter/ev-emitter.js"></script>
+<script src="../../imagesloaded.js"></script>
+<script>
+
+var imgLoad0 = imagesLoaded( '.orange-tree', { background: true }, function() {
+ console.log('orange tree bg images loaded', imgLoad0.images.length );
+});
+
+var imgLoad1 = imagesLoaded( '.thunder-cloud', { background: true }, function() {
+ console.log('thunder cloud bg images loaded', imgLoad1.images.length);
+});
+
+var imgLoad2 = imagesLoaded( '.multi1', { background: true }, function() {
+ console.log('multi1 bg images loaded', imgLoad2.images.length);
+});
+
+var imgLoad3 = imagesLoaded( '.box', { background: true }, function() {
+ console.log('.box bg images loaded', imgLoad3.images.length);
+});
+imgLoad3.on('progress', function( instance, image, element ) {
+ console.log( 'progress on .box', image.img.src, element.className );
+});
+
+</script>
+
+</body>
+</html>
diff --git a/vendor/desandro/imagesloaded/sandbox/progress/index.html b/vendor/desandro/imagesloaded/sandbox/progress/index.html
new file mode 100644
index 000000000..b01ce28c5
--- /dev/null
+++ b/vendor/desandro/imagesloaded/sandbox/progress/index.html
@@ -0,0 +1,89 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width" />
+
+ <title>progress</title>
+
+ <style>
+ #image-container img {
+ max-height: 140px;
+ }
+
+ li {
+ height: 140px;
+ min-width: 100px;
+ display: block;
+ float: left;
+ list-style: none;
+ margin: 0 5px 5px 0;
+ background-color: black;
+ background-position: center center;
+ background-repeat: no-repeat;
+ }
+
+ li img,
+ #status {
+ -webkit-transition: opacity 0.4s;
+ -moz-transition: opacity 0.4s;
+ -ms-transition: opacity 0.4s;
+ transition: opacity 0.4s;
+ }
+
+ li.is-loading {
+ background-color: black;
+ background-image: url('http://desandro.github.io/imagesloaded/assets/loading.gif');
+ }
+
+ li.is-broken {
+ background-image: url('http://desandro.github.io/imagesloaded/assets/broken.png');
+ background-color: #be3730;
+ width: 120px;
+ }
+
+ li.is-loading img,
+ li.is-broken img {
+ opacity: 0;
+ }
+
+ .buttons { margin-bottom: 1.0em; }
+
+ button {
+ font-size: 18px;
+ padding: 0.4em 0.8em;
+ font-family: sans-serif;
+ }
+
+ #status {
+ opacity: 0;
+ position: fixed;
+ right: 20px;
+ top: 20px;
+ background: hsla( 0, 0%, 0%, 0.8);
+ padding: 20px;
+ border-radius: 10px;
+ z-index: 2; /* over other stuff */
+ }
+ </style>
+
+</head>
+<body>
+
+ <h1>progress</h1>
+
+ <div class="buttons">
+ <button id="add">Add images</button>
+ <button id="reset">Reset</button>
+ </div>
+ <div id="status">
+ <progress max="7" value="0"></progress>
+ </div>
+ <div id="image-container"></div>
+
+<script src="../../bower_components/ev-emitter/ev-emitter.js"></script>
+<script src="../../imagesloaded.js"></script>
+<script src="progress.js"></script>
+
+</body>
+</html>
diff --git a/vendor/desandro/imagesloaded/sandbox/progress/progress.js b/vendor/desandro/imagesloaded/sandbox/progress/progress.js
new file mode 100644
index 000000000..7c00003f5
--- /dev/null
+++ b/vendor/desandro/imagesloaded/sandbox/progress/progress.js
@@ -0,0 +1,111 @@
+/* jshint strict: false */
+
+var progressElem, statusElem;
+var supportsProgress;
+var loadedImageCount, imageCount;
+
+var container = document.querySelector('#image-container');
+statusElem = document.querySelector('#status');
+progressElem = document.querySelector('progress');
+
+supportsProgress = progressElem &&
+ // IE does not support progress
+ progressElem.toString().indexOf('Unknown') === -1;
+
+document.querySelector('#add').onclick = function() {
+ // add new images
+ var fragment = getItemsFragment();
+ container.insertBefore( fragment, container.firstChild );
+ // use ImagesLoaded
+ var imgLoad = imagesLoaded( container );
+ imgLoad.on( 'progress', onProgress );
+ imgLoad.on( 'always', onAlways );
+ // reset progress counter
+ imageCount = imgLoad.images.length;
+ resetProgress();
+ updateProgress( 0 );
+};
+
+// reset container
+document.querySelector('#reset').onclick = function() {
+ empty( container );
+};
+
+// ----- set text helper ----- //
+
+var docElem = document.documentElement;
+var textSetter = docElem.textContent !== undefined ? 'textContent' : 'innerText';
+
+function setText( elem, value ) {
+ elem[ textSetter ] = value;
+}
+
+function empty( elem ) {
+ while ( elem.firstChild ) {
+ elem.removeChild( elem.firstChild );
+ }
+}
+
+// ----- ----- //
+
+// return doc fragment with
+function getItemsFragment() {
+ var fragment = document.createDocumentFragment();
+ for ( var i = 0; i < 7; i++ ) {
+ var item = getImageItem();
+ fragment.appendChild( item );
+ }
+ return fragment;
+}
+
+// return an <li> with a <img> in it
+function getImageItem() {
+ var item = document.createElement('li');
+ item.className = 'is-loading';
+ var img = document.createElement('img');
+ var size = Math.random() * 3 + 1;
+ var width = Math.random() * 110 + 100;
+ width = Math.round( width * size );
+ var height = Math.round( 140 * size );
+ var rando = Math.ceil( Math.random() * 1000 );
+ // 10% chance of broken image src
+ // random parameter to prevent cached images
+ img.src = rando < 100 ? '//foo/broken-' + rando + '.jpg' :
+ // use picsum for great random images
+ 'https://picsum.photos/' + width + '/' + height + '/' + '?random';
+ item.appendChild( img );
+ return item;
+}
+
+// ----- ----- //
+
+function resetProgress() {
+ statusElem.style.opacity = 1;
+ loadedImageCount = 0;
+ if ( supportsProgress ) {
+ progressElem.setAttribute( 'max', imageCount );
+ }
+}
+
+function updateProgress( value ) {
+ if ( supportsProgress ) {
+ progressElem.setAttribute( 'value', value );
+ } else {
+ // if you don't support progress elem
+ setText( statusElem, value + ' / ' + imageCount );
+ }
+}
+
+// triggered after each item is loaded
+function onProgress( imgLoad, image ) {
+ // change class if the image is loaded or broken
+ image.img.parentNode.className = image.isLoaded ? '' : 'is-broken';
+ // update progress element
+ loadedImageCount++;
+ updateProgress( loadedImageCount );
+}
+
+// hide status when done
+function onAlways() {
+ statusElem.style.opacity = 0;
+}
diff --git a/vendor/desandro/imagesloaded/test/css/tests.css b/vendor/desandro/imagesloaded/test/css/tests.css
new file mode 100644
index 000000000..af8a7e885
--- /dev/null
+++ b/vendor/desandro/imagesloaded/test/css/tests.css
@@ -0,0 +1,41 @@
+img {
+ display: inline-block;
+ max-width: 240px;
+}
+
+/* ---- backgrounds ---- */
+
+.bg-box {
+ width: 240px;
+ height: 240px;
+ margin: 0 20px 20px 0;
+ border: 1px solid;
+ display: inline-block;
+}
+
+.bg-box.tulip {
+ background: url('http://i.imgur.com/9xYjgCk.jpg');
+ background-size: cover;
+}
+
+.bg-box.thunder-cloud {
+ background: url('../img/thunder-cloud.jpg');
+ background-size: contain;
+}
+
+.bg-box.multi {
+ background:
+ url("http://i.imgur.com/ZAVN3.png"),
+ url('http://i.imgur.com/6UdOxeB.png') bottom right,
+ url(https://picsum.photos/601/401/?random);
+ background-size: cover;
+}
+
+.bg-box.blue {
+ background: #09F;
+}
+
+.bg-box.gulls {
+ background-image: url('http://i.imgur.com/qKhkOKC.jpg');
+ background-size: cover;
+}
diff --git a/vendor/desandro/imagesloaded/test/img/blue-shell.jpg b/vendor/desandro/imagesloaded/test/img/blue-shell.jpg
new file mode 100644
index 000000000..b47f1e927
--- /dev/null
+++ b/vendor/desandro/imagesloaded/test/img/blue-shell.jpg
Binary files differ
diff --git a/vendor/desandro/imagesloaded/test/img/bowser-jr.jpg b/vendor/desandro/imagesloaded/test/img/bowser-jr.jpg
new file mode 100644
index 000000000..b1de2a76f
--- /dev/null
+++ b/vendor/desandro/imagesloaded/test/img/bowser-jr.jpg
Binary files differ
diff --git a/vendor/desandro/imagesloaded/test/img/thunder-cloud.jpg b/vendor/desandro/imagesloaded/test/img/thunder-cloud.jpg
new file mode 100644
index 000000000..54fc9a1b7
--- /dev/null
+++ b/vendor/desandro/imagesloaded/test/img/thunder-cloud.jpg
Binary files differ
diff --git a/vendor/desandro/imagesloaded/test/index.html b/vendor/desandro/imagesloaded/test/index.html
new file mode 100644
index 000000000..02b04f4a6
--- /dev/null
+++ b/vendor/desandro/imagesloaded/test/index.html
@@ -0,0 +1,104 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset="utf-8">
+
+ <title>imagesLoaded tests</title>
+
+ <link rel="stylesheet" href="../bower_components/qunit/qunit/qunit.css" />
+ <link rel="stylesheet" href="css/tests.css" />
+
+ <script src="../bower_components/ev-emitter/ev-emitter.js"></script>
+ <script src="../bower_components/qunit/qunit/qunit.js"></script>
+ <script src="../bower_components/jquery/dist/jquery.js"></script>
+
+ <script src="../imagesloaded.js"></script>
+
+ <script src="unit/basics.js"></script>
+ <script src="unit/selector-string.js"></script>
+ <script src="unit/single-element.js"></script>
+ <script src="unit/local-files.js"></script>
+ <script src="unit/data-uri.js"></script>
+ <script src="unit/append.js"></script>
+ <script src="unit/no-images.js"></script>
+ <script src="unit/jquery-success.js"></script>
+ <script src="unit/jquery-fail.js"></script>
+ <script src="unit/non-element.js"></script>
+ <script src="unit/background.js"></script>
+
+</head>
+<body>
+
+ <h1>imagesLoaded tests</h1>
+
+ <div id="qunit"></div>
+
+ <h2>Basics</h2>
+
+ <div id="basics">
+ <img src="http://i.imgur.com/xrQHn.jpg" />
+ <img src="http://i.imgur.com/b3fBJ.jpg" />
+ <img src="http://i.imgur.com/xmSh2.jpg" />
+ <img src="http://i.imgur.com/iIpJm.jpg" />
+ <img src="http://i.imgur.com/cvZZl10.gif" />
+ </div>
+
+ <img id="mario-with-shell" src="http://i.imgur.com/ZAVN3.png" >
+
+ <h2>Locals</h2>
+
+ <div id="locals">
+ <img src="img/blue-shell.jpg" />
+ <img src="img/bowser-jr.jpg" />
+ <!-- thunder cloud has bad permissions, should 403 -->
+ <img src="img/not-there.jpg" />
+ </div>
+
+ <h2>Data URI</h2>
+
+ <div id="data-uri">
+ <img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAARgAA/+4ADkFkb2JlAGTAAAAAAf/bAIQABAMDAwMDBAMDBAYEAwQGBwUEBAUHCAYGBwYGCAoICQkJCQgKCgwMDAwMCgwMDQ0MDBERERERFBQUFBQUFBQUFAEEBQUIBwgPCgoPFA4ODhQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU/8AAEQgAMAAwAwERAAIRAQMRAf/EAJMAAAEFAQEBAAAAAAAAAAAAAAYAAwQHCAUBAgEAAgIDAQEAAAAAAAAAAAAAAAUEBgECAwcIEAABAwMDAgQFAwUAAAAAAAACAQMEEQUGACESMQdBUSIyYUJiExRSIwihgiQVFhEAAQMCBQEFBgcAAAAAAAAAAQARAgMEITFBEgVRYYGRIgZxocHRchPw4TJCIxQH/9oADAMBAAIRAxEAPwDf2hCWhC42R5JBxuF+RJq7JcqMWIC/uOmngnkKfMXh/TSTmOZt+MoGrVP0x1kez4nTwCl21rOvPbHvPRRMHuFzutmcuF2NClPyn1ERSjYNiXEQD4DTx389RvTl/VvrKNxUzqGRA6B2AHgt72lGlVMI/tbxRJqyKCloQloQm31eRlxY4iT6CqtCaqIqVNkVURaJXWk9207W3Ng+T9qyGfFUtPutrbyFIuazTtWRyy+1FbuIKyw9v6QiO7tODVdhEuXmldfM/qbi+arXMql2A2hDmAHQM7D29+Kt9tc04w20Rh7+9FkKZIx1VFhf8bkv3I5biqqu6p5Kvw0u9N+sL3iav9eX8tJ22dPoOnsy7FwrW8bnzZS6/NHkZ4pEdt42yZIxQlaP3DXwXX1LQqmrTjMxMNwfbLMdh7VWJBiQ7p3Xdapt99mMy5JkOC1HZEnHXTVBEQBKkSqvRERN9CFSFx7q5PkqOz8TfZs2ON8lizJDIvyZLadHlFxeLYF1BOKlTdadNWy34emIg1XMjoNElr35EmgEORO4uaXWUNnya2QMpxZ50FemSWBhuxXBJFB9tKGDn219ftAtvStdJvUnEQHHXEqQJIpTaP6jI7SwGrk5KVZ3z1IieDkfgqDkOf8AcEsmQ7FGbs+LspRm7SowzJkh2u7iNGvFhpE9iqJGXVeOvPfQX+Yw4+Iu+Q89zIOIPhSfqdanXSOQxxU6+5oSBhROA9/5Isgd08vxltq5ZQ+zfccNUKZIYZFiUwz4ugjXocEfcQ8UKnRa7a9cuOHpyiftOJDQ6pPR5AmTTCvONJYmR2ZcVwXosgBdYeBeQG2aIQkKp1RUWqaqZDJ0qL7p5U9nz1w7cY887FtMSQLGR3JteKyVb9TkJrxQK0F4/HcE8V1ZONsAwrVMtB8Uru7v7flGaGZlqdt8AGnXUOMwQqTYogjTolUTy1Z4yEkid1DwPIrzLzLKbNdba7GsFo+wlruDraCxL/IqQ/jkgopIAJ+9Ui9dKcemlUjWlUkCPKGbwXWpCAhEjMu697gZHfYmW4pabRbnZVjuzjwXa4NAJsRRZ4kX5JKKqCE2pfaUVH1pvXprANaE4iIwLv4IpxgYSJzGSnwLQ7cbe4DLyNx3iJRbVEIadFoi+emkpiJXEll2O1uXu9u5cLt1fnXZVinS1ZsFwMuSwjfWoRHK7q0p1RkvkqgL6aKlc5Pj3BrQ7x8fmn1pd7/Kc1W9zukjtr3AvuMX0VjPSpsm5WqQ5sEyFMeJ4XGyXYlFSVtxE3Eh36ppnYV4VKMRqAyj3luTJwuxIvzV6bKG2+ipJFRJQXdBXqqeVNMwAEs2mKYKZc7MItPG3NbH2PI4jLnH6gL01+IrocrIAllgkk26XgSaYJuG2XueJxHnOPjxAdq+XJaaHKCBHPFSYeQt2JoYDj9Ejigipruop4rrBiDmsGBlih+DOkdzc8s2K2BFkPtTI1wukltOTcOFDeB43XFTZFLigNoq1Ii26Lpdf3EKdEjUhgmdpbyEnK1plWF4pm8BLZltoi3eEKqTYSm0MmyXqTZ7EBbdQVF1R4VJQLxLJ2Q6zdlX8asvxO5O3TtPLbulofLktiukhWpbH0syTRRcBPAXaEn6i0+teV24T8VFq24mEMOdve/F3f8Awf8AjljPJRClS5sQIqeFeYOGS0+kFXTGXLUgMCosbJl9tdu+/FoeWEuHpKc3QZUSdFKMXxQnHGyT+4E0R5aiRiidk6IsX/jVmOW3Jq5d15bdqsrBcksdrfV2Y/T5XZIIgttr8yNciX9Q6X3XK7g0PFSqVuILSmLYbiuE2/8A1eJ2iLaIKrycbitoCuElfU4XuMt+pqq6QTqSmXkXUoBl/9k=" />
+ <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACsAAAAwCAMAAAC/knOqAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAMBQTFRFkF0QF27/Bgsp/fQF+fr6jqvpDEG2zp4CCx9Ys4IFo5JU8MqQXJH2Ulxj89QDC0bIsrKxIHn//fxztcv2iYqG5ebmCjCHzNjxAzTYRmih2drcCzijMof+OB8U/Pg59PHXE2D9xMK9eUMDAVf8kXNP/fvr2eP0p6WgOUtnAkX7Eljwa3WB5er2UXjVC0jZAh9/EFHa8PHyl5mZJVKt6NM34dzNz87NASGpsbzZDlDytq4tLWfs4bQFyLNp////+/v7DjziEwAAAEB0Uk5T////////////////////////////////////////////////////////////////////////////////////AMJ7sUQAAAPaSURBVHjadNWLdqo6EAZgQKGRA0YUYzRQY1ELqFykiojV93+rM0FQbLt/VlcvfpmVhGQq3V6TjgyjLOWyNIzR9sdn0stvE0MuQrmOZxmjf9pRybln+sJZspWZiSU7o7+twTmXtcU3BmhZ4f6/zLJk2ej+ttsyDIXVN4klsGzqmQP1ZXn9044TQbmcuS5Yx3Ic380cy2rj2qZJktzrui7MFqiDKlutcv1ip0mNseuGFbaedeVd235qGOMkAo4VJYB4AVcUbHG5erjxtN1ME8kwpgHybV0/63vbRF5QrUFk+7ADwpgGD82nva9+p4m+CQKYWFjwUH3YKYNkjPrnCr6/D4fz93f46WsKuIDqu8amPmGE5bnZr2u+fw2Hwwr3N4FYRZKsazshBLCggPv9S79K56saV+NRbU8McO6+ifSavL1dLtVQk2LYT7VtY/hcgnw8HgkGAL9Q2E78tDGJfWBV3CbiFwnqmzlsfmPXUDd2pTtUFAVVj6IIDtVNqmGtmW+aEYJQDZ9puM/gPTX7cNtBYeS7r+z+hVyfAp0+3gUsDsXKP5IXGLPne7uVUJf8TRFPEi1Ln1YVq/sbazzBbN8+v2LGjCguzNBtllVRwovoPtvnvcgYihlpLaueQeFRjY1f79vWhxfCGKpz54gVRYTZ7Nedn8JeiPNG7lhBGS2KIKdZ99edT6cKQjEiBGMf+UhhZRFQSnG02/60J9i0qmCMcsbimPGABkXIRYdQX+2EaaEcinOc57GWlWXpeR7cYqsUPWj0YksKN73QNEpLdZJer9d0rToeVC2LEG5+2rIqLjjXKKPJ6PrMxPJkK6DcsdSn3dIo5DnK8113de22tOHJWhyUDp88rBFFPEJxvruu0jYVOEE0tCyjsSMchQVBOZ3Px+MfeOehmHJLbs76LioKpuT5QND0hV4nnqZoGPrb3Z6iKNIUJc6Os5nA3ZfKTgCvGtq3Kuw2BIpMP5/O/8JGQEzC4N/BGuyuwAyZKYvtw/GOYc7A4RHf1ICNbUIi2blJqocJWt5Skm8OiyPo8aGufX/UQJvd9sSPZFUqKfGPcHRYPF0MBovT8VhXh3TT1cqgFM7kzESslEbqUezdyszJ4HvwKfhi8eCra0incwFm+1N9Hub9ztnffOqf+0/IY8BhpWbnTmfePjurs2iJZ922dXsPqQcMFouqWfbnLfst+ii05t7Stjd2lb0Y1Lt0hkA73y3bexNddzjs93S7yd5e9i4XaPFQ5tLqD5LohxfouG+S5G/u8T8+7l34Al25+7SHpVRlKS312fo4OA0Ws7Fe/1FaLg+V+l+AAQAurhhy+upm/wAAAABJRU5ErkJggg==" />
+ </div>
+
+ <h2>append</h2>
+
+ <div id="append"></div>
+
+ <h2>no images</h2>
+
+ <div id="no-images"></div>
+
+ <h2>jQuery success</h2>
+
+ <div id="jquery-success">
+ <img src="http://i.imgur.com/YbYCPFF.png" />
+ <img src="http://i.imgur.com/6UdOxeB.png" />
+ <img src="http://i.imgur.com/qd8G15D.png" />
+ </div>
+
+ <h2>jQuery fail</h2>
+
+ <div id="jquery-fail">
+ <img src="http://i.imgur.com/xmSh2.jpg" />
+ <img src="img/bowser-jr.jpg" />
+ <img src="http://i.imgur.com/ZAVN3.png">
+ <img src="img/not-there.jpg" />
+ <img src="foobar.jpg" />
+ </div>
+
+ <h2>background</h2>
+
+ <div id="background">
+ <div class="bg-box tulip"></div>
+ <div class="bg-box thunder-cloud"></div>
+ <div class="bg-box multi"></div>
+ <div class="bg-box blue"></div>
+ <div class="bg-box gulls">
+ <img src="https://picsum.photos/400/300/?random" />
+ <img src="https://picsum.photos/800/600/?random" />
+ </div>
+ </div>
+
+</body>
+</html>
diff --git a/vendor/desandro/imagesloaded/test/unit/append.js b/vendor/desandro/imagesloaded/test/unit/append.js
new file mode 100644
index 000000000..7a6b3c827
--- /dev/null
+++ b/vendor/desandro/imagesloaded/test/unit/append.js
@@ -0,0 +1,30 @@
+QUnit.test( 'append', function( assert ) {
+ 'use strict';
+
+ var imgUrls = [
+ 'http://i.imgur.com/bwy74ok.jpg',
+ 'http://i.imgur.com/bAZWoqx.jpg',
+ 'http://i.imgur.com/PgmEBSB.jpg',
+ 'http://i.imgur.com/aboaFoB.jpg',
+ 'http://i.imgur.com/LkmcILl.jpg',
+ 'http://i.imgur.com/q9zO6tw.jpg'
+ ];
+
+ // create images
+ var fragment = document.createDocumentFragment();
+ for ( var i=0, len = imgUrls.length; i < len; i++ ) {
+ var img = document.createElement('img');
+ img.src = imgUrls[i];
+ fragment.appendChild( img );
+ }
+
+ var elem = document.querySelector('#append');
+ elem.appendChild( fragment );
+ var done = assert.async();
+
+ imagesLoaded( elem, { debug: false } ).on( 'always', function() {
+ assert.ok( 'appended images loaded' );
+ done();
+ });
+
+});
diff --git a/vendor/desandro/imagesloaded/test/unit/background.js b/vendor/desandro/imagesloaded/test/unit/background.js
new file mode 100644
index 000000000..ca76fad6f
--- /dev/null
+++ b/vendor/desandro/imagesloaded/test/unit/background.js
@@ -0,0 +1,70 @@
+QUnit.test( 'background', function( assert ) {
+ 'use strict';
+
+ // from Modernizr
+ var supportsMultiBGs = ( function() {
+ var style = document.createElement('a').style;
+ style.cssText = 'background:url(https://),url(https://),red url(https://)';
+ return (/(url\s*\(.*?){3}/).test(style.background);
+ })();
+
+ var multiBGCount = supportsMultiBGs ? 3 : 0;
+ var done = assert.async( 14 + multiBGCount );
+
+ var imgLoad0 = imagesLoaded( '#background .tulip', { background: true }, function() {
+ assert.ok( true, 'callback triggered on .orange-tree');
+ done();
+ });
+ assert.equal( imgLoad0.images.length, 1, '1 image on .images' );
+
+ imgLoad0.on( 'progress', function( instance, image, element ) {
+ assert.ok( element.nodeName == 'DIV', 'progress; element is div');
+ assert.ok( image.isLoaded, 'progress; image.isLoaded');
+ done();
+ });
+
+ var imgLoad1 = imagesLoaded( '#background .thunder-cloud', { background: true }, function() {
+ assert.ok( true, 'callback triggered on .thunder-cloud');
+ done();
+ });
+ assert.equal( imgLoad1.images.length, 1, '1 image on .images' );
+
+ // multiple backgrounds
+ var imgLoad2 = imagesLoaded( '#background .multi', { background: true }, function() {
+ assert.ok( true, 'callback triggered on .multi');
+ done();
+ });
+ assert.equal( imgLoad2.images.length, multiBGCount, 'correct multiple BG count on .images' );
+
+ // multiple elements
+ var imgLoad3 = imagesLoaded( '#background .bg-box', { background: true }, function() {
+ assert.ok( true, 'callback triggered on .bg-box');
+ var count = 5 + multiBGCount;
+ assert.equal( imgLoad3.images.length, count, count + ' images on .bg-box' );
+ done();
+ });
+
+ imgLoad3.on('progress', function( instance, image/*, element */) {
+ assert.ok( true, 'progress on .bg-box; ' + image.img.src );
+ assert.equal( image.isLoaded, true, 'image.isLoaded == true' );
+ done();
+ });
+
+ // background and <img> children
+ var imgLoad4 = imagesLoaded( '#background .gulls', { background: true } );
+ assert.equal( imgLoad4.images.length, 3, '3 images: 1 background and 2 <img>' );
+
+ imgLoad4.on( 'progress', function( instance, image ) {
+ assert.equal( image.isLoaded, true, 'image is loaded' );
+ done();
+ });
+
+ // child background selector
+ var imgLoad5 = imagesLoaded( '#background', { background: '.bg-box' }, function() {
+ var count = 5 + multiBGCount;
+ assert.equal( imgLoad5.images.length, count,
+ count + ' images on .bg-box, with {background: .bg-box}' );
+ done();
+ });
+
+});
diff --git a/vendor/desandro/imagesloaded/test/unit/basics.js b/vendor/desandro/imagesloaded/test/unit/basics.js
new file mode 100644
index 000000000..6c502a793
--- /dev/null
+++ b/vendor/desandro/imagesloaded/test/unit/basics.js
@@ -0,0 +1,28 @@
+QUnit.test( 'basics', function( assert ) {
+
+ 'use strict';
+
+ var elem = document.querySelector('#basics');
+ var images = elem.querySelectorAll('img');
+ var done = assert.async( 3 + images.length );
+
+ var imgLoader = new imagesLoaded( elem, function( obj ) {
+ assert.ok( true, 'callback function triggered' );
+ assert.equal( imgLoader, obj, 'callback argument and instance match' );
+ done();
+ });
+ imgLoader.on( 'done', function() {
+ assert.ok( true, 'done event triggered' );
+ done();
+ });
+ imgLoader.on( 'always', function() {
+ assert.ok( true, 'always event triggered' );
+ done();
+ });
+
+ imgLoader.on( 'progress', function( loader, image ) {
+ assert.ok( image.isLoaded, 'image is loaded');
+ done();
+ });
+
+});
diff --git a/vendor/desandro/imagesloaded/test/unit/data-uri.js b/vendor/desandro/imagesloaded/test/unit/data-uri.js
new file mode 100644
index 000000000..635f69859
--- /dev/null
+++ b/vendor/desandro/imagesloaded/test/unit/data-uri.js
@@ -0,0 +1,10 @@
+QUnit.test( 'data-uri', function( assert ) {
+ 'use strict';
+
+ var done = assert.async();
+ imagesLoaded('#data-uri', { debug: false }).on( 'done', function( obj ) {
+ assert.ok( true, 'data-uri images loaded' );
+ assert.equal( obj.images.length, 2, 'instance has 2 images' );
+ done();
+ });
+});
diff --git a/vendor/desandro/imagesloaded/test/unit/jquery-fail.js b/vendor/desandro/imagesloaded/test/unit/jquery-fail.js
new file mode 100644
index 000000000..b2180f6f2
--- /dev/null
+++ b/vendor/desandro/imagesloaded/test/unit/jquery-fail.js
@@ -0,0 +1,29 @@
+QUnit.test( 'jquery fail', function( assert ) {
+
+ 'use strict';
+
+ var $ = window.jQuery;
+ var $images = $('#jquery-fail img');
+ var done = assert.async( 3 + $images.length );
+
+ $('#jquery-fail').imagesLoaded( function( instance ) {
+ assert.ok( true, 'callback triggered' );
+ assert.ok( instance instanceof imagesLoaded, 'instance instanceof imagesLoaded' );
+ done();
+ })
+ .fail( function( instance ) {
+ assert.ok( true, 'fail triggered' );
+ assert.ok( instance instanceof imagesLoaded, 'instance instanceof imagesLoaded' );
+ done();
+ })
+ .always( function( instance ) {
+ assert.ok( true, 'always triggered' );
+ assert.ok( instance instanceof imagesLoaded, 'instance instanceof imagesLoaded' );
+ done();
+ })
+ .progress( function(/* instance, image */) {
+ assert.ok( true, 'progress trigged');
+ done();
+ });
+
+ });
diff --git a/vendor/desandro/imagesloaded/test/unit/jquery-success.js b/vendor/desandro/imagesloaded/test/unit/jquery-success.js
new file mode 100644
index 000000000..f16621088
--- /dev/null
+++ b/vendor/desandro/imagesloaded/test/unit/jquery-success.js
@@ -0,0 +1,28 @@
+QUnit.test( 'jquery success', function( assert ) {
+
+ 'use strict';
+
+ var $ = window.jQuery;
+ var done = assert.async( 6 );
+
+ $('#jquery-success').imagesLoaded( function( instance ) {
+ assert.ok( true, 'callback triggered' );
+ assert.ok( instance instanceof imagesLoaded, 'instance instanceof imagesLoaded' );
+ done();
+ })
+ .done( function( instance ) {
+ assert.ok( true, 'done triggered' );
+ assert.ok( instance instanceof imagesLoaded, 'instance instanceof imagesLoaded' );
+ done();
+ })
+ .always( function( instance ) {
+ assert.ok( true, 'always triggered' );
+ assert.ok( instance instanceof imagesLoaded, 'instance instanceof imagesLoaded' );
+ done();
+ })
+ .progress( function( instance, image ) {
+ assert.ok( image.isLoaded, 'progress trigged, image is loaded');
+ done();
+ });
+
+});
diff --git a/vendor/desandro/imagesloaded/test/unit/local-files.js b/vendor/desandro/imagesloaded/test/unit/local-files.js
new file mode 100644
index 000000000..61da6ae92
--- /dev/null
+++ b/vendor/desandro/imagesloaded/test/unit/local-files.js
@@ -0,0 +1,31 @@
+QUnit.test( 'local files', function( assert ) {
+ 'use strict';
+
+ var elem = document.querySelector('#locals');
+ var done = assert.async( 6 );
+
+ var imgLoader = new imagesLoaded( elem, function( obj ) {
+ assert.ok( true, 'callback function triggered' );
+ assert.equal( imgLoader, obj, 'callback argument and instance match' );
+ done();
+ });
+ imgLoader.on( 'fail', function() {
+ assert.ok( true, 'fail event triggered' );
+ done();
+ });
+ imgLoader.on( 'always', function() {
+ assert.ok( true, 'always event triggered' );
+ done();
+ });
+
+ imgLoader.on( 'progress', function( loader, image ) {
+ assert.ok( true, 'image progressed');
+ if ( image.img.src.indexOf('img/not-there.jpg') !== -1 ) {
+ assert.ok( !image.isLoaded, 'thunder cloud is not loaded' );
+ } else {
+ assert.ok( image.isLoaded, 'image is loaded' );
+ }
+ done();
+ });
+
+});
diff --git a/vendor/desandro/imagesloaded/test/unit/no-images.js b/vendor/desandro/imagesloaded/test/unit/no-images.js
new file mode 100644
index 000000000..841216381
--- /dev/null
+++ b/vendor/desandro/imagesloaded/test/unit/no-images.js
@@ -0,0 +1,11 @@
+QUnit.test( 'no images', function( assert ) {
+ 'use strict';
+
+ var elem = document.querySelector('#no-images');
+ var done = assert.async();
+ imagesLoaded( elem, function() {
+ assert.ok( true, 'triggered with no images' );
+ done();
+ });
+
+});
diff --git a/vendor/desandro/imagesloaded/test/unit/non-element.js b/vendor/desandro/imagesloaded/test/unit/non-element.js
new file mode 100644
index 000000000..4c9986fa6
--- /dev/null
+++ b/vendor/desandro/imagesloaded/test/unit/non-element.js
@@ -0,0 +1,24 @@
+QUnit.test( 'dismiss non-element nodes', function( assert ) {
+ 'use strict';
+
+ var $ = window.jQuery;
+ var done = assert.async( 2 );
+
+ $(' <img src="https://picsum.photos/401/301/?random" /> <img src="https://picsum.photos/402/302/?random" /> ')
+ .imagesLoaded(function() {
+ assert.ok( true, 'elements from jQuery string ok' );
+ done();
+ });
+
+ // test fragment
+ var frag = document.createDocumentFragment();
+ var img = new Image();
+ img.src = 'https://picsum.photos/403/303/?random';
+ frag.appendChild( img );
+ var imgLoad = imagesLoaded( frag, function() {
+ assert.ok( true, 'document fragment ok' );
+ assert.equal( imgLoad.images.length, 1, '1 image found' );
+ done();
+ });
+
+});
diff --git a/vendor/desandro/imagesloaded/test/unit/selector-string.js b/vendor/desandro/imagesloaded/test/unit/selector-string.js
new file mode 100644
index 000000000..8c43c4bef
--- /dev/null
+++ b/vendor/desandro/imagesloaded/test/unit/selector-string.js
@@ -0,0 +1,12 @@
+QUnit.test( 'selector string', function( assert ) {
+ 'use strict';
+ var images = document.querySelectorAll('#basics img');
+ var done = assert.async();
+ var imgLoad = imagesLoaded('#basics', { debug: true }).on( 'done', function( obj ) {
+ assert.ok( true, 'selector string worked' );
+ assert.ok( obj.images, 'argument has images' );
+ assert.equal( obj.images.length, images.length, 'images.length matches' );
+ done();
+ });
+ assert.ok( imgLoad.options.debug, 'debug option set' );
+});
diff --git a/vendor/desandro/imagesloaded/test/unit/single-element.js b/vendor/desandro/imagesloaded/test/unit/single-element.js
new file mode 100644
index 000000000..42d7e48ee
--- /dev/null
+++ b/vendor/desandro/imagesloaded/test/unit/single-element.js
@@ -0,0 +1,11 @@
+QUnit.test( 'single element', function( assert ) {
+ 'use strict';
+ var elem = document.querySelector('#mario-with-shell');
+ var done = assert.async();
+ imagesLoaded( elem ).on( 'done', function( obj ) {
+ assert.ok( true, 'single element worked' );
+ assert.ok( obj.images, 'argument has images' );
+ assert.equal( obj.images.length, 1, 'images.length = 1' );
+ done();
+ });
+});
diff --git a/vendor/psr/log/README.md b/vendor/psr/log/README.md
index 574bc1cb2..5571a25e8 100644
--- a/vendor/psr/log/README.md
+++ b/vendor/psr/log/README.md
@@ -7,6 +7,13 @@ This repository holds all interfaces/classes/traits related to
Note that this is not a logger of its own. It is merely an interface that
describes a logger. See the specification for more details.
+Installation
+------------
+
+```bash
+composer require psr/log
+```
+
Usage
-----
diff --git a/view/css/default.css b/view/css/default.css
index 765a197d9..bd0f14ba2 100644
--- a/view/css/default.css
+++ b/view/css/default.css
@@ -1,22 +1,37 @@
main {
- display: table;
- table-layout: fixed;
position: relative;
- width: 100%;
- height: 100vh;
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
}
-aside {
+.content {
+ display: flex;
+ flex: 1;
+}
+
+.columns {
+ display: flex;
+ flex:1;
+ min-width: 0;
+}
+
+#region_1 {
position: relative;
- display: table-cell;
- vertical-align: top;
+ order: 1;
padding: 4.5rem 7px 0px 7px;
}
-section {
+#region_2 {
position: relative;
- width: 100%;
- display: table-cell;
- vertical-align: top;
+ flex: 1;
+ order: 2;
padding: 4.5rem 7px 200px 7px;
+ min-width: 0;
+}
+
+#region_3 {
+ position: relative;
+ order: 3;
+ padding: 4.5rem 7px 0px 7px;
}
diff --git a/view/css/mod_connedit.css b/view/css/mod_connedit.css
index 67a182c5c..b02f928f0 100644
--- a/view/css/mod_connedit.css
+++ b/view/css/mod_connedit.css
@@ -71,7 +71,6 @@
width: 32px;
height: 32px;
border-radius: 4px;
- border: 1px solid #ccc;
text-align: center;
}
diff --git a/view/es-es/hstrings.php b/view/es-es/hstrings.php
index 67f499feb..1dd38b930 100644
--- a/view/es-es/hstrings.php
+++ b/view/es-es/hstrings.php
@@ -2,10 +2,10 @@
if(! function_exists("string_plural_select_es_es")) {
function string_plural_select_es_es($n){
- return ($n != 1 ? 1 : 0);;
+ return ($n != 1 ? 1 : 0);
}}
App::$rtl = 0;
-App::$strings["plural_function_code"] = "(n != 1 ? 1 : 0);";
+App::$strings["plural_function_code"] = "(n != 1 ? 1 : 0)";
App::$strings["Can view my channel stream and posts"] = "Pueden verse la actividad y publicaciones de mi canal";
App::$strings["Can send me their channel stream and posts"] = "Se me pueden enviar entradas y contenido de un canal";
App::$strings["Can view my default channel profile"] = "Puede verse mi perfil de canal predeterminado.";
diff --git a/view/js/main.js b/view/js/main.js
index 085bc8d0d..a69bcfa64 100644
--- a/view/js/main.js
+++ b/view/js/main.js
@@ -544,7 +544,7 @@ function handleNotificationsItems(notifyType, data) {
notify_menu.html('');
$(data).each(function() {
- html = notifications_tpl.format(this.notify_link,this.photo,this.name,this.message,this.when,this.hclass,this.b64mid,this.notify_id,this.thread_top,this.unseen,this.private_forum);
+ html = notifications_tpl.format(this.notify_link,this.photo,this.name,this.addr,this.message,this.when,this.hclass,this.b64mid,this.notify_id,this.thread_top,this.unseen,this.private_forum);
notify_menu.append(html);
});
@@ -558,7 +558,8 @@ function handleNotificationsItems(notifyType, data) {
if(filter) {
$('#nav-' + notifyType + '-menu .notification').each(function(i, el){
var cn = $(el).data('contact_name').toString().toLowerCase();
- if(cn.indexOf(filter) === -1)
+ var ca = $(el).data('contact_addr').toString().toLowerCase();
+ if(cn.indexOf(filter) === -1 && ca.indexOf(filter) === -1)
$(el).addClass('d-none');
else
$(el).removeClass('d-none');
diff --git a/view/php/default.php b/view/php/default.php
index 60f3f6a6f..388c94382 100644
--- a/view/php/default.php
+++ b/view/php/default.php
@@ -10,12 +10,16 @@
<header><?php if(x($page,'header')) echo $page['header']; ?></header>
<nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-dark"><?php if(x($page,'nav')) echo $page['nav']; ?></nav>
<main>
- <aside id="region_1"><div class="aside_spacer"><div id="left_aside_wrapper"><?php if(x($page,'aside')) echo $page['aside']; ?></div></div></aside>
- <section id="region_2"><?php if(x($page,'content')) echo $page['content']; ?>
+ <div class="content">
+ <div class="columns">
+ <aside id="region_1"><div class="aside_spacer"><div id="left_aside_wrapper"><?php if(x($page,'aside')) echo $page['aside']; ?></div></div></aside>
+ <section id="region_2"><?php if(x($page,'content')) echo $page['content']; ?>
<div id="page-footer"></div>
- <div id="pause"></div>
- </section>
- <aside id="region_3" class="d-none d-xl-table-cell"><div class="aside_spacer"><div id="right_aside_wrapper"><?php if(x($page,'right_aside')) echo $page['right_aside']; ?></div></div></aside>
+ <div id="pause"></div>
+ </section>
+ <aside id="region_3" class="d-none d-xl-table-cell"><div class="aside_spacer"><div id="right_aside_wrapper"><?php if(x($page,'right_aside')) echo $page['right_aside']; ?></div></div></aside>
+ </div>
+ </div>
</main>
<footer><?php if(x($page,'footer')) echo $page['footer']; ?></footer>
</body>
diff --git a/view/php/theme_init.php b/view/php/theme_init.php
index dd8dcb5ee..73e559c45 100644
--- a/view/php/theme_init.php
+++ b/view/php/theme_init.php
@@ -36,7 +36,7 @@ head_add_js('/library/colorbox/jquery.colorbox-min.js');
head_add_js('/library/jquery.AreYouSure/jquery.are-you-sure.js');
head_add_js('/library/tableofcontents/jquery.toc.js');
-head_add_js('/library/imagesloaded/imagesloaded.pkgd.min.js');
+head_add_js('/vendor/desandro/imagesloaded/imagesloaded.pkgd.min.js');
/**
* Those who require this feature will know what to do with it.
* Those who don't, won't.
diff --git a/view/ru/hmessages.po b/view/ru/hmessages.po
index 6a8c8805c..76c24a404 100644
--- a/view/ru/hmessages.po
+++ b/view/ru/hmessages.po
@@ -12,7 +12,7 @@ msgstr ""
"Project-Id-Version: hubzilla\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-10-18 11:03+0200\n"
-"PO-Revision-Date: 2018-11-19 14:12+0200\n"
+"PO-Revision-Date: 2018-12-04 12:19+0200\n"
"Last-Translator: Max Kostikov <max@kostikov.co>\n"
"Language-Team: Russian (http://www.transifex.com/Friendica/hubzilla/language/ru/)\n"
"MIME-Version: 1.0\n"
@@ -25,7 +25,7 @@ msgstr ""
msgid "Source channel not found."
msgstr "Канал-источник не найден."
-#: ../../view/theme/redbasic/php/config.php:15 ../../include/text.php:3086
+#: ../../view/theme/redbasic/php/config.php:15 ../../include/text.php:3096
#: ../../Zotlabs/Module/Admin/Site.php:187
msgid "Default"
msgstr "По умолчанию"
@@ -36,7 +36,7 @@ msgid "Focus (Hubzilla default)"
msgstr "Фокус (по умолчанию Hubzilla)"
#: ../../view/theme/redbasic/php/config.php:94 ../../include/js_strings.php:22
-#: ../../Zotlabs/Module/Mail.php:431 ../../Zotlabs/Module/Pconfig.php:111
+#: ../../Zotlabs/Module/Mail.php:431 ../../Zotlabs/Module/Pconfig.php:116
#: ../../Zotlabs/Module/Defperms.php:265 ../../Zotlabs/Module/Permcats.php:128
#: ../../Zotlabs/Module/Xchan.php:15
#: ../../Zotlabs/Module/Email_validation.php:40
@@ -83,22 +83,23 @@ msgstr "Фокус (по умолчанию Hubzilla)"
#: ../../Zotlabs/Module/Group.php:156 ../../Zotlabs/Module/Mood.php:158
#: ../../Zotlabs/Module/Invite.php:168 ../../Zotlabs/Module/Connect.php:124
#: ../../Zotlabs/Module/Pdledit.php:107 ../../Zotlabs/Module/Wiki.php:215
-#: ../../Zotlabs/Module/Import.php:565
+#: ../../Zotlabs/Module/Import.php:574
#: ../../Zotlabs/Module/Import_items.php:129
#: ../../Zotlabs/Widget/Wiki_pages.php:42
#: ../../Zotlabs/Widget/Wiki_pages.php:99
-#: ../../Zotlabs/Widget/Eventstools.php:16 ../../Zotlabs/Lib/ThreadItem.php:770
+#: ../../Zotlabs/Widget/Eventstools.php:16 ../../Zotlabs/Lib/ThreadItem.php:773
#: ../../extend/addon/hzaddons/dwpost/dwpost.php:89
#: ../../extend/addon/hzaddons/fuzzloc/fuzzloc.php:191
#: ../../extend/addon/hzaddons/redphotos/redphotos.php:136
-#: ../../extend/addon/hzaddons/rtof/rtof.php:101
-#: ../../extend/addon/hzaddons/ijpost/ijpost.php:89
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:72
+#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:73
#: ../../extend/addon/hzaddons/redfiles/redfiles.php:124
#: ../../extend/addon/hzaddons/twitter/twitter.php:221
#: ../../extend/addon/hzaddons/twitter/twitter.php:268
#: ../../extend/addon/hzaddons/logrot/logrot.php:35
#: ../../extend/addon/hzaddons/likebanner/likebanner.php:57
-#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:168
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:169
+#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:67
#: ../../extend/addon/hzaddons/jappixmini/jappixmini.php:371
#: ../../extend/addon/hzaddons/piwik/piwik.php:95
#: ../../extend/addon/hzaddons/pumpio/pumpio.php:237
@@ -107,10 +108,10 @@ msgstr "Фокус (по умолчанию Hubzilla)"
#: ../../extend/addon/hzaddons/openclipatar/openclipatar.php:53
#: ../../extend/addon/hzaddons/hzfiles/hzfiles.php:84
#: ../../extend/addon/hzaddons/ljpost/ljpost.php:89
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:322
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:380
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:432
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:900
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:193
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:251
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:306
+#: ../../extend/addon/hzaddons/statusnet/statusnet.php:602
#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:139
#: ../../extend/addon/hzaddons/startpage/Mod_Startpage.php:73
#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:114
@@ -130,7 +131,7 @@ msgstr "Фокус (по умолчанию Hubzilla)"
#: ../../extend/addon/hzaddons/irc/irc.php:53
#: ../../extend/addon/hzaddons/chords/Mod_Chords.php:60
#: ../../extend/addon/hzaddons/libertree/libertree.php:85
-#: ../../extend/addon/hzaddons/redred/redred.php:119
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:90
#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:63
#: ../../extend/addon/hzaddons/diaspora/Mod_Diaspora.php:99
#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:97
@@ -150,7 +151,7 @@ msgstr "Узкая панель навигации"
#: ../../view/theme/redbasic/php/config.php:99
#: ../../view/theme/redbasic/php/config.php:116 ../../include/dir_fns.php:143
#: ../../include/dir_fns.php:144 ../../include/dir_fns.php:145
-#: ../../boot.php:1629 ../../Zotlabs/Storage/Browser.php:405
+#: ../../boot.php:1630 ../../Zotlabs/Storage/Browser.php:405
#: ../../Zotlabs/Module/Defperms.php:197 ../../Zotlabs/Module/Profiles.php:681
#: ../../Zotlabs/Module/Photos.php:712 ../../Zotlabs/Module/Api.php:99
#: ../../Zotlabs/Module/Events.php:472 ../../Zotlabs/Module/Events.php:473
@@ -165,16 +166,14 @@ msgstr "Узкая панель навигации"
#: ../../Zotlabs/Module/Mitem.php:257 ../../Zotlabs/Module/Admin/Site.php:255
#: ../../Zotlabs/Module/Connedit.php:398 ../../Zotlabs/Module/Connedit.php:785
#: ../../Zotlabs/Module/Wiki.php:227 ../../Zotlabs/Module/Wiki.php:228
-#: ../../Zotlabs/Module/Import.php:554 ../../Zotlabs/Module/Import.php:558
-#: ../../Zotlabs/Module/Import.php:559 ../../Zotlabs/Lib/Libzotdir.php:162
+#: ../../Zotlabs/Module/Import.php:563 ../../Zotlabs/Module/Import.php:567
+#: ../../Zotlabs/Module/Import.php:568 ../../Zotlabs/Lib/Libzotdir.php:162
#: ../../Zotlabs/Lib/Libzotdir.php:163 ../../Zotlabs/Lib/Libzotdir.php:165
#: ../../extend/addon/hzaddons/dwpost/dwpost.php:73
#: ../../extend/addon/hzaddons/dwpost/dwpost.php:85
#: ../../extend/addon/hzaddons/fuzzloc/fuzzloc.php:178
-#: ../../extend/addon/hzaddons/rtof/rtof.php:81
-#: ../../extend/addon/hzaddons/rtof/rtof.php:85
-#: ../../extend/addon/hzaddons/ijpost/ijpost.php:73
-#: ../../extend/addon/hzaddons/ijpost/ijpost.php:85
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:49
+#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:62
#: ../../extend/addon/hzaddons/twitter/twitter.php:246
#: ../../extend/addon/hzaddons/twitter/twitter.php:255
#: ../../extend/addon/hzaddons/twitter/twitter.php:264
@@ -191,10 +190,9 @@ msgstr "Узкая панель навигации"
#: ../../extend/addon/hzaddons/nsabait/nsabait.php:157
#: ../../extend/addon/hzaddons/ljpost/ljpost.php:73
#: ../../extend/addon/hzaddons/ljpost/ljpost.php:85
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:389
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:411
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:415
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:424
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:260
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:282
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:291
#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:111
#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:59
#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:71
@@ -219,8 +217,7 @@ msgstr "Узкая панель навигации"
#: ../../extend/addon/hzaddons/visage/visage.php:166
#: ../../extend/addon/hzaddons/libertree/libertree.php:69
#: ../../extend/addon/hzaddons/libertree/libertree.php:81
-#: ../../extend/addon/hzaddons/redred/redred.php:95
-#: ../../extend/addon/hzaddons/redred/redred.php:99
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:63
#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:82
#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:86
msgid "No"
@@ -229,7 +226,7 @@ msgstr "Нет"
#: ../../view/theme/redbasic/php/config.php:99
#: ../../view/theme/redbasic/php/config.php:116 ../../include/dir_fns.php:143
#: ../../include/dir_fns.php:144 ../../include/dir_fns.php:145
-#: ../../boot.php:1629 ../../Zotlabs/Storage/Browser.php:405
+#: ../../boot.php:1630 ../../Zotlabs/Storage/Browser.php:405
#: ../../Zotlabs/Module/Defperms.php:197 ../../Zotlabs/Module/Profiles.php:681
#: ../../Zotlabs/Module/Photos.php:712 ../../Zotlabs/Module/Api.php:98
#: ../../Zotlabs/Module/Events.php:472 ../../Zotlabs/Module/Events.php:473
@@ -243,17 +240,15 @@ msgstr "Нет"
#: ../../Zotlabs/Module/Mitem.php:177 ../../Zotlabs/Module/Mitem.php:256
#: ../../Zotlabs/Module/Mitem.php:257 ../../Zotlabs/Module/Admin/Site.php:257
#: ../../Zotlabs/Module/Connedit.php:398 ../../Zotlabs/Module/Wiki.php:227
-#: ../../Zotlabs/Module/Wiki.php:228 ../../Zotlabs/Module/Import.php:554
-#: ../../Zotlabs/Module/Import.php:558 ../../Zotlabs/Module/Import.php:559
+#: ../../Zotlabs/Module/Wiki.php:228 ../../Zotlabs/Module/Import.php:563
+#: ../../Zotlabs/Module/Import.php:567 ../../Zotlabs/Module/Import.php:568
#: ../../Zotlabs/Lib/Libzotdir.php:162 ../../Zotlabs/Lib/Libzotdir.php:163
#: ../../Zotlabs/Lib/Libzotdir.php:165
#: ../../extend/addon/hzaddons/dwpost/dwpost.php:73
#: ../../extend/addon/hzaddons/dwpost/dwpost.php:85
#: ../../extend/addon/hzaddons/fuzzloc/fuzzloc.php:178
-#: ../../extend/addon/hzaddons/rtof/rtof.php:81
-#: ../../extend/addon/hzaddons/rtof/rtof.php:85
-#: ../../extend/addon/hzaddons/ijpost/ijpost.php:73
-#: ../../extend/addon/hzaddons/ijpost/ijpost.php:85
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:49
+#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:62
#: ../../extend/addon/hzaddons/twitter/twitter.php:246
#: ../../extend/addon/hzaddons/twitter/twitter.php:255
#: ../../extend/addon/hzaddons/twitter/twitter.php:264
@@ -270,10 +265,9 @@ msgstr "Нет"
#: ../../extend/addon/hzaddons/nsabait/nsabait.php:157
#: ../../extend/addon/hzaddons/ljpost/ljpost.php:73
#: ../../extend/addon/hzaddons/ljpost/ljpost.php:85
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:389
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:411
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:415
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:424
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:260
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:282
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:291
#: ../../extend/addon/hzaddons/channelreputation/channelreputation.php:111
#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:59
#: ../../extend/addon/hzaddons/cart/Settings/Cart.php:71
@@ -298,8 +292,7 @@ msgstr "Нет"
#: ../../extend/addon/hzaddons/visage/visage.php:166
#: ../../extend/addon/hzaddons/libertree/libertree.php:69
#: ../../extend/addon/hzaddons/libertree/libertree.php:81
-#: ../../extend/addon/hzaddons/redred/redred.php:95
-#: ../../extend/addon/hzaddons/redred/redred.php:99
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:63
#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:82
#: ../../extend/addon/hzaddons/wppost/Mod_Wppost.php:86
msgid "Yes"
@@ -662,7 +655,7 @@ msgstr "Всё равно"
msgid "Ask me"
msgstr "Спроси меня"
-#: ../../include/photos.php:27 ../../include/items.php:3701
+#: ../../include/photos.php:27 ../../include/items.php:3703
#: ../../include/attach.php:150 ../../include/attach.php:197
#: ../../include/attach.php:270 ../../include/attach.php:379
#: ../../include/attach.php:393 ../../include/attach.php:400
@@ -775,23 +768,23 @@ msgstr "Последние фотографии"
msgid "Upload New Photos"
msgstr "Загрузить новые фотографии"
-#: ../../include/oembed.php:224
+#: ../../include/oembed.php:226
msgid "View PDF"
msgstr "Просмотреть PDF"
-#: ../../include/oembed.php:352
+#: ../../include/oembed.php:356
msgid " by "
msgstr " по "
-#: ../../include/oembed.php:353
+#: ../../include/oembed.php:357
msgid " on "
msgstr " на "
-#: ../../include/oembed.php:382
+#: ../../include/oembed.php:386
msgid "Embedded content"
msgstr "Встроенное содержимое"
-#: ../../include/oembed.php:391
+#: ../../include/oembed.php:395
msgid "Embedding disabled"
msgstr "Встраивание отключено"
@@ -896,7 +889,7 @@ msgstr "Просмотреть все %d общих контактов"
#: ../../Zotlabs/Module/Wiki.php:211 ../../Zotlabs/Module/Wiki.php:384
#: ../../Zotlabs/Module/Layouts.php:193 ../../Zotlabs/Widget/Cdav.php:126
#: ../../Zotlabs/Widget/Cdav.php:162 ../../Zotlabs/Lib/Apps.php:534
-#: ../../Zotlabs/Lib/ThreadItem.php:130
+#: ../../Zotlabs/Lib/ThreadItem.php:133
msgid "Edit"
msgstr "Изменить"
@@ -1038,7 +1031,7 @@ msgstr "нравится этот канал"
#: ../../include/channel.php:1595 ../../include/conversation.php:1693
#: ../../include/taxonomy.php:661 ../../Zotlabs/Module/Photos.php:1175
-#: ../../Zotlabs/Lib/ThreadItem.php:218
+#: ../../Zotlabs/Lib/ThreadItem.php:221
msgctxt "noun"
msgid "Like"
msgid_plural "Likes"
@@ -1157,7 +1150,7 @@ msgstr "Экспорт"
msgid "cover photo"
msgstr "фотография обложки"
-#: ../../include/channel.php:2390 ../../boot.php:1625
+#: ../../include/channel.php:2390 ../../boot.php:1626
#: ../../Zotlabs/Module/Rmagic.php:75
msgid "Remote Authentication"
msgstr "Удаленная аутентификация"
@@ -1175,7 +1168,7 @@ msgstr "Проверка подлинности"
msgid "Account '%s' deleted"
msgstr "Аккаунт '%s' удален"
-#: ../../include/message.php:13 ../../include/text.php:1708
+#: ../../include/message.php:13 ../../include/text.php:1718
msgid "Download binary/encrypted content"
msgstr "Загрузить двоичное / зашифрованное содержимое"
@@ -1255,7 +1248,7 @@ msgstr "Видно только одобренным контактам."
msgid "Visible to specific connections."
msgstr "Видно указанным контактам."
-#: ../../include/items.php:3613 ../../Zotlabs/Module/Display.php:45
+#: ../../include/items.php:3615 ../../Zotlabs/Module/Display.php:45
#: ../../Zotlabs/Module/Display.php:452 ../../Zotlabs/Module/Admin.php:62
#: ../../Zotlabs/Module/Filestorage.php:24 ../../Zotlabs/Module/Viewsrc.php:25
#: ../../Zotlabs/Module/Admin/Addons.php:259
@@ -1263,67 +1256,67 @@ msgstr "Видно указанным контактам."
msgid "Item not found."
msgstr "Элемент не найден."
-#: ../../include/items.php:4193 ../../Zotlabs/Module/Group.php:61
+#: ../../include/items.php:4195 ../../Zotlabs/Module/Group.php:61
#: ../../Zotlabs/Module/Group.php:200
msgid "Privacy group not found."
msgstr "Группа безопасности не найдена."
-#: ../../include/items.php:4209
+#: ../../include/items.php:4211
msgid "Privacy group is empty."
msgstr "Группа безопасности пуста"
-#: ../../include/items.php:4216
+#: ../../include/items.php:4218
#, php-format
msgid "Privacy group: %s"
msgstr "Группа безопасности: %s"
-#: ../../include/items.php:4226 ../../Zotlabs/Module/Connedit.php:856
+#: ../../include/items.php:4228 ../../Zotlabs/Module/Connedit.php:856
#, php-format
msgid "Connection: %s"
msgstr "Контакт: %s"
-#: ../../include/items.php:4228
+#: ../../include/items.php:4230
msgid "Connection not found."
msgstr "Контакт не найден."
-#: ../../include/items.php:4570 ../../Zotlabs/Module/Cover_photo.php:269
+#: ../../include/items.php:4572 ../../Zotlabs/Module/Cover_photo.php:269
msgid "female"
msgstr "женщина"
-#: ../../include/items.php:4571 ../../Zotlabs/Module/Cover_photo.php:270
+#: ../../include/items.php:4573 ../../Zotlabs/Module/Cover_photo.php:270
#, php-format
msgid "%1$s updated her %2$s"
msgstr "%1$s обновила её %2$s"
-#: ../../include/items.php:4572 ../../Zotlabs/Module/Cover_photo.php:271
+#: ../../include/items.php:4574 ../../Zotlabs/Module/Cover_photo.php:271
msgid "male"
msgstr "мужчина"
-#: ../../include/items.php:4573 ../../Zotlabs/Module/Cover_photo.php:272
+#: ../../include/items.php:4575 ../../Zotlabs/Module/Cover_photo.php:272
#, php-format
msgid "%1$s updated his %2$s"
msgstr "%1$s обновил его %2$s"
-#: ../../include/items.php:4575 ../../Zotlabs/Module/Cover_photo.php:274
+#: ../../include/items.php:4577 ../../Zotlabs/Module/Cover_photo.php:274
#, php-format
msgid "%1$s updated their %2$s"
msgstr "%1$s обновили их %2$s"
-#: ../../include/items.php:4577
+#: ../../include/items.php:4579
msgid "profile photo"
msgstr "Фотография профиля"
-#: ../../include/items.php:4769
+#: ../../include/items.php:4771
#, php-format
msgid "[Edited %s]"
msgstr "[Отредактировано %s]"
-#: ../../include/items.php:4769
+#: ../../include/items.php:4771
msgctxt "edit_activity"
msgid "Post"
msgstr "Публикация"
-#: ../../include/items.php:4769
+#: ../../include/items.php:4771
msgctxt "edit_activity"
msgid "Comment"
msgstr "Комментарий"
@@ -1742,289 +1735,289 @@ msgstr "Поиск"
msgid "Save"
msgstr "Запомнить"
-#: ../../include/text.php:1145 ../../include/text.php:1149
+#: ../../include/text.php:1155 ../../include/text.php:1159
msgid "poke"
msgstr "Ткнуть"
-#: ../../include/text.php:1145 ../../include/text.php:1149
+#: ../../include/text.php:1155 ../../include/text.php:1159
#: ../../include/conversation.php:251
msgid "poked"
msgstr "ткнут"
-#: ../../include/text.php:1150
+#: ../../include/text.php:1160
msgid "ping"
msgstr "Пингануть"
-#: ../../include/text.php:1150
+#: ../../include/text.php:1160
msgid "pinged"
msgstr "Отпингован"
-#: ../../include/text.php:1151
+#: ../../include/text.php:1161
msgid "prod"
msgstr "Подтолкнуть"
-#: ../../include/text.php:1151
+#: ../../include/text.php:1161
msgid "prodded"
msgstr "Подтолкнут"
-#: ../../include/text.php:1152
+#: ../../include/text.php:1162
msgid "slap"
msgstr "Шлёпнуть"
-#: ../../include/text.php:1152
+#: ../../include/text.php:1162
msgid "slapped"
msgstr "Шлёпнут"
-#: ../../include/text.php:1153
+#: ../../include/text.php:1163
msgid "finger"
msgstr "Указать"
-#: ../../include/text.php:1153
+#: ../../include/text.php:1163
msgid "fingered"
msgstr "Указан"
-#: ../../include/text.php:1154
+#: ../../include/text.php:1164
msgid "rebuff"
msgstr "Дать отпор"
-#: ../../include/text.php:1154
+#: ../../include/text.php:1164
msgid "rebuffed"
msgstr "Дан отпор"
-#: ../../include/text.php:1177
+#: ../../include/text.php:1187
msgid "happy"
msgstr "счастливый"
-#: ../../include/text.php:1178
+#: ../../include/text.php:1188
msgid "sad"
msgstr "грустный"
-#: ../../include/text.php:1179
+#: ../../include/text.php:1189
msgid "mellow"
msgstr "спокойный"
-#: ../../include/text.php:1180
+#: ../../include/text.php:1190
msgid "tired"
msgstr "усталый"
-#: ../../include/text.php:1181
+#: ../../include/text.php:1191
msgid "perky"
msgstr "весёлый"
-#: ../../include/text.php:1182
+#: ../../include/text.php:1192
msgid "angry"
msgstr "сердитый"
-#: ../../include/text.php:1183
+#: ../../include/text.php:1193
msgid "stupefied"
msgstr "отупевший"
-#: ../../include/text.php:1184
+#: ../../include/text.php:1194
msgid "puzzled"
msgstr "недоумевающий"
-#: ../../include/text.php:1185
+#: ../../include/text.php:1195
msgid "interested"
msgstr "заинтересованный"
-#: ../../include/text.php:1186
+#: ../../include/text.php:1196
msgid "bitter"
msgstr "едкий"
-#: ../../include/text.php:1187
+#: ../../include/text.php:1197
msgid "cheerful"
msgstr "бодрый"
-#: ../../include/text.php:1188
+#: ../../include/text.php:1198
msgid "alive"
msgstr "энергичный"
-#: ../../include/text.php:1189
+#: ../../include/text.php:1199
msgid "annoyed"
msgstr "раздражённый"
-#: ../../include/text.php:1190
+#: ../../include/text.php:1200
msgid "anxious"
msgstr "обеспокоенный"
-#: ../../include/text.php:1191
+#: ../../include/text.php:1201
msgid "cranky"
msgstr "капризный"
-#: ../../include/text.php:1192
+#: ../../include/text.php:1202
msgid "disturbed"
msgstr "встревоженный"
-#: ../../include/text.php:1193
+#: ../../include/text.php:1203
msgid "frustrated"
msgstr "разочарованный"
-#: ../../include/text.php:1194
+#: ../../include/text.php:1204
msgid "depressed"
msgstr "подавленный"
-#: ../../include/text.php:1195
+#: ../../include/text.php:1205
msgid "motivated"
msgstr "мотивированный"
-#: ../../include/text.php:1196
+#: ../../include/text.php:1206
msgid "relaxed"
msgstr "расслабленный"
-#: ../../include/text.php:1197
+#: ../../include/text.php:1207
msgid "surprised"
msgstr "удивленный"
-#: ../../include/text.php:1376 ../../include/js_strings.php:95
+#: ../../include/text.php:1386 ../../include/js_strings.php:95
msgid "Monday"
msgstr "Понедельник"
-#: ../../include/text.php:1376 ../../include/js_strings.php:96
+#: ../../include/text.php:1386 ../../include/js_strings.php:96
msgid "Tuesday"
msgstr "Вторник"
-#: ../../include/text.php:1376 ../../include/js_strings.php:97
+#: ../../include/text.php:1386 ../../include/js_strings.php:97
msgid "Wednesday"
msgstr "Среда"
-#: ../../include/text.php:1376 ../../include/js_strings.php:98
+#: ../../include/text.php:1386 ../../include/js_strings.php:98
msgid "Thursday"
msgstr "Четверг"
-#: ../../include/text.php:1376 ../../include/js_strings.php:99
+#: ../../include/text.php:1386 ../../include/js_strings.php:99
msgid "Friday"
msgstr "Пятница"
-#: ../../include/text.php:1376 ../../include/js_strings.php:100
+#: ../../include/text.php:1386 ../../include/js_strings.php:100
msgid "Saturday"
msgstr "Суббота"
-#: ../../include/text.php:1376 ../../include/js_strings.php:94
+#: ../../include/text.php:1386 ../../include/js_strings.php:94
msgid "Sunday"
msgstr "Воскресенье"
-#: ../../include/text.php:1380 ../../include/js_strings.php:70
+#: ../../include/text.php:1390 ../../include/js_strings.php:70
msgid "January"
msgstr "Январь"
-#: ../../include/text.php:1380 ../../include/js_strings.php:71
+#: ../../include/text.php:1390 ../../include/js_strings.php:71
msgid "February"
msgstr "Февраль"
-#: ../../include/text.php:1380 ../../include/js_strings.php:72
+#: ../../include/text.php:1390 ../../include/js_strings.php:72
msgid "March"
msgstr "Март"
-#: ../../include/text.php:1380 ../../include/js_strings.php:73
+#: ../../include/text.php:1390 ../../include/js_strings.php:73
msgid "April"
msgstr "Апрель"
-#: ../../include/text.php:1380
+#: ../../include/text.php:1390
msgid "May"
msgstr "Май"
-#: ../../include/text.php:1380 ../../include/js_strings.php:75
+#: ../../include/text.php:1390 ../../include/js_strings.php:75
msgid "June"
msgstr "Июнь"
-#: ../../include/text.php:1380 ../../include/js_strings.php:76
+#: ../../include/text.php:1390 ../../include/js_strings.php:76
msgid "July"
msgstr "Июль"
-#: ../../include/text.php:1380 ../../include/js_strings.php:77
+#: ../../include/text.php:1390 ../../include/js_strings.php:77
msgid "August"
msgstr "Август"
-#: ../../include/text.php:1380 ../../include/js_strings.php:78
+#: ../../include/text.php:1390 ../../include/js_strings.php:78
msgid "September"
msgstr "Сентябрь"
-#: ../../include/text.php:1380 ../../include/js_strings.php:79
+#: ../../include/text.php:1390 ../../include/js_strings.php:79
msgid "October"
msgstr "Октябрь"
-#: ../../include/text.php:1380 ../../include/js_strings.php:80
+#: ../../include/text.php:1390 ../../include/js_strings.php:80
msgid "November"
msgstr "Ноябрь"
-#: ../../include/text.php:1380 ../../include/js_strings.php:81
+#: ../../include/text.php:1390 ../../include/js_strings.php:81
msgid "December"
msgstr "Декабрь"
-#: ../../include/text.php:1454
+#: ../../include/text.php:1464
msgid "Unknown Attachment"
msgstr "Неизвестное вложение"
-#: ../../include/text.php:1456 ../../Zotlabs/Storage/Browser.php:287
+#: ../../include/text.php:1466 ../../Zotlabs/Storage/Browser.php:287
#: ../../Zotlabs/Module/Sharedwithme.php:106
msgid "Size"
msgstr "Размер"
-#: ../../include/text.php:1456 ../../include/feedutils.php:860
+#: ../../include/text.php:1466 ../../include/feedutils.php:860
msgid "unknown"
msgstr "неизвестный"
-#: ../../include/text.php:1492
+#: ../../include/text.php:1502
msgid "remove category"
msgstr "удалить категорию"
-#: ../../include/text.php:1566
+#: ../../include/text.php:1576
msgid "remove from file"
msgstr "удалить из файла"
-#: ../../include/text.php:1849 ../../Zotlabs/Module/Events.php:663
+#: ../../include/text.php:1859 ../../Zotlabs/Module/Events.php:663
#: ../../Zotlabs/Module/Cal.php:314
msgid "Link to Source"
msgstr "Ссылка на источник"
-#: ../../include/text.php:1871 ../../include/language.php:423
+#: ../../include/text.php:1881 ../../include/language.php:423
msgid "default"
msgstr "по умолчанию"
-#: ../../include/text.php:1879
+#: ../../include/text.php:1889
msgid "Page layout"
msgstr "Шаблон страницы"
-#: ../../include/text.php:1879
+#: ../../include/text.php:1889
msgid "You can create your own with the layouts tool"
msgstr "Вы можете создать свой собственный с помощью инструмента шаблонов"
-#: ../../include/text.php:1889 ../../Zotlabs/Module/Wiki.php:217
+#: ../../include/text.php:1899 ../../Zotlabs/Module/Wiki.php:217
#: ../../Zotlabs/Module/Wiki.php:371 ../../Zotlabs/Widget/Wiki_pages.php:38
#: ../../Zotlabs/Widget/Wiki_pages.php:95
msgid "BBcode"
msgstr ""
-#: ../../include/text.php:1890
+#: ../../include/text.php:1900
msgid "HTML"
msgstr ""
-#: ../../include/text.php:1891 ../../Zotlabs/Module/Wiki.php:217
+#: ../../include/text.php:1901 ../../Zotlabs/Module/Wiki.php:217
#: ../../Zotlabs/Module/Wiki.php:371 ../../Zotlabs/Widget/Wiki_pages.php:38
#: ../../Zotlabs/Widget/Wiki_pages.php:95
#: ../../extend/addon/hzaddons/mdpost/mdpost.php:41
msgid "Markdown"
msgstr "Разметка Markdown"
-#: ../../include/text.php:1892 ../../Zotlabs/Module/Wiki.php:217
+#: ../../include/text.php:1902 ../../Zotlabs/Module/Wiki.php:217
#: ../../Zotlabs/Widget/Wiki_pages.php:38
#: ../../Zotlabs/Widget/Wiki_pages.php:95
msgid "Text"
msgstr "Текст"
-#: ../../include/text.php:1893
+#: ../../include/text.php:1903
msgid "Comanche Layout"
msgstr "Шаблон Comanche"
-#: ../../include/text.php:1898
+#: ../../include/text.php:1908
msgid "PHP"
msgstr ""
-#: ../../include/text.php:1907
+#: ../../include/text.php:1917
msgid "Page content type"
msgstr "Тип содержимого страницы"
-#: ../../include/text.php:2027 ../../include/conversation.php:116
+#: ../../include/text.php:2037 ../../include/conversation.php:116
#: ../../Zotlabs/Module/Tagger.php:69 ../../Zotlabs/Module/Like.php:387
#: ../../Zotlabs/Module/Subthread.php:112 ../../Zotlabs/Lib/Activity.php:1570
#: ../../extend/addon/hzaddons/redphotos/redphotohelper.php:71
@@ -2033,13 +2026,13 @@ msgstr "Тип содержимого страницы"
msgid "photo"
msgstr "фото"
-#: ../../include/text.php:2030 ../../include/conversation.php:119
+#: ../../include/text.php:2040 ../../include/conversation.php:119
#: ../../include/event.php:1156 ../../Zotlabs/Module/Tagger.php:73
#: ../../Zotlabs/Module/Events.php:260 ../../Zotlabs/Module/Like.php:389
msgid "event"
msgstr "событие"
-#: ../../include/text.php:2033 ../../include/conversation.php:144
+#: ../../include/text.php:2043 ../../include/conversation.php:144
#: ../../Zotlabs/Module/Like.php:387 ../../Zotlabs/Module/Subthread.php:112
#: ../../Zotlabs/Lib/Activity.php:1570
#: ../../extend/addon/hzaddons/pubcrawl/as.php:1494
@@ -2047,104 +2040,104 @@ msgstr "событие"
msgid "status"
msgstr "статус"
-#: ../../include/text.php:2035 ../../include/conversation.php:146
+#: ../../include/text.php:2045 ../../include/conversation.php:146
#: ../../Zotlabs/Module/Tagger.php:79
msgid "comment"
msgstr "комментарий"
-#: ../../include/text.php:2040
+#: ../../include/text.php:2050
msgid "activity"
msgstr "активность"
-#: ../../include/text.php:2141
+#: ../../include/text.php:2151
msgid "a-z, 0-9, -, and _ only"
msgstr "Только a-z, 0-9, -, и _"
-#: ../../include/text.php:2461
+#: ../../include/text.php:2471
msgid "Design Tools"
msgstr "Инструменты дизайна"
-#: ../../include/text.php:2464 ../../Zotlabs/Module/Blocks.php:154
+#: ../../include/text.php:2474 ../../Zotlabs/Module/Blocks.php:154
msgid "Blocks"
msgstr "Блокировки"
-#: ../../include/text.php:2465 ../../Zotlabs/Module/Menu.php:170
+#: ../../include/text.php:2475 ../../Zotlabs/Module/Menu.php:170
msgid "Menus"
msgstr "Меню"
-#: ../../include/text.php:2466 ../../Zotlabs/Module/Layouts.php:184
+#: ../../include/text.php:2476 ../../Zotlabs/Module/Layouts.php:184
msgid "Layouts"
msgstr "Шаблоны"
-#: ../../include/text.php:2467
+#: ../../include/text.php:2477
msgid "Pages"
msgstr "Страницы"
-#: ../../include/text.php:2488 ../../Zotlabs/Module/Cal.php:343
+#: ../../include/text.php:2498 ../../Zotlabs/Module/Cal.php:343
msgid "Import"
msgstr "Импортировать"
-#: ../../include/text.php:2489
+#: ../../include/text.php:2499
msgid "Import website..."
msgstr "Импорт веб-сайта..."
-#: ../../include/text.php:2490
+#: ../../include/text.php:2500
msgid "Select folder to import"
msgstr "Выбрать каталог для импорта"
-#: ../../include/text.php:2491
+#: ../../include/text.php:2501
msgid "Import from a zipped folder:"
msgstr "Импортировать из каталога в zip-архиве:"
-#: ../../include/text.php:2492
+#: ../../include/text.php:2502
msgid "Import from cloud files:"
msgstr "Импортировать из сетевых файлов:"
-#: ../../include/text.php:2493
+#: ../../include/text.php:2503
msgid "/cloud/channel/path/to/folder"
msgstr ""
-#: ../../include/text.php:2494
+#: ../../include/text.php:2504
msgid "Enter path to website files"
msgstr "Введите путь к файлам веб-сайта"
-#: ../../include/text.php:2495
+#: ../../include/text.php:2505
msgid "Select folder"
msgstr "Выбрать каталог"
-#: ../../include/text.php:2496
+#: ../../include/text.php:2506
msgid "Export website..."
msgstr "Экспорт веб-сайта..."
-#: ../../include/text.php:2497
+#: ../../include/text.php:2507
msgid "Export to a zip file"
msgstr "Экспортировать в ZIP файл."
-#: ../../include/text.php:2498
+#: ../../include/text.php:2508
msgid "website.zip"
msgstr ""
-#: ../../include/text.php:2499
+#: ../../include/text.php:2509
msgid "Enter a name for the zip file."
msgstr "Введите имя для ZIP файла."
-#: ../../include/text.php:2500
+#: ../../include/text.php:2510
msgid "Export to cloud files"
msgstr "Эскпортировать в сетевые файлы:"
-#: ../../include/text.php:2501
+#: ../../include/text.php:2511
msgid "/path/to/export/folder"
msgstr ""
-#: ../../include/text.php:2502
+#: ../../include/text.php:2512
msgid "Enter a path to a cloud files destination."
msgstr "Введите путь к расположению сетевых файлов."
-#: ../../include/text.php:2503
+#: ../../include/text.php:2513
msgid "Specify folder"
msgstr "Указать каталог"
-#: ../../include/text.php:2823 ../../Zotlabs/Storage/Browser.php:131
+#: ../../include/text.php:2833 ../../Zotlabs/Storage/Browser.php:131
msgid "Collection"
msgstr "Коллекция"
@@ -2467,7 +2460,7 @@ msgctxt "mood"
msgid "%1$s is %2$s"
msgstr "%1$s в %2$s"
-#: ../../include/conversation.php:483 ../../Zotlabs/Lib/ThreadItem.php:443
+#: ../../include/conversation.php:483 ../../Zotlabs/Lib/ThreadItem.php:446
msgid "This is an unsaved preview"
msgstr "Это несохранённый просмотр"
@@ -2511,7 +2504,7 @@ msgctxt "title"
msgid "Might attend"
msgstr "Возможно посещу"
-#: ../../include/conversation.php:690 ../../Zotlabs/Lib/ThreadItem.php:160
+#: ../../include/conversation.php:690 ../../Zotlabs/Lib/ThreadItem.php:163
msgid "Select"
msgstr "Выбрать"
@@ -2531,23 +2524,23 @@ msgstr "Выбрать"
#: ../../Zotlabs/Module/Card_edit.php:129
#: ../../Zotlabs/Module/Article_edit.php:129
#: ../../Zotlabs/Module/Blocks.php:162 ../../Zotlabs/Lib/Apps.php:535
-#: ../../Zotlabs/Lib/ThreadItem.php:150
+#: ../../Zotlabs/Lib/ThreadItem.php:153
msgid "Delete"
msgstr "Удалить"
-#: ../../include/conversation.php:695 ../../Zotlabs/Lib/ThreadItem.php:249
+#: ../../include/conversation.php:695 ../../Zotlabs/Lib/ThreadItem.php:252
msgid "Toggle Star Status"
msgstr "Переключить статус пометки"
-#: ../../include/conversation.php:700 ../../Zotlabs/Lib/ThreadItem.php:99
+#: ../../include/conversation.php:700 ../../Zotlabs/Lib/ThreadItem.php:102
msgid "Private Message"
msgstr "Личное сообщение"
-#: ../../include/conversation.php:707 ../../Zotlabs/Lib/ThreadItem.php:260
+#: ../../include/conversation.php:707 ../../Zotlabs/Lib/ThreadItem.php:263
msgid "Message signature validated"
msgstr "Подпись сообщения проверена"
-#: ../../include/conversation.php:708 ../../Zotlabs/Lib/ThreadItem.php:261
+#: ../../include/conversation.php:708 ../../Zotlabs/Lib/ThreadItem.php:264
msgid "Message signature incorrect"
msgstr "Подпись сообщения неверная"
@@ -2570,17 +2563,17 @@ msgstr "Категории:"
msgid "Filed under:"
msgstr "Хранить под:"
-#: ../../include/conversation.php:766 ../../Zotlabs/Lib/ThreadItem.php:378
+#: ../../include/conversation.php:766 ../../Zotlabs/Lib/ThreadItem.php:381
#, php-format
msgid "from %s"
msgstr "от %s"
-#: ../../include/conversation.php:769 ../../Zotlabs/Lib/ThreadItem.php:381
+#: ../../include/conversation.php:769 ../../Zotlabs/Lib/ThreadItem.php:384
#, php-format
msgid "last edited: %s"
msgstr "последнее редактирование: %s"
-#: ../../include/conversation.php:770 ../../Zotlabs/Lib/ThreadItem.php:382
+#: ../../include/conversation.php:770 ../../Zotlabs/Lib/ThreadItem.php:385
#, php-format
msgid "Expires: %s"
msgstr "Срок действия: %s"
@@ -2590,7 +2583,7 @@ msgid "View in context"
msgstr "Показать в контексте"
#: ../../include/conversation.php:787 ../../Zotlabs/Module/Photos.php:1118
-#: ../../Zotlabs/Lib/ThreadItem.php:444
+#: ../../Zotlabs/Lib/ThreadItem.php:447
msgid "Please wait"
msgstr "Подождите пожалуйста"
@@ -2602,7 +2595,7 @@ msgstr "удалить"
msgid "Loading..."
msgstr "Загрузка..."
-#: ../../include/conversation.php:891 ../../Zotlabs/Lib/ThreadItem.php:273
+#: ../../include/conversation.php:891 ../../Zotlabs/Lib/ThreadItem.php:276
msgid "Conversation Tools"
msgstr "Инструменты общения"
@@ -2798,7 +2791,7 @@ msgstr "Комментарии отключены"
#: ../../include/conversation.php:1356 ../../Zotlabs/Module/Photos.php:1138
#: ../../Zotlabs/Module/Events.php:480 ../../Zotlabs/Module/Webpages.php:262
-#: ../../Zotlabs/Lib/ThreadItem.php:780
+#: ../../Zotlabs/Lib/ThreadItem.php:783
#: ../../extend/addon/hzaddons/hsse/hsse.php:153
msgid "Preview"
msgstr "Предварительный просмотр"
@@ -2821,32 +2814,32 @@ msgstr "Название ссылки на страницу "
msgid "Post as"
msgstr "Опубликовать как"
-#: ../../include/conversation.php:1403 ../../Zotlabs/Lib/ThreadItem.php:771
+#: ../../include/conversation.php:1403 ../../Zotlabs/Lib/ThreadItem.php:774
#: ../../extend/addon/hzaddons/hsse/hsse.php:200
msgid "Bold"
msgstr "Жирный"
-#: ../../include/conversation.php:1404 ../../Zotlabs/Lib/ThreadItem.php:772
+#: ../../include/conversation.php:1404 ../../Zotlabs/Lib/ThreadItem.php:775
#: ../../extend/addon/hzaddons/hsse/hsse.php:201
msgid "Italic"
msgstr "Курсив"
-#: ../../include/conversation.php:1405 ../../Zotlabs/Lib/ThreadItem.php:773
+#: ../../include/conversation.php:1405 ../../Zotlabs/Lib/ThreadItem.php:776
#: ../../extend/addon/hzaddons/hsse/hsse.php:202
msgid "Underline"
msgstr "Подчеркнутый"
-#: ../../include/conversation.php:1406 ../../Zotlabs/Lib/ThreadItem.php:774
+#: ../../include/conversation.php:1406 ../../Zotlabs/Lib/ThreadItem.php:777
#: ../../extend/addon/hzaddons/hsse/hsse.php:203
msgid "Quote"
msgstr "Цитата"
-#: ../../include/conversation.php:1407 ../../Zotlabs/Lib/ThreadItem.php:775
+#: ../../include/conversation.php:1407 ../../Zotlabs/Lib/ThreadItem.php:778
#: ../../extend/addon/hzaddons/hsse/hsse.php:204
msgid "Code"
msgstr "Код"
-#: ../../include/conversation.php:1408 ../../Zotlabs/Lib/ThreadItem.php:777
+#: ../../include/conversation.php:1408 ../../Zotlabs/Lib/ThreadItem.php:780
#: ../../extend/addon/hzaddons/hsse/hsse.php:205
msgid "Attach/Upload file"
msgstr "Прикрепить/загрузить файл"
@@ -2936,13 +2929,13 @@ msgstr "Установить дату публикации"
#: ../../include/conversation.php:1458 ../../Zotlabs/Module/Mail.php:294
#: ../../Zotlabs/Module/Mail.php:436 ../../Zotlabs/Module/Chat.php:221
-#: ../../Zotlabs/Lib/ThreadItem.php:784
+#: ../../Zotlabs/Lib/ThreadItem.php:787
#: ../../extend/addon/hzaddons/hsse/hsse.php:255
msgid "Encrypt text"
msgstr "Зашифровать текст"
#: ../../include/conversation.php:1696 ../../Zotlabs/Module/Photos.php:1180
-#: ../../Zotlabs/Lib/ThreadItem.php:223
+#: ../../Zotlabs/Lib/ThreadItem.php:226
msgctxt "noun"
msgid "Dislike"
msgid_plural "Dislikes"
@@ -3025,7 +3018,7 @@ msgstr "хотеть"
msgid "wants"
msgstr "хотеть"
-#: ../../include/taxonomy.php:575 ../../Zotlabs/Lib/ThreadItem.php:289
+#: ../../include/taxonomy.php:575 ../../Zotlabs/Lib/ThreadItem.php:292
msgid "like"
msgstr "нравится"
@@ -3033,7 +3026,7 @@ msgstr "нравится"
msgid "likes"
msgstr "нравится"
-#: ../../include/taxonomy.php:576 ../../Zotlabs/Lib/ThreadItem.php:290
+#: ../../include/taxonomy.php:576 ../../Zotlabs/Lib/ThreadItem.php:293
msgid "dislike"
msgstr "не нравится"
@@ -3050,11 +3043,11 @@ msgid "Delete this item?"
msgstr "Удалить этот элемент?"
#: ../../include/js_strings.php:6 ../../Zotlabs/Module/Photos.php:1136
-#: ../../Zotlabs/Module/Photos.php:1254 ../../Zotlabs/Lib/ThreadItem.php:769
+#: ../../Zotlabs/Module/Photos.php:1254 ../../Zotlabs/Lib/ThreadItem.php:772
msgid "Comment"
msgstr "Комментарий"
-#: ../../include/js_strings.php:7 ../../Zotlabs/Lib/ThreadItem.php:476
+#: ../../include/js_strings.php:7 ../../Zotlabs/Lib/ThreadItem.php:479
#, php-format
msgid "%s show all"
msgstr "%s показать всё"
@@ -3387,27 +3380,27 @@ msgstr "Только публичные форумы"
msgid "This Website Only"
msgstr "Только этот веб-сайт"
-#: ../../include/network.php:770
+#: ../../include/network.php:771
msgid "view full size"
msgstr "посмотреть в полный размер"
-#: ../../include/network.php:1773 ../../include/network.php:1774
+#: ../../include/network.php:1774 ../../include/network.php:1775
msgid "Friendica"
msgstr ""
-#: ../../include/network.php:1775
+#: ../../include/network.php:1776
msgid "OStatus"
msgstr ""
-#: ../../include/network.php:1776
+#: ../../include/network.php:1777
msgid "GNU-Social"
msgstr ""
-#: ../../include/network.php:1777
+#: ../../include/network.php:1778
msgid "RSS/Atom"
msgstr ""
-#: ../../include/network.php:1778 ../../Zotlabs/Lib/Activity.php:1417
+#: ../../include/network.php:1779 ../../Zotlabs/Lib/Activity.php:1417
#: ../../Zotlabs/Lib/Activity.php:1614
#: ../../extend/addon/hzaddons/pubcrawl/as.php:1204
#: ../../extend/addon/hzaddons/pubcrawl/as.php:1359
@@ -3415,39 +3408,39 @@ msgstr ""
msgid "ActivityPub"
msgstr ""
-#: ../../include/network.php:1779 ../../Zotlabs/Module/Cdav.php:1219
+#: ../../include/network.php:1780 ../../Zotlabs/Module/Cdav.php:1219
#: ../../Zotlabs/Module/Profiles.php:787
#: ../../Zotlabs/Module/Admin/Accounts.php:171
#: ../../Zotlabs/Module/Admin/Accounts.php:183
#: ../../Zotlabs/Module/Connedit.php:916
-#: ../../extend/addon/hzaddons/rtof/rtof.php:93
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:57
#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:56
#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:57
-#: ../../extend/addon/hzaddons/redred/redred.php:107
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:71
msgid "Email"
msgstr "Электронная почта"
-#: ../../include/network.php:1780
+#: ../../include/network.php:1781
msgid "Diaspora"
msgstr ""
-#: ../../include/network.php:1781
+#: ../../include/network.php:1782
msgid "Facebook"
msgstr ""
-#: ../../include/network.php:1782
+#: ../../include/network.php:1783
msgid "Zot"
msgstr ""
-#: ../../include/network.php:1783
+#: ../../include/network.php:1784
msgid "LinkedIn"
msgstr ""
-#: ../../include/network.php:1784
+#: ../../include/network.php:1785
msgid "XMPP/IM"
msgstr ""
-#: ../../include/network.php:1785
+#: ../../include/network.php:1786
msgid "MySpace"
msgstr ""
@@ -3475,7 +3468,7 @@ msgstr "YYYY-MM-DD или MM-DD"
msgid "Required"
msgstr "Требуется"
-#: ../../include/datetime.php:238 ../../boot.php:2557
+#: ../../include/datetime.php:238 ../../boot.php:2558
msgid "never"
msgstr "никогда"
@@ -3601,7 +3594,7 @@ msgid "Permissions"
msgstr "Разрешения"
#: ../../include/acl_selectors.php:125 ../../Zotlabs/Module/Photos.php:1308
-#: ../../Zotlabs/Lib/ThreadItem.php:438
+#: ../../Zotlabs/Lib/ThreadItem.php:441
msgid "Close"
msgstr "Закрыть"
@@ -3749,7 +3742,7 @@ msgid "Account/Channel Settings"
msgstr "Настройки аккаунта / канала"
#: ../../include/nav.php:103 ../../include/nav.php:132
-#: ../../include/nav.php:151 ../../boot.php:1623
+#: ../../include/nav.php:151 ../../boot.php:1624
msgid "Logout"
msgstr "Выход"
@@ -3769,7 +3762,7 @@ msgstr "Управление / редактирование профилей"
msgid "Edit your profile"
msgstr "Редактировать профиль"
-#: ../../include/nav.php:118 ../../include/nav.php:122 ../../boot.php:1624
+#: ../../include/nav.php:118 ../../include/nav.php:122 ../../boot.php:1625
#: ../../Zotlabs/Lib/Apps.php:311
msgid "Login"
msgstr "Войти"
@@ -3786,7 +3779,7 @@ msgstr "Домой"
msgid "Log me out of this site"
msgstr "Выйти с этого сайта"
-#: ../../include/nav.php:156 ../../boot.php:1604
+#: ../../include/nav.php:156 ../../boot.php:1605
#: ../../Zotlabs/Module/Register.php:289
msgid "Register"
msgstr "Регистрация"
@@ -3989,51 +3982,51 @@ msgstr "ошибка при записи базы данных."
msgid "Empty path"
msgstr "Пустое имя пути"
-#: ../../include/photo/photo_driver.php:774
+#: ../../include/photo/photo_driver.php:779
#: ../../Zotlabs/Module/Profile_photo.php:120
#: ../../Zotlabs/Module/Profile_photo.php:248
msgid "Profile Photos"
msgstr "Фотографии профиля"
-#: ../../boot.php:1603
+#: ../../boot.php:1604
msgid "Create an account to access services and applications"
msgstr "Создайте аккаунт для доступа к службам и приложениям"
-#: ../../boot.php:1627
+#: ../../boot.php:1628
msgid "Login/Email"
msgstr "Пользователь / email"
-#: ../../boot.php:1628
+#: ../../boot.php:1629
msgid "Password"
msgstr "Пароль"
-#: ../../boot.php:1629
+#: ../../boot.php:1630
msgid "Remember me"
msgstr "Запомнить меня"
-#: ../../boot.php:1632
+#: ../../boot.php:1633
msgid "Forgot your password?"
msgstr "Забыли пароль или логин?"
-#: ../../boot.php:1633 ../../Zotlabs/Module/Lostpass.php:91
+#: ../../boot.php:1634 ../../Zotlabs/Module/Lostpass.php:91
msgid "Password Reset"
msgstr "Сбросить пароль"
-#: ../../boot.php:2430
+#: ../../boot.php:2431
#, php-format
msgid "[$Projectname] Website SSL error for %s"
msgstr "[$Projectname] Ошибка SSL/TLS веб-сайта для %s"
-#: ../../boot.php:2435
+#: ../../boot.php:2436
msgid "Website SSL certificate is not valid. Please correct."
msgstr "SSL/TLS сертификат веб-сайт недействителен. Исправьте это."
-#: ../../boot.php:2551
+#: ../../boot.php:2552
#, php-format
msgid "[$Projectname] Cron tasks not running on %s"
msgstr "[$Projectname] Задания Cron не запущены на %s"
-#: ../../boot.php:2556
+#: ../../boot.php:2557
msgid "Cron/Scheduled tasks not running."
msgstr "Задания Cron / планировщика не запущены."
@@ -4079,7 +4072,7 @@ msgstr "Создать"
msgid "Add Files"
msgstr "Добавить файлы"
-#: ../../Zotlabs/Storage/Browser.php:280 ../../Zotlabs/Lib/ThreadItem.php:154
+#: ../../Zotlabs/Storage/Browser.php:280 ../../Zotlabs/Lib/ThreadItem.php:157
msgid "Admin Delete"
msgstr "Удалено администратором"
@@ -4261,15 +4254,15 @@ msgstr "Отправить ответ"
msgid "Your message for %s (%s):"
msgstr "Ваше сообщение для %s (%s):"
-#: ../../Zotlabs/Module/Pconfig.php:27 ../../Zotlabs/Module/Pconfig.php:63
+#: ../../Zotlabs/Module/Pconfig.php:32 ../../Zotlabs/Module/Pconfig.php:68
msgid "This setting requires special processing and editing has been blocked."
msgstr "Этот параметр требует специальной обработки и редактирования и был заблокирован."
-#: ../../Zotlabs/Module/Pconfig.php:52
+#: ../../Zotlabs/Module/Pconfig.php:57
msgid "Configuration Editor"
msgstr "Редактор конфигурации"
-#: ../../Zotlabs/Module/Pconfig.php:53
+#: ../../Zotlabs/Module/Pconfig.php:58
msgid ""
"Warning: Changing some settings could render your channel inoperable. Please "
"leave this page unless you are comfortable with and knowledgeable about how "
@@ -4284,7 +4277,7 @@ msgstr "Не удалось получить доступ к записи кон
#: ../../Zotlabs/Module/Settings/Channel.php:266
#: ../../extend/addon/hzaddons/twitter/twitter.php:775
#: ../../extend/addon/hzaddons/logrot/logrot.php:54
-#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:184
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:185
#: ../../extend/addon/hzaddons/rendezvous/rendezvous.php:82
#: ../../extend/addon/hzaddons/piwik/piwik.php:116
#: ../../extend/addon/hzaddons/msgfooter/msgfooter.php:54
@@ -4514,7 +4507,7 @@ msgid "Privacy group: "
msgstr "Группа безопасности: "
#: ../../Zotlabs/Module/Network.php:316
-#: ../../extend/addon/hzaddons/redred/redred.php:65
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:29
msgid "Invalid channel."
msgstr "Недействительный канал."
@@ -4617,39 +4610,39 @@ msgstr "Статья"
msgid "Item has been removed."
msgstr "Элемент был удалён."
-#: ../../Zotlabs/Module/Ping.php:337
+#: ../../Zotlabs/Module/Ping.php:338
msgid "sent you a private message"
msgstr "отправил вам личное сообщение"
-#: ../../Zotlabs/Module/Ping.php:390
+#: ../../Zotlabs/Module/Ping.php:392
msgid "added your channel"
msgstr "добавил ваш канал"
-#: ../../Zotlabs/Module/Ping.php:414
+#: ../../Zotlabs/Module/Ping.php:417
msgid "requires approval"
msgstr "Требуется подтверждение"
-#: ../../Zotlabs/Module/Ping.php:424
+#: ../../Zotlabs/Module/Ping.php:427
msgid "g A l F d"
msgstr "g A l F d"
-#: ../../Zotlabs/Module/Ping.php:442
+#: ../../Zotlabs/Module/Ping.php:445
msgid "[today]"
msgstr "[сегодня]"
-#: ../../Zotlabs/Module/Ping.php:451
+#: ../../Zotlabs/Module/Ping.php:455
msgid "posted an event"
msgstr "событие опубликовано"
-#: ../../Zotlabs/Module/Ping.php:484
+#: ../../Zotlabs/Module/Ping.php:489
msgid "shared a file with you"
msgstr "с вами поделились файлом"
-#: ../../Zotlabs/Module/Ping.php:665
+#: ../../Zotlabs/Module/Ping.php:671
msgid "Private forum"
msgstr "Частный форум"
-#: ../../Zotlabs/Module/Ping.php:665
+#: ../../Zotlabs/Module/Ping.php:671
msgid "Public forum"
msgstr "Публичный форум"
@@ -5630,21 +5623,21 @@ msgstr "Пример: @bob, @Barbara_Jensen, @jim@example.com"
msgid "Flag as adult in album view"
msgstr "Пометить как альбом \"для взрослых\""
-#: ../../Zotlabs/Module/Photos.php:1115 ../../Zotlabs/Lib/ThreadItem.php:289
+#: ../../Zotlabs/Module/Photos.php:1115 ../../Zotlabs/Lib/ThreadItem.php:292
msgid "I like this (toggle)"
msgstr "мне это нравится (переключение)"
-#: ../../Zotlabs/Module/Photos.php:1116 ../../Zotlabs/Lib/ThreadItem.php:290
+#: ../../Zotlabs/Module/Photos.php:1116 ../../Zotlabs/Lib/ThreadItem.php:293
msgid "I don't like this (toggle)"
msgstr "мне это не нравится (переключение)"
#: ../../Zotlabs/Module/Photos.php:1134 ../../Zotlabs/Module/Photos.php:1252
-#: ../../Zotlabs/Lib/ThreadItem.php:767
+#: ../../Zotlabs/Lib/ThreadItem.php:770
msgid "This is you"
msgstr "Это вы"
#: ../../Zotlabs/Module/Photos.php:1171 ../../Zotlabs/Module/Photos.php:1183
-#: ../../Zotlabs/Lib/ThreadItem.php:214 ../../Zotlabs/Lib/ThreadItem.php:226
+#: ../../Zotlabs/Lib/ThreadItem.php:217 ../../Zotlabs/Lib/ThreadItem.php:229
msgid "View all"
msgstr "Просмотреть все"
@@ -5660,12 +5653,12 @@ msgstr "На этой фотографии:"
msgid "Map"
msgstr "Карта"
-#: ../../Zotlabs/Module/Photos.php:1302 ../../Zotlabs/Lib/ThreadItem.php:432
+#: ../../Zotlabs/Module/Photos.php:1302 ../../Zotlabs/Lib/ThreadItem.php:435
msgctxt "noun"
msgid "Likes"
msgstr "Нравится"
-#: ../../Zotlabs/Module/Photos.php:1303 ../../Zotlabs/Lib/ThreadItem.php:433
+#: ../../Zotlabs/Module/Photos.php:1303 ../../Zotlabs/Lib/ThreadItem.php:436
msgctxt "noun"
msgid "Dislikes"
msgstr "Не нравится"
@@ -5823,7 +5816,7 @@ msgstr "Название приложения"
#: ../../Zotlabs/Module/Oauth.php:114 ../../Zotlabs/Module/Oauth.php:140
#: ../../extend/addon/hzaddons/twitter/twitter.php:784
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:894
+#: ../../extend/addon/hzaddons/statusnet/statusnet.php:596
msgid "Consumer Key"
msgstr "Ключ клиента"
@@ -5835,7 +5828,7 @@ msgstr "Сгенерирован автоматические - измените
#: ../../Zotlabs/Module/Oauth.php:115 ../../Zotlabs/Module/Oauth.php:141
#: ../../Zotlabs/Module/Oauth2.php:119 ../../Zotlabs/Module/Oauth2.php:147
#: ../../extend/addon/hzaddons/twitter/twitter.php:785
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:893
+#: ../../extend/addon/hzaddons/statusnet/statusnet.php:595
msgid "Consumer Secret"
msgstr "Код клиента"
@@ -8749,7 +8742,7 @@ msgid "Policies"
msgstr "Правила"
#: ../../Zotlabs/Module/Admin/Site.php:297
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:891
+#: ../../extend/addon/hzaddons/statusnet/statusnet.php:593
msgid "Site name"
msgstr "Название сайта"
@@ -9464,7 +9457,7 @@ msgid "Their Settings"
msgstr "Их настройки"
#: ../../Zotlabs/Module/Notifications.php:60
-#: ../../Zotlabs/Lib/ThreadItem.php:425
+#: ../../Zotlabs/Lib/ThreadItem.php:428
msgid "Mark all seen"
msgstr "Отметить как просмотренное"
@@ -10580,7 +10573,7 @@ msgstr "Введите название каталога"
msgid "or select an existing folder (doubleclick)"
msgstr "или выберите существующий каталог (двойной щелчок)"
-#: ../../Zotlabs/Module/Filer.php:54 ../../Zotlabs/Lib/ThreadItem.php:164
+#: ../../Zotlabs/Module/Filer.php:54 ../../Zotlabs/Lib/ThreadItem.php:167
msgid "Save to Folder"
msgstr "Сохранить в каталог"
@@ -10651,61 +10644,61 @@ msgstr "Невозможно загрузить данные со старого
msgid "Imported file is empty."
msgstr "Импортированный файл пуст."
-#: ../../Zotlabs/Module/Import.php:146
+#: ../../Zotlabs/Module/Import.php:155
#, php-format
msgid "Your service plan only allows %d channels."
msgstr "Ваш класс обслуживания разрешает только %d каналов."
-#: ../../Zotlabs/Module/Import.php:173
+#: ../../Zotlabs/Module/Import.php:182
msgid "No channel. Import failed."
msgstr "Канала нет. Импорт невозможен."
-#: ../../Zotlabs/Module/Import.php:513
+#: ../../Zotlabs/Module/Import.php:522
#: ../../extend/addon/hzaddons/diaspora/import_diaspora.php:141
msgid "Import completed."
msgstr "Импорт завершен."
-#: ../../Zotlabs/Module/Import.php:541
+#: ../../Zotlabs/Module/Import.php:550
msgid "You must be logged in to use this feature."
msgstr "Вы должны войти в систему, чтобы использовать эту функцию."
-#: ../../Zotlabs/Module/Import.php:546
+#: ../../Zotlabs/Module/Import.php:555
msgid "Import Channel"
msgstr "Импортировать канал"
-#: ../../Zotlabs/Module/Import.php:547
+#: ../../Zotlabs/Module/Import.php:556
msgid ""
"Use this form to import an existing channel from a different server/hub. You "
"may retrieve the channel identity from the old server/hub via the network or "
"provide an export file."
msgstr "Используйте эту форм для импорта существующего канала с другого сервера / хаба. Вы можете получить идентификационные данные канала со старого сервера / хаба через сеть или предоставить файл экспорта."
-#: ../../Zotlabs/Module/Import.php:548
+#: ../../Zotlabs/Module/Import.php:557
#: ../../Zotlabs/Module/Import_items.php:127
msgid "File to Upload"
msgstr "Файл для загрузки"
-#: ../../Zotlabs/Module/Import.php:549
+#: ../../Zotlabs/Module/Import.php:558
msgid "Or provide the old server/hub details"
msgstr "или предоставьте данные старого сервера"
-#: ../../Zotlabs/Module/Import.php:551
+#: ../../Zotlabs/Module/Import.php:560
msgid "Your old identity address (xyz@example.com)"
msgstr "Ваш старый адрес идентичности (xyz@example.com)"
-#: ../../Zotlabs/Module/Import.php:552
+#: ../../Zotlabs/Module/Import.php:561
msgid "Your old login email address"
msgstr "Ваш старый адрес электронной почты"
-#: ../../Zotlabs/Module/Import.php:553
+#: ../../Zotlabs/Module/Import.php:562
msgid "Your old login password"
msgstr "Ваш старый пароль"
-#: ../../Zotlabs/Module/Import.php:554
+#: ../../Zotlabs/Module/Import.php:563
msgid "Import a few months of posts if possible (limited by available memory"
msgstr "Импортировать несколько месяцев публикаций если возможно (ограничено доступной памятью)"
-#: ../../Zotlabs/Module/Import.php:556
+#: ../../Zotlabs/Module/Import.php:565
msgid ""
"For either option, please choose whether to make this hub your new primary "
"address, or whether your old location should continue this role. You will be "
@@ -10713,25 +10706,25 @@ msgid ""
"location for files, photos, and media."
msgstr "Для любого варианта, пожалуйста, выберите, следует ли сделать этот хаб вашим новым основным адресом, или ваше прежнее местоположение должно продолжить выполнять эту роль. Вы сможете отправлять сообщения из любого местоположения, но только одно может быть помечено как основное место для файлов, фотографий и мультимедиа."
-#: ../../Zotlabs/Module/Import.php:558
+#: ../../Zotlabs/Module/Import.php:567
msgid "Make this hub my primary location"
msgstr "Сделать этот хаб главным"
-#: ../../Zotlabs/Module/Import.php:559
+#: ../../Zotlabs/Module/Import.php:568
msgid "Move this channel (disable all previous locations)"
msgstr "Переместить это канал (отключить все предыдущие месторасположения)"
-#: ../../Zotlabs/Module/Import.php:560
+#: ../../Zotlabs/Module/Import.php:569
msgid "Use this channel nickname instead of the one provided"
msgstr "Использовать псевдоним этого канала вместо предоставленного"
-#: ../../Zotlabs/Module/Import.php:560
+#: ../../Zotlabs/Module/Import.php:569
msgid ""
"Leave blank to keep your existing channel nickname. You will be randomly "
"assigned a similar nickname if either name is already allocated on this site."
msgstr "Оставьте пустым для сохранения существующего псевдонима канала. Вам будет случайным образом назначен похожий псевдоним если такое имя уже выделено на этом сайте."
-#: ../../Zotlabs/Module/Import.php:562
+#: ../../Zotlabs/Module/Import.php:571
msgid ""
"This process may take several minutes to complete. Please submit the form "
"only once and leave this page open until finished."
@@ -10972,9 +10965,8 @@ msgstr "Показывать только новые публикации"
#: ../../Zotlabs/Widget/Notifications.php:46
#: ../../Zotlabs/Widget/Notifications.php:122
#: ../../Zotlabs/Widget/Notifications.php:153
-#: ../../Zotlabs/Widget/Activity_filter.php:165
-msgid "Filter by name"
-msgstr "Отфильтровать по имени"
+msgid "Filter by name or address"
+msgstr "Фильтровать по имени или адресу"
#: ../../Zotlabs/Widget/Notifications.php:35
msgid "New Home Activity"
@@ -11411,6 +11403,10 @@ msgstr "Показывать категории добавленных публ
msgid "Panel search"
msgstr "Панель поиска"
+#: ../../Zotlabs/Widget/Activity_filter.php:165
+msgid "Filter by name"
+msgstr "Отфильтровать по имени"
+
#: ../../Zotlabs/Widget/Activity_filter.php:180
msgid "Remove active filter"
msgstr "Удалить активный фильтр"
@@ -12117,47 +12113,47 @@ msgstr "Добавить на панель навигации"
msgid "Unpin from navbar"
msgstr "Удалить с панели навигации"
-#: ../../Zotlabs/Lib/ThreadItem.php:185
+#: ../../Zotlabs/Lib/ThreadItem.php:188
msgid "I will attend"
msgstr "Я буду присутствовать"
-#: ../../Zotlabs/Lib/ThreadItem.php:185
+#: ../../Zotlabs/Lib/ThreadItem.php:188
msgid "I will not attend"
msgstr "Я не буду присутствовать"
-#: ../../Zotlabs/Lib/ThreadItem.php:185
+#: ../../Zotlabs/Lib/ThreadItem.php:188
msgid "I might attend"
msgstr "Я возможно буду присутствовать"
-#: ../../Zotlabs/Lib/ThreadItem.php:195
+#: ../../Zotlabs/Lib/ThreadItem.php:198
msgid "I agree"
msgstr "Я согласен"
-#: ../../Zotlabs/Lib/ThreadItem.php:195
+#: ../../Zotlabs/Lib/ThreadItem.php:198
msgid "I disagree"
msgstr "Я не согласен"
-#: ../../Zotlabs/Lib/ThreadItem.php:195
+#: ../../Zotlabs/Lib/ThreadItem.php:198
msgid "I abstain"
msgstr "Я воздержался"
-#: ../../Zotlabs/Lib/ThreadItem.php:269
+#: ../../Zotlabs/Lib/ThreadItem.php:272
msgid "Add Tag"
msgstr "Добавить тег"
-#: ../../Zotlabs/Lib/ThreadItem.php:294
+#: ../../Zotlabs/Lib/ThreadItem.php:297
msgid "Share This"
msgstr "Поделиться этим"
-#: ../../Zotlabs/Lib/ThreadItem.php:294
+#: ../../Zotlabs/Lib/ThreadItem.php:297
msgid "share"
msgstr "поделиться"
-#: ../../Zotlabs/Lib/ThreadItem.php:303
+#: ../../Zotlabs/Lib/ThreadItem.php:306
msgid "Delivery Report"
msgstr "Отчёт о доставке"
-#: ../../Zotlabs/Lib/ThreadItem.php:323
+#: ../../Zotlabs/Lib/ThreadItem.php:326
#, php-format
msgid "%d comment"
msgid_plural "%d comments"
@@ -12165,73 +12161,73 @@ msgstr[0] "%d комментарий"
msgstr[1] "%d комментария"
msgstr[2] "%d комментариев"
-#: ../../Zotlabs/Lib/ThreadItem.php:357 ../../Zotlabs/Lib/ThreadItem.php:358
+#: ../../Zotlabs/Lib/ThreadItem.php:360 ../../Zotlabs/Lib/ThreadItem.php:361
#, php-format
msgid "View %s's profile - %s"
msgstr "Просмотр %s профиля - %s"
-#: ../../Zotlabs/Lib/ThreadItem.php:361
+#: ../../Zotlabs/Lib/ThreadItem.php:364
msgid "to"
msgstr "к"
-#: ../../Zotlabs/Lib/ThreadItem.php:362
+#: ../../Zotlabs/Lib/ThreadItem.php:365
msgid "via"
msgstr "через"
-#: ../../Zotlabs/Lib/ThreadItem.php:363
+#: ../../Zotlabs/Lib/ThreadItem.php:366
msgid "Wall-to-Wall"
msgstr "Стена-к-Стене"
-#: ../../Zotlabs/Lib/ThreadItem.php:364
+#: ../../Zotlabs/Lib/ThreadItem.php:367
msgid "via Wall-To-Wall:"
msgstr "через Стена-к-Стене:"
-#: ../../Zotlabs/Lib/ThreadItem.php:390
+#: ../../Zotlabs/Lib/ThreadItem.php:393
msgid "Attend"
msgstr "Посетить"
-#: ../../Zotlabs/Lib/ThreadItem.php:391
+#: ../../Zotlabs/Lib/ThreadItem.php:394
msgid "Attendance Options"
msgstr "Параметры посещаемости"
-#: ../../Zotlabs/Lib/ThreadItem.php:392
+#: ../../Zotlabs/Lib/ThreadItem.php:395
msgid "Vote"
msgstr "Голосовать"
-#: ../../Zotlabs/Lib/ThreadItem.php:393
+#: ../../Zotlabs/Lib/ThreadItem.php:396
msgid "Voting Options"
msgstr "Параметры голосования"
-#: ../../Zotlabs/Lib/ThreadItem.php:414
+#: ../../Zotlabs/Lib/ThreadItem.php:417
#: ../../extend/addon/hzaddons/bookmarker/bookmarker.php:38
msgid "Save Bookmarks"
msgstr "Сохранить закладки"
-#: ../../Zotlabs/Lib/ThreadItem.php:415
+#: ../../Zotlabs/Lib/ThreadItem.php:418
msgid "Add to Calendar"
msgstr "Добавить в календарь"
-#: ../../Zotlabs/Lib/ThreadItem.php:776
+#: ../../Zotlabs/Lib/ThreadItem.php:779
msgid "Image"
msgstr "Изображение"
-#: ../../Zotlabs/Lib/ThreadItem.php:778
+#: ../../Zotlabs/Lib/ThreadItem.php:781
msgid "Insert Link"
msgstr "Вставить ссылку"
-#: ../../Zotlabs/Lib/ThreadItem.php:779
+#: ../../Zotlabs/Lib/ThreadItem.php:782
msgid "Video"
msgstr "Видео"
-#: ../../Zotlabs/Lib/ThreadItem.php:789
+#: ../../Zotlabs/Lib/ThreadItem.php:792
msgid "Your full name (required)"
msgstr "Ваше полное имя (требуется)"
-#: ../../Zotlabs/Lib/ThreadItem.php:790
+#: ../../Zotlabs/Lib/ThreadItem.php:793
msgid "Your email address (required)"
msgstr "Ваш адрес электронной почты (требуется)"
-#: ../../Zotlabs/Lib/ThreadItem.php:791
+#: ../../Zotlabs/Lib/ThreadItem.php:794
msgid "Your website URL (optional)"
msgstr "URL вашего вебсайта (необязательно)"
@@ -12532,42 +12528,42 @@ msgstr "Галерея"
msgid "Photo Gallery"
msgstr "Фотогалерея"
-#: ../../extend/addon/hzaddons/rtof/rtof.php:45
-msgid "Post to Friendica"
-msgstr "Опубликовать в Friendica"
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:24
+msgid "Friendica Crosspost Connector Settings saved."
+msgstr "Настройки пересылки публикаций Friendica сохранены."
-#: ../../extend/addon/hzaddons/rtof/rtof.php:62
-msgid "rtof Settings saved."
-msgstr "Настройки rtof сохранены."
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:37
+msgid "Relay public postings to a connected Friendica account"
+msgstr "Ретранслировать общедоступные публикации на подключённую учётную запись Friendica"
-#: ../../extend/addon/hzaddons/rtof/rtof.php:81
-msgid "Allow posting to Friendica"
-msgstr "Разрешить публиковать в Friendica"
-
-#: ../../extend/addon/hzaddons/rtof/rtof.php:85
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:49
msgid "Send public postings to Friendica by default"
msgstr "Отправлять общедоступные публикации во Friendica по умолчанию"
-#: ../../extend/addon/hzaddons/rtof/rtof.php:89
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:53
msgid "Friendica API Path"
msgstr "Путь к Friendica API"
-#: ../../extend/addon/hzaddons/rtof/rtof.php:89
-#: ../../extend/addon/hzaddons/redred/redred.php:103
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:53
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:67
msgid "https://{sitename}/api"
msgstr ""
-#: ../../extend/addon/hzaddons/rtof/rtof.php:93
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:57
msgid "Friendica login name"
msgstr "Имя входа Friendica"
-#: ../../extend/addon/hzaddons/rtof/rtof.php:97
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:61
msgid "Friendica password"
msgstr "Пароль Friendica"
-#: ../../extend/addon/hzaddons/rtof/rtof.php:101
-msgid "Hubzilla to Friendica Post Settings"
-msgstr "Настройки публикаций Hubzilla для Friendica"
+#: ../../extend/addon/hzaddons/rtof/Mod_Rtof.php:69
+msgid "Friendica Crosspost Connector"
+msgstr "Пересылка публикаций Friendica"
+
+#: ../../extend/addon/hzaddons/rtof/rtof.php:51
+msgid "Post to Friendica"
+msgstr "Опубликовать в Friendica"
#: ../../extend/addon/hzaddons/ldapauth/ldapauth.php:70
msgid "An account has been created for you."
@@ -12577,33 +12573,33 @@ msgstr "Учётная запись, которая была для вас со
msgid "Authentication successful but rejected: account creation is disabled."
msgstr "Аутентификация выполнена успешно, но отклонена: создание учетной записи отключено."
-#: ../../extend/addon/hzaddons/ijpost/ijpost.php:42
-msgid "Post to Insanejournal"
-msgstr "Опубликовать в InsaneJournal"
+#: ../../extend/addon/hzaddons/ijpost/ijpost.php:45
+msgid "Post to Insane Journal"
+msgstr "Опубликовать в Insane Journal"
-#: ../../extend/addon/hzaddons/ijpost/ijpost.php:73
-msgid "Enable InsaneJournal Post Plugin"
-msgstr "Включить плагин публикаций InsaneJournal"
+#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:24
+msgid "Insane Journal Crosspost Connector Settings saved."
+msgstr "Настройки пересылки публикаций Insane Journal сохранены."
-#: ../../extend/addon/hzaddons/ijpost/ijpost.php:77
+#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:37
+msgid "Relay public postings to Insane Journal"
+msgstr "Ретранслировать общедоступные публикации в Insane Journal"
+
+#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:54
msgid "InsaneJournal username"
-msgstr "Имя пользователя InsaneJournal"
+msgstr "Имя пользователя Insane Journal"
-#: ../../extend/addon/hzaddons/ijpost/ijpost.php:81
+#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:58
msgid "InsaneJournal password"
-msgstr "Пароль InsaneJournal"
+msgstr "Пароль Insane Journal"
-#: ../../extend/addon/hzaddons/ijpost/ijpost.php:85
+#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:62
msgid "Post to InsaneJournal by default"
-msgstr "Публиковать в InsaneJournal по умолчанию"
-
-#: ../../extend/addon/hzaddons/ijpost/ijpost.php:89
-msgid "InsaneJournal Post Settings"
-msgstr "Настройки публикаций в InsaneJournal"
+msgstr "Публиковать в Insane Journal по умолчанию"
-#: ../../extend/addon/hzaddons/ijpost/ijpost.php:104
-msgid "Insane Journal Settings saved."
-msgstr "Настройки InsaneJournal сохранены."
+#: ../../extend/addon/hzaddons/ijpost/Mod_Ijpost.php:70
+msgid "Insane Journal Crosspost Connector"
+msgstr "Пересылка публикаций Insane Journal"
#: ../../extend/addon/hzaddons/testdrive/testdrive.php:104
#, php-format
@@ -12658,7 +12654,7 @@ msgid "Copy the PIN from Twitter here"
msgstr "Скопируйте PIN-код из Twitter здесь"
#: ../../extend/addon/hzaddons/twitter/twitter.php:236
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:401
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:272
msgid "Currently connected to: "
msgstr "В настоящее время подключён к:"
@@ -12699,7 +12695,7 @@ msgid ""
msgstr "Если включено, ваши общедоступные публикации будут опубликованы в связанной учётной записи Twitter по умолчанию"
#: ../../extend/addon/hzaddons/twitter/twitter.php:264
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:424
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:291
msgid "Clear OAuth configuration"
msgstr "Очистить конфигурацию OAuth"
@@ -13094,43 +13090,67 @@ msgstr "Введите любой текст"
msgid "View Larger"
msgstr "Увеличить"
-#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:169
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:170
msgid "Tile Server URL"
msgstr "URL сервера Tile"
-#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:169
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:170
msgid ""
"A list of <a href=\"http://wiki.openstreetmap.org/wiki/TMS\" target=\"_blank"
"\">public tile servers</a>"
msgstr "Список <a href=\"http://wiki.openstreetmap.org/wiki/TMS\" target=\"_blank\">общедоступных серверов</a>"
-#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:170
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:171
msgid "Nominatim (reverse geocoding) Server URL"
msgstr "URL сервера Nominatim (обратное геокодирование)"
-#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:170
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:171
msgid ""
"A list of <a href=\"http://wiki.openstreetmap.org/wiki/Nominatim\" target="
"\"_blank\">Nominatim servers</a>"
msgstr "Список <a href=\"http://wiki.openstreetmap.org/wiki/Nominatim\" target=\"_blank\">серверов Nominatim</a>"
-#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:171
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:172
msgid "Default zoom"
msgstr "Масштаб по умолчанию"
-#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:171
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:172
msgid ""
"The default zoom level. (1:world, 18:highest, also depends on tile server)"
msgstr "Уровень размера по умолчанию (1 - весь мир, 18 - максимальный; зависит от сервера)."
-#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:172
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:173
msgid "Include marker on map"
msgstr "Включите маркер на карте"
-#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:172
+#: ../../extend/addon/hzaddons/openstreetmap/openstreetmap.php:173
msgid "Include a marker on the map."
msgstr "Включить маркер на карте"
+#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:27
+msgid "Photo Cache settings saved."
+msgstr "Настройки Photo Cache сохранены."
+
+#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:36
+msgid ""
+"Photo Cache addon saves a copy of images from external sites locally to "
+"increase your anonymity in the web."
+msgstr "Приложение Photo Cache сохраняет копию изображений с внешних сайтов локально для повышения вашей анонимности в Интернет."
+
+#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:53
+msgid "Minimal photo size for caching"
+msgstr "Минимальный размер фотографии для кэширования"
+
+#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:55
+msgid ""
+"In pixels. 0 will be replaced with system default, from 1 up to 1024 (large "
+"images will be scaled to this value)."
+msgstr "В пискелях. 0 будет заменён значением по умолчанию, от 1 до 1024 (большие изображения будут масштабированы до этого значения)."
+
+#: ../../extend/addon/hzaddons/photocache/Mod_Photocache.php:64
+msgid "Photo Cache"
+msgstr ""
+
#: ../../extend/addon/hzaddons/jappixmini/jappixmini.php:309
msgid "Activate addon"
msgstr "Активировать расширение"
@@ -13160,7 +13180,7 @@ msgid "Encrypt Jabber password with Hubzilla password"
msgstr "Зашифровать пароль Jabber с помощью пароля Hubzilla"
#: ../../extend/addon/hzaddons/jappixmini/jappixmini.php:347
-#: ../../extend/addon/hzaddons/redred/redred.php:115
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:79
msgid "Hubzilla password"
msgstr "Пароль Hubzilla"
@@ -13611,40 +13631,41 @@ msgstr "Публиковать в Livejournal по умолчанию"
msgid "Livejournal Post Settings"
msgstr "Настройки публикации в Livejournal"
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:143
-msgid "Post to GNU social"
-msgstr "Опубликовать в GNU Social"
-
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:195
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:61
msgid ""
"Please contact your site administrator.<br />The provided API URL is not "
"valid."
msgstr "Пожалуйста свяжитесь с администратором сайта. <br />Предоставленный URL API недействителен."
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:232
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:98
msgid "We could not contact the GNU social API with the Path you entered."
msgstr "Нам не удалось установить контакт с GNU Social API по введённому вами пути"
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:266
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:130
msgid "GNU social settings updated."
msgstr "Настройки GNU Social обновлены."
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:310
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:147
+msgid ""
+"Relay public postings to a connected GNU social account (formerly StatusNet)"
+msgstr "Ретранслировать общедоступные публикации на подключённую учётную запись GNU social (бывшая StatusNet)"
+
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:181
msgid "Globally Available GNU social OAuthKeys"
msgstr "Глобально доступные ключи OAuthKeys GNU Social"
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:312
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:183
msgid ""
"There are preconfigured OAuth key pairs for some GNU social servers "
"available. If you are using one of them, please use these credentials.<br /"
">If not feel free to connect to any other GNU social instance (see below)."
msgstr "Существуют предварительно настроенные пары ключей OAuth для некоторых доступных серверов GNU social. Если вы используете один из них, используйте эти учетные данные. <br />Если вы не хотите подключаться к какому-либо другому серверу GNU social (см. ниже)."
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:327
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:198
msgid "Provide your own OAuth Credentials"
msgstr "Предоставьте ваши собственные регистрационные данные OAuth"
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:329
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:200
msgid ""
"No consumer key pair for GNU social found. Register your Hubzilla Account as "
"an desktop client on your GNU social account, copy the consumer key pair "
@@ -13653,27 +13674,27 @@ msgid ""
"Hubzilla installation at your favourite GNU social installation."
msgstr "Не найдена пользовательская пара ключей для GNU social. Зарегистрируйте свою учетную запись Hubzilla в качестве настольного клиента в своей учетной записи GNU social, скопируйте cюда пару ключей пользователя и введите корневой каталог базы API. <br />Прежде чем регистрировать свою собственную пару ключей OAuth, спросите администратора, если ли уже пара ключей для этой установки Hubzilla в вашем GNU social."
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:333
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:204
msgid "OAuth Consumer Key"
msgstr "Ключ клиента OAuth"
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:337
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:208
msgid "OAuth Consumer Secret"
msgstr "Пароль клиента OAuth"
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:341
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:212
msgid "Base API Path"
msgstr "Основной путь к API"
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:341
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:212
msgid "Remember the trailing /"
msgstr "Запомнить закрывающий /"
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:345
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:216
msgid "GNU social application name"
msgstr "Имя приложения GNU social"
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:368
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:239
msgid ""
"To connect to your GNU social account click the button below to get a "
"security code from GNU social which you have to copy into the input box "
@@ -13681,27 +13702,27 @@ msgid ""
"posted to GNU social."
msgstr "Чтобы подключиться к вашей учетной записи GNU social нажмите кнопку ниже для получения кода безопасности из GNU social, который вы должны скопировать в поле ввода ниже и отправить форму. Только ваши общедоступные сообщения будут опубликованы в GNU social."
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:370
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:241
msgid "Log in with GNU social"
msgstr "Войти с GNU social"
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:373
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:244
msgid "Copy the security code from GNU social here"
msgstr "Скопируйте код безопасности GNU social здесь"
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:383
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:254
msgid "Cancel Connection Process"
msgstr "Отменить процесс подключения"
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:385
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:256
msgid "Current GNU social API is"
msgstr "Текущий GNU social API"
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:389
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:260
msgid "Cancel GNU social Connection"
msgstr "Отменить подключение с GNU social"
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:406
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:277
msgid ""
"<strong>Note</strong>: Due your privacy settings (<em>Hide your profile "
"details from unknown viewers?</em>) the link potentially included in public "
@@ -13709,35 +13730,29 @@ msgid ""
"informing the visitor that the access to your profile has been restricted."
msgstr "<strong>Замечание</strong>: Из-за настроек конфиденциальности (<em>скрыть данные своего профиля от неизвестных зрителей?</em>) cсылка, потенциально включенная в общедоступные публикации, переданные в GNU social, приведет посетителя к пустой странице, информирующей его о том, что доступ к вашему профилю был ограничен."
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:411
-msgid "Allow posting to GNU social"
-msgstr "Разрешить публиковать в GNU social"
-
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:411
-msgid ""
-"If enabled your public postings can be posted to the associated GNU-social "
-"account"
-msgstr "Если включено, ваши общедоступные публикации будут опубликованы в связанной учётной записи GNU social"
-
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:415
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:282
msgid "Post to GNU social by default"
msgstr "Публиковать в GNU social по умолчанию"
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:415
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:282
msgid ""
"If enabled your public postings will be posted to the associated GNU-social "
"account by default"
msgstr "Если включено, ваши общедоступные публикации будут опубликованы в связанной учётной записи GNU social по умолчанию"
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:432
-msgid "GNU social Post Settings"
-msgstr "Настройки публикаций GNU social"
+#: ../../extend/addon/hzaddons/statusnet/Mod_Statusnet.php:303
+msgid "GNU-Social Crosspost Connector"
+msgstr ""
+
+#: ../../extend/addon/hzaddons/statusnet/statusnet.php:145
+msgid "Post to GNU social"
+msgstr "Опубликовать в GNU Social"
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:892
+#: ../../extend/addon/hzaddons/statusnet/statusnet.php:594
msgid "API URL"
msgstr ""
-#: ../../extend/addon/hzaddons/statusnet/statusnet.php:895
+#: ../../extend/addon/hzaddons/statusnet/statusnet.php:597
msgid "Application name"
msgstr "Название приложения"
@@ -13834,7 +13849,7 @@ msgid "Last Name"
msgstr "Фамилия"
#: ../../extend/addon/hzaddons/openid/MysqlProvider.php:54
-#: ../../extend/addon/hzaddons/redred/redred.php:111
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:75
msgid "Nickname"
msgstr "Псевдоним"
@@ -14897,41 +14912,41 @@ msgstr "Настройки публикаций в Libertree"
msgid "Libertree Settings saved."
msgstr "Настройки Libertree сохранены."
-#: ../../extend/addon/hzaddons/redred/redred.php:45
-msgid "Post to Red"
-msgstr "Опубликовать в Red"
-
-#: ../../extend/addon/hzaddons/redred/redred.php:60
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:24
msgid "Channel is required."
msgstr "Необходим канал."
-#: ../../extend/addon/hzaddons/redred/redred.php:76
-msgid "redred Settings saved."
-msgstr "Настройки RedRed сохранены."
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:38
+msgid "Hubzilla Crosspost Connector Settings saved."
+msgstr ""
-#: ../../extend/addon/hzaddons/redred/redred.php:95
-msgid "Allow posting to another Hubzilla Channel"
-msgstr "Разрешить публиковать в другой канал Hubzilla"
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:51
+msgid "Relay public postings to another Hubzilla channel"
+msgstr "Ретранслировать общедоступные публикации в другой канал Hubzilla"
-#: ../../extend/addon/hzaddons/redred/redred.php:99
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:63
msgid "Send public postings to Hubzilla channel by default"
msgstr "Отправлять общедоступные публикации в канал Hubzilla по умолчанию"
-#: ../../extend/addon/hzaddons/redred/redred.php:103
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:67
msgid "Hubzilla API Path"
msgstr "Путь к Hubzilla API"
-#: ../../extend/addon/hzaddons/redred/redred.php:107
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:71
msgid "Hubzilla login name"
msgstr "Имя входа Hubzilla"
-#: ../../extend/addon/hzaddons/redred/redred.php:111
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:75
msgid "Hubzilla channel name"
msgstr "Название канала Hubzilla"
-#: ../../extend/addon/hzaddons/redred/redred.php:119
-msgid "Hubzilla Crosspost Settings"
-msgstr "Настройки перекрёстных публикаций Hubzilla"
+#: ../../extend/addon/hzaddons/redred/Mod_Redred.php:87
+msgid "Hubzilla Crosspost Connector"
+msgstr ""
+
+#: ../../extend/addon/hzaddons/redred/redred.php:50
+msgid "Post to Hubzilla"
+msgstr ""
#: ../../extend/addon/hzaddons/pubcrawl/Mod_Pubcrawl.php:25
msgid "ActivityPub Protocol Settings updated."
@@ -15114,3 +15129,7 @@ msgstr ""
#: ../../extend/addon/hzaddons/opensearch/opensearch.php:43
msgid "Search $Projectname"
msgstr "Поиск $Projectname"
+
+#: ../../store/[data]/smarty3/compiled/3fbe720b52221cc66640ba6ea030406a047aa52a_0.file.cover_photo.tpl.php:127
+msgid "Cover Photo"
+msgstr ""
diff --git a/view/ru/hstrings.php b/view/ru/hstrings.php
index 02c88dde3..30dd01269 100644
--- a/view/ru/hstrings.php
+++ b/view/ru/hstrings.php
@@ -2489,7 +2489,7 @@ App::$strings["New Network Activity Notifications"] = "Новые уведомл
App::$strings["View your network activity"] = "Просмотреть вашу сетевую активность";
App::$strings["Mark all notifications read"] = "Пометить уведомления как прочитанные";
App::$strings["Show new posts only"] = "Показывать только новые публикации";
-App::$strings["Filter by name"] = "Отфильтровать по имени";
+App::$strings["Filter by name or address"] = "Фильтровать по имени или адресу";
App::$strings["New Home Activity"] = "Новая локальная активность";
App::$strings["New Home Activity Notifications"] = "Новые уведомления локальной активности";
App::$strings["View your home activity"] = "Просмотреть локальную активность";
@@ -2597,6 +2597,7 @@ App::$strings["Show posts that mention or involve me"] = "Показывать
App::$strings["Show posts that I have filed to %s"] = "Показывать публикации которые я добавил в %s";
App::$strings["Show filed post categories"] = "Показывать категории добавленных публикаций";
App::$strings["Panel search"] = "Панель поиска";
+App::$strings["Filter by name"] = "Отфильтровать по имени";
App::$strings["Remove active filter"] = "Удалить активный фильтр";
App::$strings["Stream Filters"] = "Фильтры потока";
App::$strings["Chat Members"] = "Участники чата";
@@ -2855,24 +2856,24 @@ App::$strings["0 or blank to import all available"] = "0 или пусто дл
App::$strings["A simple gallery for your photo albums"] = "Простая галлерея для ваших фотоальбомов";
App::$strings["Gallery"] = "Галерея";
App::$strings["Photo Gallery"] = "Фотогалерея";
-App::$strings["Post to Friendica"] = "Опубликовать в Friendica";
-App::$strings["rtof Settings saved."] = "Настройки rtof сохранены.";
-App::$strings["Allow posting to Friendica"] = "Разрешить публиковать в Friendica";
+App::$strings["Friendica Crosspost Connector Settings saved."] = "Настройки пересылки публикаций Friendica сохранены.";
+App::$strings["Relay public postings to a connected Friendica account"] = "Ретранслировать общедоступные публикации на подключённую учётную запись Friendica";
App::$strings["Send public postings to Friendica by default"] = "Отправлять общедоступные публикации во Friendica по умолчанию";
App::$strings["Friendica API Path"] = "Путь к Friendica API";
App::$strings["https://{sitename}/api"] = "";
App::$strings["Friendica login name"] = "Имя входа Friendica";
App::$strings["Friendica password"] = "Пароль Friendica";
-App::$strings["Hubzilla to Friendica Post Settings"] = "Настройки публикаций Hubzilla для Friendica";
+App::$strings["Friendica Crosspost Connector"] = "Пересылка публикаций Friendica";
+App::$strings["Post to Friendica"] = "Опубликовать в Friendica";
App::$strings["An account has been created for you."] = "Учётная запись, которая была для вас создана.";
App::$strings["Authentication successful but rejected: account creation is disabled."] = "Аутентификация выполнена успешно, но отклонена: создание учетной записи отключено.";
-App::$strings["Post to Insanejournal"] = "Опубликовать в InsaneJournal";
-App::$strings["Enable InsaneJournal Post Plugin"] = "Включить плагин публикаций InsaneJournal";
-App::$strings["InsaneJournal username"] = "Имя пользователя InsaneJournal";
-App::$strings["InsaneJournal password"] = "Пароль InsaneJournal";
-App::$strings["Post to InsaneJournal by default"] = "Публиковать в InsaneJournal по умолчанию";
-App::$strings["InsaneJournal Post Settings"] = "Настройки публикаций в InsaneJournal";
-App::$strings["Insane Journal Settings saved."] = "Настройки InsaneJournal сохранены.";
+App::$strings["Post to Insane Journal"] = "Опубликовать в Insane Journal";
+App::$strings["Insane Journal Crosspost Connector Settings saved."] = "Настройки пересылки публикаций Insane Journal сохранены.";
+App::$strings["Relay public postings to Insane Journal"] = "Ретранслировать общедоступные публикации в Insane Journal";
+App::$strings["InsaneJournal username"] = "Имя пользователя Insane Journal";
+App::$strings["InsaneJournal password"] = "Пароль Insane Journal";
+App::$strings["Post to InsaneJournal by default"] = "Публиковать в Insane Journal по умолчанию";
+App::$strings["Insane Journal Crosspost Connector"] = "Пересылка публикаций Insane Journal";
App::$strings["Your account on %s will expire in a few days."] = "Ваш аккаунт на %s перестанет работать через несколько дней.";
App::$strings["Your $Productname test account is about to expire."] = "Ваш тестовый аккаунт в $Productname близок к окончанию срока действия.";
App::$strings["Redmatrix File Storage Import"] = "Импорт файлового хранилища Redmatrix";
@@ -2994,6 +2995,11 @@ App::$strings["Default zoom"] = "Масштаб по умолчанию";
App::$strings["The default zoom level. (1:world, 18:highest, also depends on tile server)"] = "Уровень размера по умолчанию (1 - весь мир, 18 - максимальный; зависит от сервера).";
App::$strings["Include marker on map"] = "Включите маркер на карте";
App::$strings["Include a marker on the map."] = "Включить маркер на карте";
+App::$strings["Photo Cache settings saved."] = "Настройки Photo Cache сохранены.";
+App::$strings["Photo Cache addon saves a copy of images from external sites locally to increase your anonymity in the web."] = "Приложение Photo Cache сохраняет копию изображений с внешних сайтов локально для повышения вашей анонимности в Интернет.";
+App::$strings["Minimal photo size for caching"] = "Минимальный размер фотографии для кэширования";
+App::$strings["In pixels. 0 will be replaced with system default, from 1 up to 1024 (large images will be scaled to this value)."] = "В пискелях. 0 будет заменён значением по умолчанию, от 1 до 1024 (большие изображения будут масштабированы до этого значения).";
+App::$strings["Photo Cache"] = "";
App::$strings["Activate addon"] = "Активировать расширение";
App::$strings["Hide Jappixmini Chat-Widget from the webinterface"] = "Скрыть виджет чата Jappixmini из веб-интерфейса";
App::$strings["Jabber username"] = "Имя пользователя Jabber";
@@ -3105,10 +3111,10 @@ App::$strings["Livejournal username"] = "Имя пользователя Livejou
App::$strings["Livejournal password"] = "Пароль Livejournal";
App::$strings["Post to Livejournal by default"] = "Публиковать в Livejournal по умолчанию";
App::$strings["Livejournal Post Settings"] = "Настройки публикации в Livejournal";
-App::$strings["Post to GNU social"] = "Опубликовать в GNU Social";
App::$strings["Please contact your site administrator.<br />The provided API URL is not valid."] = "Пожалуйста свяжитесь с администратором сайта. <br />Предоставленный URL API недействителен.";
App::$strings["We could not contact the GNU social API with the Path you entered."] = "Нам не удалось установить контакт с GNU Social API по введённому вами пути";
App::$strings["GNU social settings updated."] = "Настройки GNU Social обновлены.";
+App::$strings["Relay public postings to a connected GNU social account (formerly StatusNet)"] = "Ретранслировать общедоступные публикации на подключённую учётную запись GNU social (бывшая StatusNet)";
App::$strings["Globally Available GNU social OAuthKeys"] = "Глобально доступные ключи OAuthKeys GNU Social";
App::$strings["There are preconfigured OAuth key pairs for some GNU social servers available. If you are using one of them, please use these credentials.<br />If not feel free to connect to any other GNU social instance (see below)."] = "Существуют предварительно настроенные пары ключей OAuth для некоторых доступных серверов GNU social. Если вы используете один из них, используйте эти учетные данные. <br />Если вы не хотите подключаться к какому-либо другому серверу GNU social (см. ниже).";
App::$strings["Provide your own OAuth Credentials"] = "Предоставьте ваши собственные регистрационные данные OAuth";
@@ -3125,11 +3131,10 @@ App::$strings["Cancel Connection Process"] = "Отменить процесс п
App::$strings["Current GNU social API is"] = "Текущий GNU social API";
App::$strings["Cancel GNU social Connection"] = "Отменить подключение с GNU social";
App::$strings["<strong>Note</strong>: Due your privacy settings (<em>Hide your profile details from unknown viewers?</em>) the link potentially included in public postings relayed to GNU social will lead the visitor to a blank page informing the visitor that the access to your profile has been restricted."] = "<strong>Замечание</strong>: Из-за настроек конфиденциальности (<em>скрыть данные своего профиля от неизвестных зрителей?</em>) cсылка, потенциально включенная в общедоступные публикации, переданные в GNU social, приведет посетителя к пустой странице, информирующей его о том, что доступ к вашему профилю был ограничен.";
-App::$strings["Allow posting to GNU social"] = "Разрешить публиковать в GNU social";
-App::$strings["If enabled your public postings can be posted to the associated GNU-social account"] = "Если включено, ваши общедоступные публикации будут опубликованы в связанной учётной записи GNU social";
App::$strings["Post to GNU social by default"] = "Публиковать в GNU social по умолчанию";
App::$strings["If enabled your public postings will be posted to the associated GNU-social account by default"] = "Если включено, ваши общедоступные публикации будут опубликованы в связанной учётной записи GNU social по умолчанию";
-App::$strings["GNU social Post Settings"] = "Настройки публикаций GNU social";
+App::$strings["GNU-Social Crosspost Connector"] = "";
+App::$strings["Post to GNU social"] = "Опубликовать в GNU Social";
App::$strings["API URL"] = "";
App::$strings["Application name"] = "Название приложения";
App::$strings["Access Denied"] = "Доступ запрещён";
@@ -3400,15 +3405,15 @@ App::$strings["Libertree site URL"] = "URL сайта Libertree";
App::$strings["Post to Libertree by default"] = "Публиковать в Libertree по умолчанию";
App::$strings["Libertree Post Settings"] = "Настройки публикаций в Libertree";
App::$strings["Libertree Settings saved."] = "Настройки Libertree сохранены.";
-App::$strings["Post to Red"] = "Опубликовать в Red";
App::$strings["Channel is required."] = "Необходим канал.";
-App::$strings["redred Settings saved."] = "Настройки RedRed сохранены.";
-App::$strings["Allow posting to another Hubzilla Channel"] = "Разрешить публиковать в другой канал Hubzilla";
+App::$strings["Hubzilla Crosspost Connector Settings saved."] = "";
+App::$strings["Relay public postings to another Hubzilla channel"] = "Ретранслировать общедоступные публикации в другой канал Hubzilla";
App::$strings["Send public postings to Hubzilla channel by default"] = "Отправлять общедоступные публикации в канал Hubzilla по умолчанию";
App::$strings["Hubzilla API Path"] = "Путь к Hubzilla API";
App::$strings["Hubzilla login name"] = "Имя входа Hubzilla";
App::$strings["Hubzilla channel name"] = "Название канала Hubzilla";
-App::$strings["Hubzilla Crosspost Settings"] = "Настройки перекрёстных публикаций Hubzilla";
+App::$strings["Hubzilla Crosspost Connector"] = "";
+App::$strings["Post to Hubzilla"] = "";
App::$strings["ActivityPub Protocol Settings updated."] = "Настройки протокола ActivityPub обновлены.";
App::$strings["The activitypub protocol does not support location independence. Connections you make within that network may be unreachable from alternate channel locations."] = "Протокол ActivityPub не поддерживает независимость от расположения. Ваши контакты установленные в этой сети могут быть недоступны из альтернативных мест размещения канала.";
App::$strings["Deliver to ActivityPub recipients in privacy groups"] = "Доставить получателям ActivityPub в группах безопасности";
@@ -3450,3 +3455,4 @@ App::$strings["Skeleton Settings"] = "Настройки скелета";
App::$strings["__ctx:opensearch__ Search %1\$s (%2\$s)"] = "Искать %1\$s (%2\$s)";
App::$strings["__ctx:opensearch__ \$Projectname"] = "";
App::$strings["Search \$Projectname"] = "Поиск \$Projectname";
+App::$strings["Cover Photo"] = "";
diff --git a/view/theme/redbasic/js/redbasic.js b/view/theme/redbasic/js/redbasic.js
index 688e92148..8d3b795cc 100644
--- a/view/theme/redbasic/js/redbasic.js
+++ b/view/theme/redbasic/js/redbasic.js
@@ -121,9 +121,9 @@ function toggleAside() {
$('main').addClass('region_1-on')
$('<div id="overlay"></div>').appendTo('section');
$('#left_aside_wrapper').stick_in_parent({
- offset_top: $('nav').outerHeight(true) + 10,
- parent: '#region_1',
- spacer: '#left_aside_spacer'
+ offset_top: parseInt($('aside').css('padding-top')),
+ parent: 'main',
+ spacer: '.aside_spacer'
});
}
}
diff --git a/view/tpl/notifications_widget.tpl b/view/tpl/notifications_widget.tpl
index f43d82301..98047f1d9 100644
--- a/view/tpl/notifications_widget.tpl
+++ b/view/tpl/notifications_widget.tpl
@@ -105,8 +105,9 @@
$("#nav-{{$notification.type}}-menu .notification").each(function(i, el){
var cn = $(el).data('contact_name').toString().toLowerCase();
+ var ca = $(el).data('contact_addr').toString().toLowerCase();
- if(cn.indexOf(val) === -1)
+ if(cn.indexOf(val) === -1 && ca.indexOf(val) === -1)
$(this).addClass('d-none');
else
$(this).removeClass('d-none');
@@ -134,18 +135,18 @@
{{$no_notifications}}<span class="jumping-dots"><span class="dot-1">.</span><span class="dot-2">.</span><span class="dot-3">.</span></span>
</div>
<div id="nav-notifications-template" rel="template">
- <a class="list-group-item clearfix notification {5}" href="{0}" title="{2}" data-b64mid="{6}" data-notify_id="{7}" data-thread_top="{8}" data-contact_name="{2}">
+ <a class="list-group-item clearfix notification {6}" href="{0}" title="{3}" data-b64mid="{7}" data-notify_id="{8}" data-thread_top="{9}" data-contact_name="{2}" data-contact_addr="{3}">
<img class="menu-img-3" data-src="{1}">
<span class="contactname">{2}</span>
- <span class="dropdown-sub-text">{3}<br>{4}</span>
+ <span class="dropdown-sub-text">{4}<br>{5}</span>
</a>
</div>
<div id="nav-notifications-forums-template" rel="template">
- <a class="list-group-item clearfix notification notification-forum" href="{0}" title="{3}" data-b64mid="{6}" data-notify_id="{7}" data-thread_top="{8}" data-contact_name="{2}">
- <span class="float-right badge badge-{{$notification.severity}}">{9}</span>
+ <a class="list-group-item clearfix notification notification-forum" href="{0}" title="{4} - {3}" data-b64mid="{7}" data-notify_id="{8}" data-thread_top="{9}" data-contact_name="{2}" data-contact_addr="{3}">
+ <span class="float-right badge badge-{{$notification.severity}}">{10}</span>
<img class="menu-img-1" data-src="{1}">
<span class="">{2}</span>
- <i class="fa fa-{10} text-muted"></i>
+ <i class="fa fa-{11} text-muted"></i>
</a>
</div>
<div id="notifications" class="navbar-nav">