diff --git a/CHANGELOG b/CHANGELOG index 9821eda26..272f839fb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,25 @@ +Hubzilla 3.8.2 (2018-10-29) + - Merge unmerged changes from dev into master + - Fix issues with forum handling in mod network and ping + - Fix delivery chain linkage messed up if original post was edited + - Fix issues with the experimental queue worker + - Fix call to image source {1} from html template + - Group stream filters by threaded and unthreaded default view + - Show only unseen forum messages when clicking on forum notification + - Improve editor contact autocomplete performance + - Convert non UTF-8 content on link embeding + - Make textcomplete return up to 100 items + - Look for for matches in the entire string when suggesting emojis + - Add [summary] bbcode to autocomplete list + - Update blueimp_upload to version 9.23 + - Update spanish strings + + Addons + - Cart: don't allow items to be added unless user is logged into the Grid. + - Pubcrawl: simplify asencode_activity() addressing to reflect upcoming changes in mastodon 2.6 + - Rendezvous: Update rendezvous_group.tpl to fix broken Bootstrap library reference + + Hubzilla 3.8.1 (2018-10-21) - Fix issue with too long navbar banners - Fix menu item edit link diff --git a/Zotlabs/Access/PermissionLimits.php b/Zotlabs/Access/PermissionLimits.php index b8ca3034c..c11dc95e6 100644 --- a/Zotlabs/Access/PermissionLimits.php +++ b/Zotlabs/Access/PermissionLimits.php @@ -88,4 +88,4 @@ class PermissionLimits { return false; } -} +} \ No newline at end of file diff --git a/Zotlabs/Daemon/Master.php b/Zotlabs/Daemon/Master.php index 3a71ee578..0656ca05b 100644 --- a/Zotlabs/Daemon/Master.php +++ b/Zotlabs/Daemon/Master.php @@ -60,7 +60,8 @@ class Master { $k = explode('_',$worker['k']); q("delete from config where cat='queueworkers' and k='%s'", 'workerstarted_'.$k[1]); - q("update config set k='workitem' where cat='queuework' and k='%s'", + q("update config set k='%s' where cat='queuework' and k='%s'", + dbesc(uniqid('workitem:',true)), 'workitem_'.$k[1]); unset($workers[$idx]); } @@ -69,7 +70,7 @@ class Master { return false; } } - return uniqid(); + return uniqid('',true); } diff --git a/Zotlabs/Module/Acl.php b/Zotlabs/Module/Acl.php index ea131e08c..738e8fbe2 100644 --- a/Zotlabs/Module/Acl.php +++ b/Zotlabs/Module/Acl.php @@ -83,7 +83,8 @@ class Acl extends \Zotlabs\Web\Controller { if($search) { $sql_extra = " AND pgrp.gname LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " "; $sql_extra2 = "AND ( xchan_name LIKE " . protect_sprintf( "'%" . dbesc($search) . "%'" ) . " OR xchan_addr LIKE " . protect_sprintf( "'%" . dbesc(punify($search)) . ((strpos($search,'@') === false) ? "%@%'" : "%'")) . ") "; - + $sql_extra2_xchan = "AND ( xchan_name LIKE " . protect_sprintf( "'" . dbesc($search) . "%'" ) . " OR xchan_addr LIKE " . protect_sprintf( "'" . dbesc(punify($search)) . ((strpos($search,'@') === false) ? "%@%'" : "%'")) . ") "; + // This horrible mess is needed because position also returns 0 if nothing is found. // Would be MUCH easier if it instead returned a very large value // Otherwise we could just @@ -226,7 +227,7 @@ class Acl extends \Zotlabs\Web\Controller { else { // Visitors $r = q("SELECT xchan_hash as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self FROM xchan left join xlink on xlink_link = xchan_hash - WHERE xlink_xchan = '%s' AND xchan_deleted = 0 $sql_extra2 order by $order_extra2 xchan_name asc" , + WHERE xlink_xchan = '%s' AND xchan_deleted = 0 $sql_extra2_xchan order by $order_extra2 xchan_name asc" , dbesc(get_observer_hash()) ); @@ -270,7 +271,7 @@ class Acl extends \Zotlabs\Web\Controller { if((count($r) < 100) && $type == 'c') { $r2 = q("SELECT substr(xchan_hash,1,18) as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self FROM xchan - WHERE xchan_deleted = 0 and not xchan_network in ('rss','anon','unknown') $sql_extra2 order by $order_extra2 xchan_name asc" + WHERE xchan_deleted = 0 and not xchan_network in ('rss','anon','unknown') $sql_extra2_xchan order by $order_extra2 xchan_name asc" ); if($r2) { $r = array_merge($r,$r2); diff --git a/Zotlabs/Module/Linkinfo.php b/Zotlabs/Module/Linkinfo.php index f0d62b5e0..a0ad17e68 100644 --- a/Zotlabs/Module/Linkinfo.php +++ b/Zotlabs/Module/Linkinfo.php @@ -228,8 +228,8 @@ class Linkinfo extends \Zotlabs\Web\Controller { $header = $result['header']; $body = $result['body']; - - $body = mb_convert_encoding($body, 'UTF-8', 'UTF-8'); + + $body = mb_convert_encoding($body, 'UTF-8', (preg_match('/meta.+content=["|\']text\/html;\s+charset=([^"|\']+)/i', $body, $o) ? $o[1] : 'UTF-8')); $body = mb_convert_encoding($body, 'HTML-ENTITIES', "UTF-8"); $doc = new \DOMDocument(); diff --git a/Zotlabs/Module/Network.php b/Zotlabs/Module/Network.php index 792f92418..294e11c52 100644 --- a/Zotlabs/Module/Network.php +++ b/Zotlabs/Module/Network.php @@ -128,11 +128,12 @@ class Network extends \Zotlabs\Web\Controller { $xchan = ((x($_GET,'xchan')) ? $_GET['xchan'] : ''); $net = ((x($_GET,'net')) ? $_GET['net'] : ''); $pf = ((x($_GET,'pf')) ? $_GET['pf'] : ''); + $unseen = ((x($_GET,'unseen')) ? $_GET['unseen'] : ''); $deftag = ''; - if(x($_GET,'search') || $file || (!$pf && $cid) || $hashtags || $verb || $category) + if(x($_GET,'search') || $file || (!$pf && $cid) || $hashtags || $verb || $category || $conv || $unseen) $nouveau = true; if($cid) { @@ -220,6 +221,7 @@ class Network extends \Zotlabs\Web\Controller { $sql_extra = ''; if($group) { + $contact_str = ''; $contacts = group_get_members($group); if($contacts) { @@ -232,7 +234,6 @@ class Network extends \Zotlabs\Web\Controller { } } $item_thread_top = ''; - $sql_extra = " AND item.parent IN ( SELECT DISTINCT parent FROM item WHERE true $sql_options AND (( author_xchan IN ( $contact_str ) OR owner_xchan in ( $contact_str )) or allow_gid like '" . protect_sprintf('%<' . dbesc($group_hash) . '>%') . "' ) and id = parent $item_normal ) "; $x = group_rec_byhash(local_channel(), $group_hash); @@ -252,15 +253,35 @@ class Network extends \Zotlabs\Web\Controller { if($load || $update) { if(!$pf && $nouveau) { + // This is for nouveau view cid queries (not a public forum) $sql_extra = " AND author_xchan = '" . dbesc($cid_r[0]['abook_xchan']) . "' "; } + elseif($pf && $unseen && $nouveau) { + + // This is for nouveau view public forum cid queries (if a forum notification is clicked) + $p = q("SELECT oid AS parent FROM term WHERE uid = %d AND ttype = %d AND term = '%s'", + intval(local_channel()), + intval(TERM_FORUM), + dbesc($cid_r[0]['xchan_name']) + ); + + $p_str = ids_to_querystr($p, 'parent'); + if($p_str) + $p_sql = " OR item.parent IN ( $p_str ) "; + + $sql_extra = " AND ( owner_xchan = '" . protect_sprintf(dbesc($cid_r[0]['abook_xchan'])) . "' OR owner_xchan = '" . protect_sprintf(dbesc($cid_r[0]['abook_xchan'])) . "' $p_sql ) AND item_unseen = 1 "; + } else { + // This is for threaded view cid queries (e.g. if a forum is selected from the forum filter) $ttype = (($pf) ? TERM_FORUM : TERM_MENTION); $p1 = q("SELECT DISTINCT parent FROM item WHERE uid = " . intval(local_channel()) . " AND ( author_xchan = '" . dbesc($cid_r[0]['abook_xchan']) . "' OR owner_xchan = '" . dbesc($cid_r[0]['abook_xchan']) . "' ) $item_normal "); $p2 = q("SELECT oid AS parent FROM term WHERE uid = " . intval(local_channel()) . " AND ttype = $ttype AND term = '" . dbesc($cid_r[0]['xchan_name']) . "'"); $p_str = ids_to_querystr(array_merge($p1,$p2),'parent'); + if(! $p_str) + killme(); + $sql_extra = " AND item.parent IN ( $p_str ) "; } } @@ -345,7 +366,8 @@ class Network extends \Zotlabs\Web\Controller { '$verb' => $verb, '$net' => $net, '$dbegin' => $datequery2, - '$pf' => (($pf) ? $pf : '0'), + '$pf' => (($pf) ? $pf : '0'), + '$unseen' => $unseen )); } @@ -386,15 +408,7 @@ class Network extends \Zotlabs\Web\Controller { if($conv) { $item_thread_top = ''; - - if($nouveau) { - $sql_extra .= " AND author_xchan = '" . dbesc($channel['channel_hash']) . "' "; - } - else { - $sql_extra .= sprintf(" AND parent IN (SELECT distinct(parent) from item where ( author_xchan = '%s' or item_mentionsme = 1 )) ", - dbesc(protect_sprintf($channel['channel_hash'])) - ); - } + $sql_extra .= " AND ( author_xchan = '" . dbesc($channel['channel_hash']) . "' OR item_mentionsme = 1 ) "; } if($update && ! $load) { @@ -441,9 +455,11 @@ class Network extends \Zotlabs\Web\Controller { $page_mode = 'list'; else $page_mode = 'client'; - - $simple_update = (($update) ? " and item_unseen = 1 " : ''); + $parents_str = ''; + $update_unseen = ''; + + $simple_update = (($update) ? " and item_unseen = 1 " : ''); // This fixes a very subtle bug so I'd better explain it. You wake up in the morning or return after a day // or three and look at your matrix page - after opening up your browser. The first page loads just as it @@ -459,15 +475,15 @@ class Network extends \Zotlabs\Web\Controller { if($update && $_SESSION['loadtime']) $simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) "; - if($load) - $simple_update = ''; + + if($load) + $simple_update = ''; if($static && $simple_update) $simple_update .= " and item_thread_top = 0 and author_xchan = '" . protect_sprintf(get_observer_hash()) . "' "; if($nouveau && $load) { // "New Item View" - show all items unthreaded in reverse created date order - $items = q("SELECT item.*, item.id AS item_id, created FROM item left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids ) $net_query @@ -478,7 +494,12 @@ class Network extends \Zotlabs\Web\Controller { $net_query2 ORDER BY item.created DESC $pager_sql " ); - + + $parents_str = ids_to_querystr($items,'item_id'); + if($parents_str) { + $update_unseen = " AND id IN ( " . dbesc($parents_str) . " )"; + } + require_once('include/items.php'); xchan_query($items); @@ -521,8 +542,6 @@ class Network extends \Zotlabs\Web\Controller { } // Then fetch all the children of the parents that are on this page - $parents_str = ''; - $update_unseen = ''; if($r) { diff --git a/Zotlabs/Module/Photo.php b/Zotlabs/Module/Photo.php index 3f68e5c67..8efc00707 100644 --- a/Zotlabs/Module/Photo.php +++ b/Zotlabs/Module/Photo.php @@ -151,18 +151,6 @@ class Photo extends \Zotlabs\Web\Controller { $allowed = attach_can_view($r[0]['uid'],$observer_xchan,$photo); } - if(intval($r[0]['photo_usage'])) { - $allowed = 1; - if(intval($r[0]['photo_usage']) === PHOTO_COVER) - if($resolution < PHOTO_RES_COVER_1200) - $allowed = (-1); - if(intval($r[0]['photo_usage']) === PHOTO_PROFILE) - if(! in_array($resolution,[4,5,6])) - $allowed = (-1); - } - if($allowed === (-1)) - $allowed = attach_can_view($r[0]['uid'],$observer_xchan,$photo); - $channel = channelx_by_n($r[0]['uid']); // Now we'll see if we can access the photo diff --git a/Zotlabs/Module/Ping.php b/Zotlabs/Module/Ping.php index 14627f56e..75e8843d6 100644 --- a/Zotlabs/Module/Ping.php +++ b/Zotlabs/Module/Ping.php @@ -634,23 +634,30 @@ class Ping extends \Zotlabs\Web\Controller { if($vnotify & VNOTIFY_FORUMS) { $forums = get_forum_channels(local_channel()); - if(! $forums) { - $result['forums'] = 0; - } - else { - - $perms_sql = item_permissions_sql(local_channel()) . item_normal(); + if($forums) { + $perms_sql = item_permissions_sql(local_channel()); + $item_normal = item_normal(); $fcount = count($forums); $forums['total'] = 0; for($x = 0; $x < $fcount; $x ++) { - $r = q("select sum(item_unseen) as unseen from item - where uid = %d and owner_xchan = '%s' and item_unseen = 1 $perms_sql ", + $p = q("SELECT oid AS parent FROM term WHERE uid = %d AND ttype = %d AND term = '%s'", intval(local_channel()), + intval(TERM_FORUM), + dbesc($forums[$x]['xchan_hash']) + ); + + $p_str = ids_to_querystr($p, 'parent'); + $p_sql = (($p_str) ? "OR parent IN ( $p_str )" : ''); + + $r = q("select sum(item_unseen) as unseen from item + where uid = %d and ( owner_xchan = '%s' OR author_xchan = '%s' $p_sql ) and item_unseen = 1 $perms_sql $item_normal", + intval(local_channel()), + dbesc($forums[$x]['xchan_hash']), dbesc($forums[$x]['xchan_hash']) ); if($r[0]['unseen']) { - $forums[$x]['notify_link'] = (($forums[$x]['private_forum']) ? $forums[$x]['xchan_url'] : z_root() . '/network/?f=&pf=1&cid=' . $forums[$x]['abook_id']); + $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]['url'] = $forums[$x]['xchan_url']; $forums[$x]['photo'] = $forums[$x]['xchan_photo_s']; diff --git a/Zotlabs/Widget/Activity_filter.php b/Zotlabs/Widget/Activity_filter.php index 4ea0086dd..32ab10c77 100644 --- a/Zotlabs/Widget/Activity_filter.php +++ b/Zotlabs/Widget/Activity_filter.php @@ -16,35 +16,6 @@ class Activity_filter { $tabs = []; - if(feature_enabled(local_channel(),'personal_tab')) { - if(x($_GET,'conv')) { - $conv_active = (($_GET['conv'] == 1) ? 'active' : ''); - $filter_active = 'personal'; - } - - $tabs[] = [ - 'label' => t('Personal Posts'), - 'icon' => 'user-circle', - 'url' => z_root() . '/' . $cmd . '/?f=&conv=1', - 'sel' => $conv_active, - 'title' => t('Show posts that mention or involve me') - ]; - } - - if(feature_enabled(local_channel(),'star_posts')) { - if(x($_GET,'star')) { - $starred_active = (($_GET['star'] == 1) ? 'active' : ''); - $filter_active = 'star'; - } - - $tabs[] = [ - 'label' => t('Starred Posts'), - 'icon' => 'star', - 'url'=>z_root() . '/' . $cmd . '/?f=&star=1', - 'sel'=>$starred_active, - 'title' => t('Show posts that I have starred') - ]; - } if(Apps::system_app_installed(local_channel(), 'Privacy Groups')) { $groups = q("SELECT * FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC", @@ -110,6 +81,36 @@ class Activity_filter { } } + if(feature_enabled(local_channel(),'star_posts')) { + if(x($_GET,'star')) { + $starred_active = (($_GET['star'] == 1) ? 'active' : ''); + $filter_active = 'star'; + } + + $tabs[] = [ + 'label' => t('Starred Posts'), + 'icon' => 'star', + 'url'=>z_root() . '/' . $cmd . '/?f=&star=1', + 'sel'=>$starred_active, + 'title' => t('Show posts that I have starred') + ]; + } + + if(feature_enabled(local_channel(),'personal_tab')) { + if(x($_GET,'conv')) { + $conv_active = (($_GET['conv'] == 1) ? 'active' : ''); + $filter_active = 'personal'; + } + + $tabs[] = [ + 'label' => t('Personal Posts'), + 'icon' => 'user-circle', + 'url' => z_root() . '/' . $cmd . '/?f=&conv=1', + 'sel' => $conv_active, + 'title' => t('Show posts that mention or involve me') + ]; + } + if(feature_enabled(local_channel(),'filing')) { $terms = q("select distinct term from term where uid = %d and ttype = %d order by term asc", intval(local_channel()), diff --git a/Zotlabs/Widget/Activity_order.php b/Zotlabs/Widget/Activity_order.php index 1cba1ce8c..d3fe2a30f 100644 --- a/Zotlabs/Widget/Activity_order.php +++ b/Zotlabs/Widget/Activity_order.php @@ -54,8 +54,8 @@ class Activity_order { } } - // override order for search, filer and cid results - if(x($_GET,'search') || x($_GET,'file') || (! x($_GET,'pf') && x($_GET,'cid')) || x($_GET,'verb') || x($_GET,'tag') || x($_GET,'cat')) { + // override order for some filter results + if(x($_GET,'search') || x($_GET,'file') || (! x($_GET,'pf') && x($_GET,'cid')) || x($_GET,'verb') || x($_GET,'tag') || x($_GET,'cat') || x($_GET,'conv') || x($_GET,'unseen')) { $unthreaded_active = 'active'; $commentord_active = $postord_active = 'disabled'; } diff --git a/Zotlabs/Widget/Wiki_pages.php b/Zotlabs/Widget/Wiki_pages.php index f178c940d..dee0a2229 100644 --- a/Zotlabs/Widget/Wiki_pages.php +++ b/Zotlabs/Widget/Wiki_pages.php @@ -61,8 +61,6 @@ class Wiki_pages { $wikiname = ''; - $wikiname = ''; - $pages = array(); $p = \Zotlabs\Lib\NativeWikiPage::page_list($arr['channel_id'],get_observer_hash(),$arr['resource_id']); diff --git a/boot.php b/boot.php index aa1941d19..e01763ca5 100755 --- a/boot.php +++ b/boot.php @@ -50,7 +50,7 @@ require_once('include/attach.php'); require_once('include/bbcode.php'); define ( 'PLATFORM_NAME', 'hubzilla' ); -define ( 'STD_VERSION', '3.8.1' ); +define ( 'STD_VERSION', '3.8.2' ); define ( 'ZOT_REVISION', '6.0a' ); diff --git a/home.png b/home.png new file mode 100755 index 000000000..a9e2993eb Binary files /dev/null and b/home.png differ diff --git a/include/connections.php b/include/connections.php index 874237f97..d97ea3887 100644 --- a/include/connections.php +++ b/include/connections.php @@ -379,8 +379,6 @@ function contact_remove($channel_id, $abook_id) { intval($channel_id) ); if($r) { - $r = fetch_post_tags($r,true); - foreach($r as $rr) { $x = q("select uid from term where otype = %d and oid = %d and ttype = %d limit 1", intval(TERM_OBJ_POST), diff --git a/include/dba/dba_driver.php b/include/dba/dba_driver.php index 9e9f24bb3..9533acc7f 100755 --- a/include/dba/dba_driver.php +++ b/include/dba/dba_driver.php @@ -484,4 +484,4 @@ function db_columns($table) { } return []; -} \ No newline at end of file +} diff --git a/include/import.php b/include/import.php index 19e2bbcec..714161c57 100644 --- a/include/import.php +++ b/include/import.php @@ -168,7 +168,6 @@ function import_profiles($channel, $profiles) { unset($profile['id']); $profile['aid'] = get_account_id(); $profile['uid'] = $channel['channel_id']; - unset($profile['profile_vcard']); convert_oldfields($profile,'name','fullname'); convert_oldfields($profile,'with','partner'); diff --git a/include/items.php b/include/items.php index 58461cc3a..cae380b01 100755 --- a/include/items.php +++ b/include/items.php @@ -2150,6 +2150,7 @@ function item_store_update($arr, $allow_exec = false, $deliver = true) { unset($arr['created']); unset($arr['author_xchan']); unset($arr['owner_xchan']); + unset($arr['source_xchan']); unset($arr['thr_parent']); unset($arr['llink']); @@ -2514,7 +2515,7 @@ function tag_deliver($uid, $item_id) { // Just start the second delivery chain to deliver the updated post // after resetting ownership and permission bits logger('updating edited tag_deliver post for ' . $u[0]['channel_address']); - start_delivery_chain($u[0], $item, $item_id, 0); + start_delivery_chain($u[0], $item, $item_id, 0, true); return; } @@ -2941,7 +2942,7 @@ function tgroup_check($uid, $item) { * @param int $item_id * @param boolean $parent */ -function start_delivery_chain($channel, $item, $item_id, $parent) { +function start_delivery_chain($channel, $item, $item_id, $parent, $edit = false) { $sourced = check_item_source($channel['channel_id'],$item); @@ -2950,7 +2951,7 @@ function start_delivery_chain($channel, $item, $item_id, $parent) { intval($channel['channel_id']), dbesc(($item['source_xchan']) ? $item['source_xchan'] : $item['owner_xchan']) ); - if($r) { + if($r && ! $edit) { $t = trim($r[0]['src_tag']); if($t) { $tags = explode(',',$t); @@ -3017,9 +3018,17 @@ function start_delivery_chain($channel, $item, $item_id, $parent) { } else { $item_uplink = 1; - $r = q("update item set source_xchan = owner_xchan where id = %d", - intval($item_id) - ); + + // if this is an edit, item_store_update() will have already updated the item + // with the correct value for source_xchan (by ignoring it). We cannot set to owner_xchan + // in this case because owner_xchan will point to the parent of this chain + // and not the original sender. + + if(! $edit) { + $r = q("update item set source_xchan = owner_xchan where id = %d", + intval($item_id) + ); + } } $title = $item['title']; diff --git a/include/nav.php b/include/nav.php index 9c15552e2..d405b9f06 100644 --- a/include/nav.php +++ b/include/nav.php @@ -224,7 +224,6 @@ function nav($template = 'default') { //app bin if($is_owner) { - //daily system apps import if(get_pconfig(local_channel(), 'system','import_system_apps') !== datetime_convert('UTC','UTC','now','Y-m-d')) { Apps::import_system_apps(); set_pconfig(local_channel(), 'system','import_system_apps', datetime_convert('UTC','UTC','now','Y-m-d')); diff --git a/include/zot.php b/include/zot.php index 4a8892083..1a632cf87 100644 --- a/include/zot.php +++ b/include/zot.php @@ -4327,7 +4327,7 @@ function zotinfo($arr) { if($role === 'forum' || $role === 'repository') { $public_forum = true; } - elseif($ztarget_hash) { + else { // check if it has characteristics of a public forum based on custom permissions. $m = \Zotlabs\Access\Permissions::FilledAutoperms($e['channel_id']); if($m) { diff --git a/install/schema_postgres.sql b/install/schema_postgres.sql index 5d1b8baaa..cb4476628 100644 --- a/install/schema_postgres.sql +++ b/install/schema_postgres.sql @@ -1,6 +1,6 @@ CREATE TABLE "abconfig" ( "id" serial NOT NULL, - "chan" bigint NOT NULL DEFAULT 0, + "chan" bigint NOT NULL DEFAULT '0', "xchan" text NOT NULL, "cat" text NOT NULL, "k" text NOT NULL, @@ -73,13 +73,13 @@ CREATE TABLE "account" ( "account_language" varchar(16) NOT NULL DEFAULT 'en', "account_created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', "account_lastlog" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', - "account_flags" bigint NOT NULL DEFAULT 0 , - "account_roles" bigint NOT NULL DEFAULT 0 , + "account_flags" bigint NOT NULL DEFAULT '0', + "account_roles" bigint NOT NULL DEFAULT '0', "account_reset" text NOT NULL DEFAULT '', "account_expires" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', "account_expire_notified" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', "account_service_class" varchar(32) NOT NULL DEFAULT '', - "account_level" bigint NOT NULL DEFAULT 0 , + "account_level" bigint NOT NULL DEFAULT '0', "account_password_changed" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', PRIMARY KEY ("account_id") ); @@ -97,11 +97,11 @@ create index "account_password_changed" on account ("account_password_changed") CREATE TABLE "addon" ( "id" serial NOT NULL, "aname" text NOT NULL, - "version" text NOT NULL DEFAULT 0 , - "installed" numeric(1) NOT NULL DEFAULT 0 , - "hidden" numeric(1) NOT NULL DEFAULT 0 , - "tstamp" numeric(20) NOT NULL DEFAULT 0 , - "plugin_admin" numeric(1) NOT NULL DEFAULT 0 , + "version" text NOT NULL DEFAULT '0', + "installed" numeric(1) NOT NULL DEFAULT '0', + "hidden" numeric(1) NOT NULL DEFAULT '0', + "tstamp" numeric(20) NOT NULL DEFAULT '0', + "plugin_admin" numeric(1) NOT NULL DEFAULT '0', PRIMARY KEY ("id") ); create index "addon_hidden_idx" on addon ("hidden"); @@ -117,13 +117,13 @@ CREATE TABLE "app" ( "app_url" text NOT NULL DEFAULT '', "app_photo" text NOT NULL DEFAULT '', "app_version" text NOT NULL DEFAULT '', - "app_channel" bigint NOT NULL DEFAULT 0 , + "app_channel" bigint NOT NULL DEFAULT '0', "app_addr" text NOT NULL DEFAULT '', "app_price" text NOT NULL DEFAULT '', "app_page" text NOT NULL DEFAULT '', "app_requires" text NOT NULL DEFAULT '', - "app_deleted" smallint NOT NULL DEFAULT 0 , - "app_system" smallint NOT NULL DEFAULT 0 , + "app_deleted" smallint NOT NULL DEFAULT '0', + "app_system" smallint NOT NULL DEFAULT '0', "app_plugin" text NOT NULL DEFAULT '', "app_options" smallint NOT NULL DEFAULT '0', "app_created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', @@ -159,19 +159,19 @@ create index atoken_expires on atoken (atoken_expires); CREATE TABLE "attach" ( "id" serial NOT NULL, - "aid" bigint NOT NULL DEFAULT 0 , - "uid" bigint NOT NULL DEFAULT 0 , + "aid" bigint NOT NULL DEFAULT '0', + "uid" bigint NOT NULL DEFAULT '0', "hash" varchar(64) NOT NULL DEFAULT '', "creator" varchar(128) NOT NULL DEFAULT '', "filename" text NOT NULL DEFAULT '', "filetype" varchar(64) NOT NULL DEFAULT '', - "filesize" bigint NOT NULL DEFAULT 0 , - "revision" bigint NOT NULL DEFAULT 0 , + "filesize" bigint NOT NULL DEFAULT '0', + "revision" bigint NOT NULL DEFAULT '0', "folder" varchar(64) NOT NULL DEFAULT '', - "flags" bigint NOT NULL DEFAULT 0 , - "is_dir" smallint NOT NULL DEFAULT 0 , - "is_photo" smallint NOT NULL DEFAULT 0 , - "os_storage" smallint NOT NULL DEFAULT 0 , + "flags" bigint NOT NULL DEFAULT '0', + "is_dir" smallint NOT NULL DEFAULT '0', + "is_photo" smallint NOT NULL DEFAULT '0', + "os_storage" smallint NOT NULL DEFAULT '0', "os_path" text NOT NULL, "display_path" text NOT NULL, "content" bytea NOT NULL, @@ -215,8 +215,8 @@ CREATE TABLE "cache" ( ); CREATE TABLE "cal" ( "cal_id" serial NOT NULL, - "cal_aid" bigint NOT NULL DEFAULT 0 , - "cal_uid" bigint NOT NULL DEFAULT 0 , + "cal_aid" bigint NOT NULL DEFAULT '0', + "cal_uid" bigint NOT NULL DEFAULT '0', "cal_hash" text NOT NULL, "cal_name" text NOT NULL, "uri" text NOT NULL, @@ -224,7 +224,7 @@ CREATE TABLE "cal" ( "pass" text NOT NULL, "ctag" text NOT NULL, "synctoken" text NOT NULL, - "cal_types" text NOT NULL DEFAULT 0 , + "cal_types" text NOT NULL DEFAULT '0', PRIMARY KEY ("cal_id") ); create index "cal_hash_idx" on cal ("cal_hash"); @@ -235,8 +235,8 @@ create index "cal_uid_idx" on cal ("cal_uid"); CREATE TABLE "channel" ( "channel_id" serial NOT NULL, - "channel_account_id" bigint NOT NULL DEFAULT 0 , - "channel_primary" numeric(1) NOT NULL DEFAULT 0 , + "channel_account_id" bigint NOT NULL DEFAULT '0', + "channel_primary" numeric(1) NOT NULL DEFAULT '0', "channel_name" text NOT NULL DEFAULT '', "channel_address" text NOT NULL DEFAULT '', "channel_guid" text NOT NULL DEFAULT '', @@ -248,8 +248,8 @@ CREATE TABLE "channel" ( "channel_startpage" text NOT NULL DEFAULT '', "channel_pubkey" text NOT NULL, "channel_prvkey" text NOT NULL, - "channel_notifyflags" bigint NOT NULL DEFAULT 65535, - "channel_pageflags" bigint NOT NULL DEFAULT 0 , + "channel_notifyflags" bigint NOT NULL DEFAULT '65535', + "channel_pageflags" bigint NOT NULL DEFAULT '0', "channel_dirdate" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', "channel_lastpost" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', "channel_deleted" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', @@ -294,7 +294,7 @@ create index "channel_system" on channel ("channel_system"); create index "channel_moved" on channel ("channel_moved"); CREATE TABLE "chat" ( "chat_id" serial NOT NULL, - "chat_room" bigint NOT NULL DEFAULT 0 , + "chat_room" bigint NOT NULL DEFAULT '0', "chat_xchan" text NOT NULL DEFAULT '', "chat_text" text NOT NULL, "created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', @@ -305,7 +305,7 @@ create index "chat_xchan_idx" on chat ("chat_xchan"); create index "chat_created_idx" on chat ("created"); CREATE TABLE "chatpresence" ( "cp_id" serial NOT NULL, - "cp_room" bigint NOT NULL DEFAULT 0 , + "cp_room" bigint NOT NULL DEFAULT '0', "cp_xchan" text NOT NULL DEFAULT '', "cp_last" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', "cp_status" text NOT NULL, @@ -319,12 +319,12 @@ create index "cp_status" on chatpresence ("cp_status"); CREATE TABLE "chatroom" ( "cr_id" serial NOT NULL, - "cr_aid" bigint NOT NULL DEFAULT 0 , - "cr_uid" bigint NOT NULL DEFAULT 0 , + "cr_aid" bigint NOT NULL DEFAULT '0', + "cr_uid" bigint NOT NULL DEFAULT '0', "cr_name" text NOT NULL DEFAULT '', "cr_created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', "cr_edited" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', - "cr_expire" bigint NOT NULL DEFAULT 0 , + "cr_expire" bigint NOT NULL DEFAULT '0', "allow_cid" text NOT NULL, "allow_gid" text NOT NULL, "deny_cid" text NOT NULL, @@ -343,7 +343,7 @@ CREATE TABLE "clients" ( "redirect_uri" varchar(200) NOT NULL, "clname" text, "icon" text, - "uid" bigint NOT NULL DEFAULT 0 , + "uid" bigint NOT NULL DEFAULT '0', PRIMARY KEY ("client_id") ); CREATE TABLE "config" ( @@ -390,9 +390,9 @@ create index "dreport_channel" on dreport ("dreport_channel"); CREATE TABLE "event" ( "id" serial NOT NULL, - "aid" bigint NOT NULL DEFAULT 0 , + "aid" bigint NOT NULL DEFAULT '0', "uid" bigint NOT NULL, - "cal_id" bigint NOT NULL DEFAULT 0 , + "cal_id" bigint NOT NULL DEFAULT '0', "event_xchan" text NOT NULL DEFAULT '', "event_hash" text NOT NULL DEFAULT '', "created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', @@ -403,19 +403,19 @@ CREATE TABLE "event" ( "description" text NOT NULL, "location" text NOT NULL, "etype" text NOT NULL, - "nofinish" numeric(1) NOT NULL DEFAULT 0 , - "adjust" numeric(1) NOT NULL DEFAULT 1, - "dismissed" numeric(1) NOT NULL DEFAULT 0 , + "nofinish" numeric(1) NOT NULL DEFAULT '0', + "adjust" numeric(1) NOT NULL DEFAULT '1', + "dismissed" numeric(1) NOT NULL DEFAULT '0', "allow_cid" text NOT NULL, "allow_gid" text NOT NULL, "deny_cid" text NOT NULL, "deny_gid" text NOT NULL, "event_status" varchar(255) NOT NULL DEFAULT '', "event_status_date" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', - "event_percent" smallint NOT NULL DEFAULT 0 , + "event_percent" smallint NOT NULL DEFAULT '0', "event_repeat" text NOT NULL, - "event_sequence" smallint NOT NULL DEFAULT 0 , - "event_priority" smallint NOT NULL DEFAULT 0 , + "event_sequence" smallint NOT NULL DEFAULT '0', + "event_priority" smallint NOT NULL DEFAULT '0', "event_vdata" text NOT NULL, PRIMARY KEY ("id") ); @@ -449,8 +449,8 @@ CREATE TABLE "pgrp" ( "id" serial NOT NULL, "hash" text NOT NULL DEFAULT '', "uid" bigint NOT NULL, - "visible" numeric(1) NOT NULL DEFAULT 0 , - "deleted" numeric(1) NOT NULL DEFAULT 0 , + "visible" numeric(1) NOT NULL DEFAULT '0', + "deleted" numeric(1) NOT NULL DEFAULT '0', "gname" text NOT NULL, PRIMARY KEY ("id") @@ -465,8 +465,8 @@ CREATE TABLE "hook" ( "hook" text NOT NULL, "file" text NOT NULL, "fn" text NOT NULL, - "priority" smallint NOT NULL DEFAULT 0 , - "hook_version" smallint NOT NULL DEFAULT 0 , + "priority" smallint NOT NULL DEFAULT '0', + "hook_version" smallint NOT NULL DEFAULT '0', PRIMARY KEY ("id") ); @@ -483,8 +483,8 @@ CREATE TABLE "hubloc" ( "hubloc_hash" text NOT NULL, "hubloc_addr" text NOT NULL DEFAULT '', "hubloc_network" text NOT NULL DEFAULT '', - "hubloc_flags" bigint NOT NULL DEFAULT 0 , - "hubloc_status" bigint NOT NULL DEFAULT 0 , + "hubloc_flags" bigint NOT NULL DEFAULT '0', + "hubloc_status" bigint NOT NULL DEFAULT '0', "hubloc_url" text NOT NULL DEFAULT '', "hubloc_url_sig" text NOT NULL DEFAULT '', "hubloc_site_id" text NOT NULL DEFAULT '', @@ -494,10 +494,10 @@ CREATE TABLE "hubloc" ( "hubloc_sitekey" text NOT NULL DEFAULT '', "hubloc_updated" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', "hubloc_connected" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', - "hubloc_primary" smallint NOT NULL DEFAULT 0 , - "hubloc_orphancheck" smallint NOT NULL DEFAULT 0 , - "hubloc_error" smallint NOT NULL DEFAULT 0 , - "hubloc_deleted" smallint NOT NULL DEFAULT 0 , + "hubloc_primary" smallint NOT NULL DEFAULT '0', + "hubloc_orphancheck" smallint NOT NULL DEFAULT '0', + "hubloc_error" smallint NOT NULL DEFAULT '0', + "hubloc_deleted" smallint NOT NULL DEFAULT '0', PRIMARY KEY ("hubloc_id") ); create index "hubloc_url" on hubloc ("hubloc_url"); @@ -518,11 +518,11 @@ create index "hubloc_error" on hubloc ("hubloc_error"); create index "hubloc_deleted" on hubloc ("hubloc_deleted"); CREATE TABLE "iconfig" ( "id" serial NOT NULL, - "iid" bigint NOT NULL DEFAULT 0 , + "iid" bigint NOT NULL DEFAULT '0', "cat" text NOT NULL DEFAULT '', "k" text NOT NULL DEFAULT '', "v" text NOT NULL DEFAULT '', - "sharing" int NOT NULL DEFAULT 0 , + "sharing" int NOT NULL DEFAULT '0', PRIMARY KEY("id") ); create index "iconfig_iid" on iconfig ("iid"); @@ -549,9 +549,9 @@ create index "issue_component" on issue ("issue_component"); CREATE TABLE "item" ( "id" serial NOT NULL, "mid" text NOT NULL DEFAULT '', - "aid" bigint NOT NULL DEFAULT 0 , - "uid" bigint NOT NULL DEFAULT 0 , - "parent" bigint NOT NULL DEFAULT 0 , + "aid" bigint NOT NULL DEFAULT '0', + "uid" bigint NOT NULL DEFAULT '0', + "parent" bigint NOT NULL DEFAULT '0', "parent_mid" text NOT NULL DEFAULT '', "thr_parent" text NOT NULL DEFAULT '', "created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', @@ -570,7 +570,7 @@ CREATE TABLE "item" ( "html" text NOT NULL, "app" text NOT NULL DEFAULT '', "lang" varchar(64) NOT NULL DEFAULT '', - "revision" bigint NOT NULL DEFAULT 0 , + "revision" bigint NOT NULL DEFAULT '0', "verb" text NOT NULL DEFAULT '', "obj_type" text NOT NULL DEFAULT '', "obj" text NOT NULL, @@ -593,32 +593,32 @@ CREATE TABLE "item" ( "allow_gid" text NOT NULL, "deny_cid" text NOT NULL, "deny_gid" text NOT NULL, - "item_restrict" bigint NOT NULL DEFAULT 0 , - "item_flags" bigint NOT NULL DEFAULT 0 , - "item_private" numeric(4) NOT NULL DEFAULT 0 , - "item_unseen" smallint NOT NULL DEFAULT 0 , - "item_wall" smallint NOT NULL DEFAULT 0 , - "item_origin" smallint NOT NULL DEFAULT 0 , - "item_starred" smallint NOT NULL DEFAULT 0 , - "item_uplink" smallint NOT NULL DEFAULT 0 , - "item_consensus" smallint NOT NULL DEFAULT 0 , - "item_thread_top" smallint NOT NULL DEFAULT 0 , - "item_notshown" smallint NOT NULL DEFAULT 0 , - "item_nsfw" smallint NOT NULL DEFAULT 0 , - "item_relay" smallint NOT NULL DEFAULT 0 , - "item_mentionsme" smallint NOT NULL DEFAULT 0 , - "item_nocomment" smallint NOT NULL DEFAULT 0 , - "item_obscured" smallint NOT NULL DEFAULT 0 , - "item_verified" smallint NOT NULL DEFAULT 0 , - "item_retained" smallint NOT NULL DEFAULT 0 , - "item_rss" smallint NOT NULL DEFAULT 0 , - "item_deleted" smallint NOT NULL DEFAULT 0 , - "item_type" int NOT NULL DEFAULT 0 , - "item_hidden" smallint NOT NULL DEFAULT 0 , - "item_unpublished" smallint NOT NULL DEFAULT 0 , - "item_delayed" smallint NOT NULL DEFAULT 0 , - "item_pending_remove" smallint NOT NULL DEFAULT 0 , - "item_blocked" smallint NOT NULL DEFAULT 0 , + "item_restrict" bigint NOT NULL DEFAULT '0', + "item_flags" bigint NOT NULL DEFAULT '0', + "item_private" numeric(4) NOT NULL DEFAULT '0', + "item_unseen" smallint NOT NULL DEFAULT '0', + "item_wall" smallint NOT NULL DEFAULT '0', + "item_origin" smallint NOT NULL DEFAULT '0', + "item_starred" smallint NOT NULL DEFAULT '0', + "item_uplink" smallint NOT NULL DEFAULT '0', + "item_consensus" smallint NOT NULL DEFAULT '0', + "item_thread_top" smallint NOT NULL DEFAULT '0', + "item_notshown" smallint NOT NULL DEFAULT '0', + "item_nsfw" smallint NOT NULL DEFAULT '0', + "item_relay" smallint NOT NULL DEFAULT '0', + "item_mentionsme" smallint NOT NULL DEFAULT '0', + "item_nocomment" smallint NOT NULL DEFAULT '0', + "item_obscured" smallint NOT NULL DEFAULT '0', + "item_verified" smallint NOT NULL DEFAULT '0', + "item_retained" smallint NOT NULL DEFAULT '0', + "item_rss" smallint NOT NULL DEFAULT '0', + "item_deleted" smallint NOT NULL DEFAULT '0', + "item_type" int NOT NULL DEFAULT '0', + "item_hidden" smallint NOT NULL DEFAULT '0', + "item_unpublished" smallint NOT NULL DEFAULT '0', + "item_delayed" smallint NOT NULL DEFAULT '0', + "item_pending_remove" smallint NOT NULL DEFAULT '0', + "item_blocked" smallint NOT NULL DEFAULT '0', "item_search_vector" tsvector, PRIMARY KEY ("id") ); @@ -731,9 +731,9 @@ create index "ltype_idx" on listeners ("ltype"); CREATE TABLE "mail" ( "id" serial NOT NULL, - "convid" bigint NOT NULL DEFAULT 0 , + "convid" bigint NOT NULL DEFAULT '0', "conv_guid" text NOT NULL, - "mail_flags" bigint NOT NULL DEFAULT 0 , + "mail_flags" bigint NOT NULL DEFAULT '0', "from_xchan" text NOT NULL DEFAULT '', "to_xchan" text NOT NULL DEFAULT '', "account_id" bigint NOT NULL DEFAULT '0', @@ -745,13 +745,13 @@ CREATE TABLE "mail" ( "attach" text NOT NULL DEFAULT '', "mid" text NOT NULL, "parent_mid" text NOT NULL, - "mail_deleted" smallint NOT NULL DEFAULT 0 , - "mail_replied" smallint NOT NULL DEFAULT 0 , - "mail_isreply" smallint NOT NULL DEFAULT 0 , - "mail_seen" smallint NOT NULL DEFAULT 0 , - "mail_recalled" smallint NOT NULL DEFAULT 0 , - "mail_obscured" smallint NOT NULL DEFAULT 0 , - "mail_raw" smallint NOT NULL DEFAULT 0 , + "mail_deleted" smallint NOT NULL DEFAULT '0', + "mail_replied" smallint NOT NULL DEFAULT '0', + "mail_isreply" smallint NOT NULL DEFAULT '0', + "mail_seen" smallint NOT NULL DEFAULT '0', + "mail_recalled" smallint NOT NULL DEFAULT '0', + "mail_obscured" smallint NOT NULL DEFAULT '0', + "mail_raw" smallint NOT NULL DEFAULT '0', "created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', "expires" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', PRIMARY KEY ("id") @@ -775,10 +775,10 @@ create index "mail_recalled" on mail ("mail_recalled"); create index "mail_obscured" on mail ("mail_obscured"); CREATE TABLE "menu" ( "menu_id" serial NOT NULL, - "menu_channel_id" bigint NOT NULL DEFAULT 0 , + "menu_channel_id" bigint NOT NULL DEFAULT '0', "menu_name" text NOT NULL DEFAULT '', "menu_desc" text NOT NULL DEFAULT '', - "menu_flags" bigint NOT NULL DEFAULT 0 , + "menu_flags" bigint NOT NULL DEFAULT '0', "menu_created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', "menu_edited" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', PRIMARY KEY ("menu_id") @@ -792,14 +792,14 @@ CREATE TABLE "menu_item" ( "mitem_id" serial NOT NULL, "mitem_link" text NOT NULL DEFAULT '', "mitem_desc" text NOT NULL DEFAULT '', - "mitem_flags" bigint NOT NULL DEFAULT 0 , + "mitem_flags" bigint NOT NULL DEFAULT '0', "allow_cid" text NOT NULL, "allow_gid" text NOT NULL, "deny_cid" text NOT NULL, "deny_gid" text NOT NULL, "mitem_channel_id" bigint NOT NULL, - "mitem_menu_id" bigint NOT NULL DEFAULT 0 , - "mitem_order" bigint NOT NULL DEFAULT 0 , + "mitem_menu_id" bigint NOT NULL DEFAULT '0', + "mitem_order" bigint NOT NULL DEFAULT '0', PRIMARY KEY ("mitem_id") ); @@ -818,7 +818,7 @@ CREATE TABLE "notify" ( "uid" bigint NOT NULL, "link" text NOT NULL, "parent" text NOT NULL DEFAULT '', - "seen" numeric(1) NOT NULL DEFAULT 0 , + "seen" numeric(1) NOT NULL DEFAULT '0', "ntype" bigint NOT NULL, "verb" text NOT NULL, "otype" varchar(16) NOT NULL, @@ -867,18 +867,18 @@ create index "obj_quantity" on obj ("obj_quantity"); CREATE TABLE "outq" ( "outq_hash" text NOT NULL, - "outq_account" bigint NOT NULL DEFAULT 0 , - "outq_channel" bigint NOT NULL DEFAULT 0 , + "outq_account" bigint NOT NULL DEFAULT '0', + "outq_channel" bigint NOT NULL DEFAULT '0', "outq_driver" varchar(32) NOT NULL DEFAULT '', "outq_posturl" text NOT NULL DEFAULT '', - "outq_async" numeric(1) NOT NULL DEFAULT 0 , - "outq_delivered" numeric(1) NOT NULL DEFAULT 0 , + "outq_async" numeric(1) NOT NULL DEFAULT '0', + "outq_delivered" numeric(1) NOT NULL DEFAULT '0', "outq_created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', "outq_updated" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', "outq_scheduled" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', "outq_notify" text NOT NULL, "outq_msg" text NOT NULL, - "outq_priority" smallint NOT NULL DEFAULT 0 , + "outq_priority" smallint NOT NULL DEFAULT '0', PRIMARY KEY ("outq_hash") ); create index "outq_account" on outq ("outq_account"); @@ -906,7 +906,7 @@ create index "pchan_hash" on pchan ("pchan_hash"); CREATE TABLE "pconfig" ( "id" serial NOT NULL, - "uid" bigint NOT NULL DEFAULT 0 , + "uid" bigint NOT NULL DEFAULT '0', "cat" text NOT NULL, "k" text NOT NULL, "v" text NOT NULL, @@ -916,7 +916,7 @@ CREATE TABLE "pconfig" ( CREATE TABLE "photo" ( "id" serial NOT NULL, - "aid" bigint NOT NULL DEFAULT 0 , + "aid" bigint NOT NULL DEFAULT '0', "uid" bigint NOT NULL, "xchan" text NOT NULL DEFAULT '', "resource_id" text NOT NULL, @@ -929,16 +929,16 @@ CREATE TABLE "photo" ( "mimetype" varchar(128) NOT NULL DEFAULT 'image/jpeg', "height" numeric(6) NOT NULL, "width" numeric(6) NOT NULL, - "filesize" bigint NOT NULL DEFAULT 0 , + "filesize" bigint NOT NULL DEFAULT '0', "content" bytea NOT NULL, - "imgscale" numeric(3) NOT NULL DEFAULT 0 , - "profile" numeric(1) NOT NULL DEFAULT 0 , - "photo_usage" smallint NOT NULL DEFAULT 0 , - "is_nsfw" smallint NOT NULL DEFAULT 0 , - "os_storage" smallint NOT NULL DEFAULT 0 , + "imgscale" numeric(3) NOT NULL DEFAULT '0', + "profile" numeric(1) NOT NULL DEFAULT '0', + "photo_usage" smallint NOT NULL DEFAULT '0', + "is_nsfw" smallint NOT NULL DEFAULT '0', + "os_storage" smallint NOT NULL DEFAULT '0', "os_path" text NOT NULL, "display_path" text NOT NULL, - "photo_flags" bigint NOT NULL DEFAULT 0 , + "photo_flags" bigint NOT NULL DEFAULT '0', "allow_cid" text NOT NULL, "allow_gid" text NOT NULL, "deny_cid" text NOT NULL, @@ -965,8 +965,8 @@ CREATE TABLE "poll" ( "poll_channel" bigint NOT NULL DEFAULT '0', "poll_author" text NOT NULL, "poll_desc" text NOT NULL, - "poll_flags" bigint NOT NULL DEFAULT 0 , - "poll_votes" bigint NOT NULL DEFAULT 0 , + "poll_flags" bigint NOT NULL DEFAULT '0', + "poll_votes" bigint NOT NULL DEFAULT '0', PRIMARY KEY ("poll_id") ); @@ -1002,7 +1002,7 @@ CREATE TABLE "profdef" ( create index "profdef_field_name" on profdef ("field_name"); CREATE TABLE "profext" ( "id" serial NOT NULL, - "channel_id" bigint NOT NULL DEFAULT 0 , + "channel_id" bigint NOT NULL DEFAULT '0', "hash" text NOT NULL DEFAULT '', "k" text NOT NULL DEFAULT '', "v" text NOT NULL, @@ -1018,8 +1018,8 @@ CREATE TABLE "profile" ( "aid" bigint NOT NULL DEFAULT '0', "uid" bigint NOT NULL, "profile_name" text NOT NULL, - "is_default" numeric(1) NOT NULL DEFAULT 0 , - "hide_friends" numeric(1) NOT NULL DEFAULT 0 , + "is_default" numeric(1) NOT NULL DEFAULT '0', + "hide_friends" numeric(1) NOT NULL DEFAULT '0', "fullname" text NOT NULL, "pdesc" text NOT NULL DEFAULT '', "chandesc" text NOT NULL DEFAULT '', @@ -1056,7 +1056,7 @@ CREATE TABLE "profile" ( "homepage" text NOT NULL DEFAULT '', "photo" text NOT NULL, "thumb" text NOT NULL, - "publish" numeric(1) NOT NULL DEFAULT 0 , + "publish" numeric(1) NOT NULL DEFAULT '0', "profile_vcard" text NOT NULL DEFAULT '', PRIMARY KEY ("id"), UNIQUE ("profile_guid","uid") @@ -1078,7 +1078,7 @@ create index "profile_guid" on profile ("profile_guid"); CREATE TABLE "profile_check" ( "id" serial NOT NULL, "uid" bigint NOT NULL, - "cid" bigint NOT NULL DEFAULT 0 , + "cid" bigint NOT NULL DEFAULT '0', "dfrn_id" text NOT NULL, "sec" text NOT NULL, "expire" bigint NOT NULL, @@ -1113,8 +1113,8 @@ create index "session_sid" on session ("sid"); create index "session_expire" on session ("expire"); CREATE TABLE "shares" ( "share_id" serial NOT NULL, - "share_type" bigint NOT NULL DEFAULT 0 , - "share_target" bigint NOT NULL DEFAULT 0 , + "share_type" bigint NOT NULL DEFAULT '0', + "share_target" bigint NOT NULL DEFAULT '0', "share_xchan" text NOT NULL DEFAULT '', PRIMARY KEY ("share_id") ); @@ -1124,8 +1124,8 @@ create index "share_xchan" on shares ("share_xchan"); CREATE TABLE "sign" ( "id" serial NOT NULL, - "iid" bigint NOT NULL DEFAULT 0 , - "retract_iid" bigint NOT NULL DEFAULT 0 , + "iid" bigint NOT NULL DEFAULT '0', + "retract_iid" bigint NOT NULL DEFAULT '0', "signed_text" text NOT NULL, "signature" text NOT NULL, "signer" text NOT NULL, @@ -1136,19 +1136,19 @@ create index "sign_retract_iid" on "sign" ("retract_iid"); CREATE TABLE "site" ( "site_url" text NOT NULL, - "site_access" bigint NOT NULL DEFAULT 0 , - "site_flags" bigint NOT NULL DEFAULT 0 , + "site_access" bigint NOT NULL DEFAULT '0', + "site_flags" bigint NOT NULL DEFAULT '0', "site_update" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', "site_pull" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', "site_sync" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', "site_directory" text NOT NULL DEFAULT '', - "site_register" bigint NOT NULL DEFAULT 0 , + "site_register" bigint NOT NULL DEFAULT '0', "site_sellpage" text NOT NULL DEFAULT '', "site_location" text NOT NULL DEFAULT '', "site_realm" text NOT NULL DEFAULT '', - "site_valid" smallint NOT NULL DEFAULT 0 , - "site_dead" smallint NOT NULL DEFAULT 0 , - "site_type" smallint NOT NULL DEFAULT 0 , + "site_valid" smallint NOT NULL DEFAULT '0', + "site_dead" smallint NOT NULL DEFAULT '0', + "site_type" smallint NOT NULL DEFAULT '0', "site_project" text NOT NULL DEFAULT '', "site_version" text NOT NULL DEFAULT '', "site_crypto" text NOT NULL DEFAULT '', @@ -1168,7 +1168,7 @@ create index "site_project" on site ("site_project"); CREATE TABLE "source" ( "src_id" serial NOT NULL, - "src_channel_id" bigint NOT NULL DEFAULT 0 , + "src_channel_id" bigint NOT NULL DEFAULT '0', "src_channel_xchan" text NOT NULL DEFAULT '', "src_xchan" text NOT NULL DEFAULT '', "src_patt" text NOT NULL DEFAULT '', @@ -1188,8 +1188,8 @@ CREATE TABLE "sys_perms" ( ); CREATE TABLE "term" ( "tid" serial NOT NULL, - "aid" bigint NOT NULL DEFAULT 0 , - "uid" bigint NOT NULL DEFAULT 0 , + "aid" bigint NOT NULL DEFAULT '0', + "uid" bigint NOT NULL DEFAULT '0', "oid" bigint NOT NULL, "otype" numeric(3) NOT NULL, "ttype" numeric(3) NOT NULL, @@ -1228,7 +1228,7 @@ CREATE TABLE "updates" ( "ud_guid" text NOT NULL DEFAULT '', "ud_date" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', "ud_last" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', - "ud_flags" bigint NOT NULL DEFAULT 0 , + "ud_flags" bigint NOT NULL DEFAULT '0', "ud_addr" text NOT NULL DEFAULT '', PRIMARY KEY ("ud_id") ); @@ -1240,7 +1240,7 @@ create index "ud_addr" on updates ("ud_addr"); create index "ud_last" on updates ("ud_last"); CREATE TABLE "verify" ( "id" serial NOT NULL, - "channel" bigint NOT NULL DEFAULT 0 , + "channel" bigint NOT NULL DEFAULT '0', "vtype" varchar(32) NOT NULL DEFAULT '', "token" text NOT NULL DEFAULT '', "meta" text NOT NULL DEFAULT '', @@ -1282,16 +1282,16 @@ CREATE TABLE "xchan" ( "xchan_name" text NOT NULL DEFAULT '', "xchan_network" text NOT NULL DEFAULT '', "xchan_instance_url" text NOT NULL DEFAULT '', - "xchan_flags" bigint NOT NULL DEFAULT 0 , + "xchan_flags" bigint NOT NULL DEFAULT '0', "xchan_photo_date" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', "xchan_name_date" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', - "xchan_hidden" smallint NOT NULL DEFAULT 0 , - "xchan_orphan" smallint NOT NULL DEFAULT 0 , - "xchan_censored" smallint NOT NULL DEFAULT 0 , - "xchan_selfcensored" smallint NOT NULL DEFAULT 0 , - "xchan_system" smallint NOT NULL DEFAULT 0 , - "xchan_pubforum" smallint NOT NULL DEFAULT 0 , - "xchan_deleted" smallint NOT NULL DEFAULT 0 , + "xchan_hidden" smallint NOT NULL DEFAULT '0', + "xchan_orphan" smallint NOT NULL DEFAULT '0', + "xchan_censored" smallint NOT NULL DEFAULT '0', + "xchan_selfcensored" smallint NOT NULL DEFAULT '0', + "xchan_system" smallint NOT NULL DEFAULT '0', + "xchan_pubforum" smallint NOT NULL DEFAULT '0', + "xchan_deleted" smallint NOT NULL DEFAULT '0', PRIMARY KEY ("xchan_hash") ); create index "xchan_guid" on xchan ("xchan_guid"); @@ -1336,7 +1336,7 @@ create index "xconfig_cat" on xconfig ("cat"); create index "xconfig_k" on xconfig ("k"); CREATE TABLE "xign" ( "id" serial NOT NULL, - "uid" bigint NOT NULL DEFAULT 0 , + "uid" bigint NOT NULL DEFAULT '0', "xchan" text NOT NULL DEFAULT '', PRIMARY KEY ("id") ); @@ -1346,10 +1346,10 @@ CREATE TABLE "xlink" ( "xlink_id" serial NOT NULL, "xlink_xchan" text NOT NULL DEFAULT '', "xlink_link" text NOT NULL DEFAULT '', - "xlink_rating" bigint NOT NULL DEFAULT 0 , + "xlink_rating" bigint NOT NULL DEFAULT '0', "xlink_rating_text" TEXT NOT NULL DEFAULT '', "xlink_updated" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00', - "xlink_static" numeric(1) NOT NULL DEFAULT 0 , + "xlink_static" numeric(1) NOT NULL DEFAULT '0', "xlink_sig" text NOT NULL DEFAULT '', PRIMARY KEY ("xlink_id") ); @@ -1361,7 +1361,7 @@ create index "xlink_static" on xlink ("xlink_static"); CREATE TABLE "xperm" ( "xp_id" serial NOT NULL, "xp_client" varchar( 20 ) NOT NULL DEFAULT '', - "xp_channel" bigint NOT NULL DEFAULT 0 , + "xp_channel" bigint NOT NULL DEFAULT '0', "xp_perm" varchar( 64 ) NOT NULL DEFAULT '', PRIMARY KEY ("xp_id") ); @@ -1370,7 +1370,7 @@ create index "xp_channel" on xperm ("xp_channel"); create index "xp_perm" on xperm ("xp_perm"); CREATE TABLE "xprof" ( "xprof_hash" text NOT NULL, - "xprof_age" numeric(3) NOT NULL DEFAULT 0 , + "xprof_age" numeric(3) NOT NULL DEFAULT '0', "xprof_desc" text NOT NULL DEFAULT '', "xprof_dob" varchar(12) NOT NULL DEFAULT '', "xprof_gender" text NOT NULL DEFAULT '', @@ -1401,7 +1401,7 @@ CREATE TABLE "xtag" ( "xtag_id" serial NOT NULL, "xtag_hash" text NOT NULL, "xtag_term" text NOT NULL DEFAULT '', - "xtag_flags" bigint NOT NULL DEFAULT 0 , + "xtag_flags" bigint NOT NULL DEFAULT '0', PRIMARY KEY ("xtag_id") ); create index "xtag_term" on xtag ("xtag_term"); diff --git a/library/jqupload/.gitignore b/library/blueimp_upload/.gitignore similarity index 100% rename from library/jqupload/.gitignore rename to library/blueimp_upload/.gitignore diff --git a/library/jqupload/.jshintrc b/library/blueimp_upload/.jshintrc similarity index 100% rename from library/jqupload/.jshintrc rename to library/blueimp_upload/.jshintrc diff --git a/library/blueimp_upload/.npmignore b/library/blueimp_upload/.npmignore new file mode 100644 index 000000000..0530f5dbd --- /dev/null +++ b/library/blueimp_upload/.npmignore @@ -0,0 +1,20 @@ +* +!css/jquery.fileupload-noscript.css +!css/jquery.fileupload-ui-noscript.css +!css/jquery.fileupload-ui.css +!css/jquery.fileupload.css +!img/loading.gif +!img/progressbar.gif +!js/cors/jquery.postmessage-transport.js +!js/cors/jquery.xdr-transport.js +!js/vendor/jquery.ui.widget.js +!js/jquery.fileupload-angular.js +!js/jquery.fileupload-audio.js +!js/jquery.fileupload-image.js +!js/jquery.fileupload-jquery-ui.js +!js/jquery.fileupload-process.js +!js/jquery.fileupload-ui.js +!js/jquery.fileupload-validate.js +!js/jquery.fileupload-video.js +!js/jquery.fileupload.js +!js/jquery.iframe-transport.js diff --git a/library/blueimp_upload/LICENSE b/library/blueimp_upload/LICENSE deleted file mode 100644 index 0ecca3e8c..000000000 --- a/library/blueimp_upload/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 jQuery-File-Upload Authors - -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/library/blueimp_upload/LICENSE.txt b/library/blueimp_upload/LICENSE.txt new file mode 100644 index 000000000..87a644638 --- /dev/null +++ b/library/blueimp_upload/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright © 2010 Sebastian Tschan, https://blueimp.net + +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/library/blueimp_upload/README.md b/library/blueimp_upload/README.md index 56785b847..76bdf89d5 100644 --- a/library/blueimp_upload/README.md +++ b/library/blueimp_upload/README.md @@ -39,7 +39,7 @@ Supports cross-domain, chunked and resumable file uploads and client-side image * **Multiple plugin instances:** Allows to use multiple plugin instances on the same webpage. * **Customizable and extensible:** - Provides an API to set individual options and define callBack methods for various upload events. + Provides an API to set individual options and define callback methods for various upload events. * **Multipart and file contents stream uploads:** Files can be uploaded as standard "multipart/form-data" or file contents stream (HTTP PUT file upload). * **Compatible with any server-side application platform:** @@ -60,7 +60,7 @@ Supports cross-domain, chunked and resumable file uploads and client-side image * [Bootstrap](http://getbootstrap.com/) v. 3.2.0+ * [Glyphicons](http://glyphicons.com/) -The user interface of all versions except the jQuery UI version is built with [Bootstrap](http://getbootstrap.com/) and icons from [Glyphicons](http://glyphicons.com/). +The user interface of all versions, except the jQuery UI version, is built with [Bootstrap](http://getbootstrap.com/) and icons from [Glyphicons](http://glyphicons.com/). ### Cross-domain requirements [Cross-domain File Uploads](https://github.com/blueimp/jQuery-File-Upload/wiki/Cross-domain-uploads) using the [Iframe Transport plugin](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.iframe-transport.js) require a redirect back to the origin server to retrieve the upload results. The [example implementation](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/main.js) makes use of [result.html](https://github.com/blueimp/jQuery-File-Upload/blob/master/cors/result.html) as a static redirect page for the origin server. diff --git a/library/blueimp_upload/angularjs.html b/library/blueimp_upload/angularjs.html index 4858c8600..2051bbf79 100644 --- a/library/blueimp_upload/angularjs.html +++ b/library/blueimp_upload/angularjs.html @@ -22,11 +22,11 @@ - + - + @@ -79,7 +79,7 @@
-
+ @@ -177,18 +177,18 @@
    - - + + - + - + - + - + diff --git a/library/blueimp_upload/basic-plus.html b/library/blueimp_upload/basic-plus.html index 9e5c2321f..acee24843 100644 --- a/library/blueimp_upload/basic-plus.html +++ b/library/blueimp_upload/basic-plus.html @@ -20,7 +20,7 @@ - + @@ -96,15 +96,15 @@ - + - + - + - + diff --git a/library/blueimp_upload/basic.html b/library/blueimp_upload/basic.html index c0df639b4..232a24624 100644 --- a/library/blueimp_upload/basic.html +++ b/library/blueimp_upload/basic.html @@ -20,7 +20,7 @@ - + @@ -96,7 +96,7 @@ - + @@ -104,7 +104,7 @@ - + + - + - + - + - + - + - + diff --git a/library/blueimp_upload/jquery-ui.html b/library/blueimp_upload/jquery-ui.html index 83fe9acd1..842dd4ca7 100644 --- a/library/blueimp_upload/jquery-ui.html +++ b/library/blueimp_upload/jquery-ui.html @@ -22,11 +22,13 @@ - + + + - + - + @@ -95,7 +97,7 @@ Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads.

    - + @@ -199,16 +201,16 @@ {% } %} - - + + - + - + - + - + diff --git a/library/blueimp_upload/js/jquery.fileupload-angular.js b/library/blueimp_upload/js/jquery.fileupload-angular.js index 1c2055276..185907d36 100644 --- a/library/blueimp_upload/js/jquery.fileupload-angular.js +++ b/library/blueimp_upload/js/jquery.fileupload-angular.js @@ -315,6 +315,7 @@ 'fileuploadpaste', 'fileuploaddrop', 'fileuploaddragover', + 'fileuploadchunkbeforesend', 'fileuploadchunksend', 'fileuploadchunkdone', 'fileuploadchunkfail', diff --git a/library/blueimp_upload/js/jquery.fileupload-ui.js b/library/blueimp_upload/js/jquery.fileupload-ui.js index 83e7449e6..5058084b4 100644 --- a/library/blueimp_upload/js/jquery.fileupload-ui.js +++ b/library/blueimp_upload/js/jquery.fileupload-ui.js @@ -30,6 +30,7 @@ require('jquery'), require('blueimp-tmpl'), require('./jquery.fileupload-image'), + require('./jquery.fileupload-audio'), require('./jquery.fileupload-video'), require('./jquery.fileupload-validate') ); diff --git a/library/blueimp_upload/js/jquery.fileupload.js b/library/blueimp_upload/js/jquery.fileupload.js index 5ff151b53..700f9013c 100644 --- a/library/blueimp_upload/js/jquery.fileupload.js +++ b/library/blueimp_upload/js/jquery.fileupload.js @@ -43,7 +43,7 @@ '|(Kindle/(1\\.0|2\\.[05]|3\\.0))' ).test(window.navigator.userAgent) || // Feature detection for all other devices: - $('').prop('disabled')); + $('').prop('disabled')); // The FileReader API is not actually used, but works as feature detection, // as some Safari versions (5?) support XHR file uploads via the FormData API, @@ -261,6 +261,9 @@ // Callback for dragover events of the dropZone(s): // dragover: function (e) {}, // .bind('fileuploaddragover', func); + // Callback before the start of each chunk upload request (before form data initialization): + // chunkbeforesend: function (e, data) {}, // .bind('fileuploadchunkbeforesend', func); + // Callback for the start of each chunk upload request: // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func); @@ -434,6 +437,13 @@ } }, + _deinitProgressListener: function (options) { + var xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr(); + if (xhr.upload) { + $(xhr.upload).unbind('progress'); + } + }, + _isInstanceOf: function (type, obj) { // Cross-frame instanceof check return Object.prototype.toString.call(obj) === '[object ' + type + ']'; @@ -453,7 +463,7 @@ } if (!multipart || options.blob || !this._isInstanceOf('File', file)) { options.headers['Content-Disposition'] = 'attachment; filename="' + - encodeURI(file.name) + '"'; + encodeURI(file.uploadName || file.name) + '"'; } if (!multipart) { options.contentType = file.type || 'application/octet-stream'; @@ -489,7 +499,11 @@ }); } if (options.blob) { - formData.append(paramName, options.blob, file.name); + formData.append( + paramName, + options.blob, + file.uploadName || file.name + ); } else { $.each(options.files, function (index, file) { // This check allows the tests to run with @@ -730,7 +744,7 @@ promise = dfd.promise(), jqXHR, upload; - if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) || + if (!(this._isXHRUpload(options) && slice && (ub || ($.type(mcs) === 'function' ? mcs(options) : mcs) < fs)) || options.data) { return false; } @@ -753,7 +767,7 @@ o.blob = slice.call( file, ub, - ub + mcs, + ub + ($.type(mcs) === 'function' ? mcs(o) : mcs), file.type ); // Store the current chunk size, as the blob itself @@ -762,6 +776,8 @@ // Expose the chunk bytes position range: o.contentRange = 'bytes ' + ub + '-' + (ub + o.chunkSize - 1) + '/' + fs; + // Trigger chunkbeforesend to allow form data to be updated for this chunk + that._trigger('chunkbeforesend', null, o); // Process the upload data (the blob and potential form data): that._initXHRData(o); // Add progress listeners for this chunk upload: @@ -808,6 +824,9 @@ o.context, [jqXHR, textStatus, errorThrown] ); + }) + .always(function () { + that._deinitProgressListener(o); }); }; this._enhancePromise(promise); @@ -909,6 +928,7 @@ }).fail(function (jqXHR, textStatus, errorThrown) { that._onFail(jqXHR, textStatus, errorThrown, options); }).always(function (jqXHRorResult, textStatus, jqXHRorError) { + that._deinitProgressListener(options); that._onAlways( jqXHRorResult, textStatus, @@ -1126,7 +1146,7 @@ dirReader = entry.createReader(); readEntries(); } else { - // Return an empy list for file system items + // Return an empty list for file system items // other than files or directories: dfd.resolve([]); } diff --git a/library/blueimp_upload/js/vendor/jquery.ui.widget.js b/library/blueimp_upload/js/vendor/jquery.ui.widget.js index e08df3fd0..914b8ffb8 100644 --- a/library/blueimp_upload/js/vendor/jquery.ui.widget.js +++ b/library/blueimp_upload/js/vendor/jquery.ui.widget.js @@ -1,571 +1,751 @@ -/*! jQuery UI - v1.11.4+CommonJS - 2015-08-28 -* http://jqueryui.com -* Includes: widget.js -* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */ +/*! jQuery UI - v1.12.1+CommonJS - 2018-02-10 + * http://jqueryui.com + * Includes: widget.js + * Copyright jQuery Foundation and other contributors; Licensed MIT */ (function( factory ) { - if ( typeof define === "function" && define.amd ) { + if ( typeof define === "function" && define.amd ) { - // AMD. Register as an anonymous module. - define([ "jquery" ], factory ); + // AMD. Register as an anonymous module. + define([ "jquery" ], factory ); + } else if ( typeof exports === "object" ) { - } else if ( typeof exports === "object" ) { + // Node/CommonJS + factory( require( "jquery" ) ); + } else { - // Node/CommonJS - factory( require( "jquery" ) ); - - } else { - - // Browser globals - factory( jQuery ); - } + // Browser globals + factory( jQuery ); + } }(function( $ ) { -/*! - * jQuery UI Widget 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/jQuery.widget/ - */ + + $.ui = $.ui || {}; + + var version = $.ui.version = "1.12.1"; -var widget_uuid = 0, - widget_slice = Array.prototype.slice; + /*! + * jQuery UI Widget 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ -$.cleanData = (function( orig ) { - return function( elems ) { - var events, elem, i; - for ( i = 0; (elem = elems[i]) != null; i++ ) { - try { + //>>label: Widget + //>>group: Core + //>>description: Provides a factory for creating stateful widgets with a common API. + //>>docs: http://api.jqueryui.com/jQuery.widget/ + //>>demos: http://jqueryui.com/widget/ - // Only trigger remove when necessary to save time - events = $._data( elem, "events" ); - if ( events && events.remove ) { - $( elem ).triggerHandler( "remove" ); - } - // http://bugs.jquery.com/ticket/8235 - } catch ( e ) {} - } - orig( elems ); - }; -})( $.cleanData ); -$.widget = function( name, base, prototype ) { - var fullName, existingConstructor, constructor, basePrototype, - // proxiedPrototype allows the provided prototype to remain unmodified - // so that it can be used as a mixin for multiple widgets (#8876) - proxiedPrototype = {}, - namespace = name.split( "." )[ 0 ]; + var widgetUuid = 0; + var widgetSlice = Array.prototype.slice; - name = name.split( "." )[ 1 ]; - fullName = namespace + "-" + name; + $.cleanData = ( function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { + try { - if ( !prototype ) { - prototype = base; - base = $.Widget; - } + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } - // create selector for plugin - $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { - return !!$.data( elem, fullName ); - }; + // Http://bugs.jquery.com/ticket/8235 + } catch ( e ) {} + } + orig( elems ); + }; + } )( $.cleanData ); - $[ namespace ] = $[ namespace ] || {}; - existingConstructor = $[ namespace ][ name ]; - constructor = $[ namespace ][ name ] = function( options, element ) { - // allow instantiation without "new" keyword - if ( !this._createWidget ) { - return new constructor( options, element ); - } + $.widget = function( name, base, prototype ) { + var existingConstructor, constructor, basePrototype; - // allow instantiation without initializing for simple inheritance - // must use "new" keyword (the code above always passes args) - if ( arguments.length ) { - this._createWidget( options, element ); - } - }; - // extend with the existing constructor to carry over any static properties - $.extend( constructor, existingConstructor, { - version: prototype.version, - // copy the object used to create the prototype in case we need to - // redefine the widget later - _proto: $.extend( {}, prototype ), - // track widgets that inherit from this widget in case this widget is - // redefined after a widget inherits from it - _childConstructors: [] - }); + // ProxiedPrototype allows the provided prototype to remain unmodified + // so that it can be used as a mixin for multiple widgets (#8876) + var proxiedPrototype = {}; - basePrototype = new base(); - // we need to make the options hash a property directly on the new instance - // otherwise we'll modify the options hash on the prototype that we're - // inheriting from - basePrototype.options = $.widget.extend( {}, basePrototype.options ); - $.each( prototype, function( prop, value ) { - if ( !$.isFunction( value ) ) { - proxiedPrototype[ prop ] = value; - return; - } - proxiedPrototype[ prop ] = (function() { - var _super = function() { - return base.prototype[ prop ].apply( this, arguments ); - }, - _superApply = function( args ) { - return base.prototype[ prop ].apply( this, args ); - }; - return function() { - var __super = this._super, - __superApply = this._superApply, - returnValue; + var namespace = name.split( "." )[ 0 ]; + name = name.split( "." )[ 1 ]; + var fullName = namespace + "-" + name; - this._super = _super; - this._superApply = _superApply; + if ( !prototype ) { + prototype = base; + base = $.Widget; + } - returnValue = value.apply( this, arguments ); + if ( $.isArray( prototype ) ) { + prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); + } - this._super = __super; - this._superApply = __superApply; + // Create selector for plugin + $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { + return !!$.data( elem, fullName ); + }; - return returnValue; - }; - })(); - }); - constructor.prototype = $.widget.extend( basePrototype, { - // TODO: remove support for widgetEventPrefix - // always use the name + a colon as the prefix, e.g., draggable:start - // don't prefix for widgets that aren't DOM-based - widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name - }, proxiedPrototype, { - constructor: constructor, - namespace: namespace, - widgetName: name, - widgetFullName: fullName - }); + $[ namespace ] = $[ namespace ] || {}; + existingConstructor = $[ namespace ][ name ]; + constructor = $[ namespace ][ name ] = function( options, element ) { - // If this widget is being redefined then we need to find all widgets that - // are inheriting from it and redefine all of them so that they inherit from - // the new version of this widget. We're essentially trying to replace one - // level in the prototype chain. - if ( existingConstructor ) { - $.each( existingConstructor._childConstructors, function( i, child ) { - var childPrototype = child.prototype; + // Allow instantiation without "new" keyword + if ( !this._createWidget ) { + return new constructor( options, element ); + } - // redefine the child widget using the same prototype that was - // originally used, but inherit from the new version of the base - $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); - }); - // remove the list of existing child constructors from the old constructor - // so the old child constructors can be garbage collected - delete existingConstructor._childConstructors; - } else { - base._childConstructors.push( constructor ); - } + // Allow instantiation without initializing for simple inheritance + // must use "new" keyword (the code above always passes args) + if ( arguments.length ) { + this._createWidget( options, element ); + } + }; - $.widget.bridge( name, constructor ); + // Extend with the existing constructor to carry over any static properties + $.extend( constructor, existingConstructor, { + version: prototype.version, - return constructor; -}; + // Copy the object used to create the prototype in case we need to + // redefine the widget later + _proto: $.extend( {}, prototype ), -$.widget.extend = function( target ) { - var input = widget_slice.call( arguments, 1 ), - inputIndex = 0, - inputLength = input.length, - key, - value; - for ( ; inputIndex < inputLength; inputIndex++ ) { - for ( key in input[ inputIndex ] ) { - value = input[ inputIndex ][ key ]; - if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { - // Clone objects - if ( $.isPlainObject( value ) ) { - target[ key ] = $.isPlainObject( target[ key ] ) ? - $.widget.extend( {}, target[ key ], value ) : - // Don't extend strings, arrays, etc. with objects - $.widget.extend( {}, value ); - // Copy everything else by reference - } else { - target[ key ] = value; - } - } - } - } - return target; -}; + // Track widgets that inherit from this widget in case this widget is + // redefined after a widget inherits from it + _childConstructors: [] + } ); -$.widget.bridge = function( name, object ) { - var fullName = object.prototype.widgetFullName || name; - $.fn[ name ] = function( options ) { - var isMethodCall = typeof options === "string", - args = widget_slice.call( arguments, 1 ), - returnValue = this; + basePrototype = new base(); - if ( isMethodCall ) { - this.each(function() { - var methodValue, - instance = $.data( this, fullName ); - if ( options === "instance" ) { - returnValue = instance; - return false; - } - if ( !instance ) { - return $.error( "cannot call methods on " + name + " prior to initialization; " + - "attempted to call method '" + options + "'" ); - } - if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { - return $.error( "no such method '" + options + "' for " + name + " widget instance" ); - } - methodValue = instance[ options ].apply( instance, args ); - if ( methodValue !== instance && methodValue !== undefined ) { - returnValue = methodValue && methodValue.jquery ? - returnValue.pushStack( methodValue.get() ) : - methodValue; - return false; - } - }); - } else { + // We need to make the options hash a property directly on the new instance + // otherwise we'll modify the options hash on the prototype that we're + // inheriting from + basePrototype.options = $.widget.extend( {}, basePrototype.options ); + $.each( prototype, function( prop, value ) { + if ( !$.isFunction( value ) ) { + proxiedPrototype[ prop ] = value; + return; + } + proxiedPrototype[ prop ] = ( function() { + function _super() { + return base.prototype[ prop ].apply( this, arguments ); + } - // Allow multiple hashes to be passed on init - if ( args.length ) { - options = $.widget.extend.apply( null, [ options ].concat(args) ); - } + function _superApply( args ) { + return base.prototype[ prop ].apply( this, args ); + } - this.each(function() { - var instance = $.data( this, fullName ); - if ( instance ) { - instance.option( options || {} ); - if ( instance._init ) { - instance._init(); - } - } else { - $.data( this, fullName, new object( options, this ) ); - } - }); - } + return function() { + var __super = this._super; + var __superApply = this._superApply; + var returnValue; - return returnValue; - }; -}; + this._super = _super; + this._superApply = _superApply; -$.Widget = function( /* options, element */ ) {}; -$.Widget._childConstructors = []; + returnValue = value.apply( this, arguments ); -$.Widget.prototype = { - widgetName: "widget", - widgetEventPrefix: "", - defaultElement: "
    ", - options: { - disabled: false, + this._super = __super; + this._superApply = __superApply; - // callbacks - create: null - }, - _createWidget: function( options, element ) { - element = $( element || this.defaultElement || this )[ 0 ]; - this.element = $( element ); - this.uuid = widget_uuid++; - this.eventNamespace = "." + this.widgetName + this.uuid; + return returnValue; + }; + } )(); + } ); + constructor.prototype = $.widget.extend( basePrototype, { - this.bindings = $(); - this.hoverable = $(); - this.focusable = $(); + // TODO: remove support for widgetEventPrefix + // always use the name + a colon as the prefix, e.g., draggable:start + // don't prefix for widgets that aren't DOM-based + widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name + }, proxiedPrototype, { + constructor: constructor, + namespace: namespace, + widgetName: name, + widgetFullName: fullName + } ); - if ( element !== this ) { - $.data( element, this.widgetFullName, this ); - this._on( true, this.element, { - remove: function( event ) { - if ( event.target === element ) { - this.destroy(); - } - } - }); - this.document = $( element.style ? - // element within the document - element.ownerDocument : - // element is window or document - element.document || element ); - this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); - } + // If this widget is being redefined then we need to find all widgets that + // are inheriting from it and redefine all of them so that they inherit from + // the new version of this widget. We're essentially trying to replace one + // level in the prototype chain. + if ( existingConstructor ) { + $.each( existingConstructor._childConstructors, function( i, child ) { + var childPrototype = child.prototype; - this.options = $.widget.extend( {}, - this.options, - this._getCreateOptions(), - options ); + // Redefine the child widget using the same prototype that was + // originally used, but inherit from the new version of the base + $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, + child._proto ); + } ); - this._create(); - this._trigger( "create", null, this._getCreateEventData() ); - this._init(); - }, - _getCreateOptions: $.noop, - _getCreateEventData: $.noop, - _create: $.noop, - _init: $.noop, + // Remove the list of existing child constructors from the old constructor + // so the old child constructors can be garbage collected + delete existingConstructor._childConstructors; + } else { + base._childConstructors.push( constructor ); + } - destroy: function() { - this._destroy(); - // we can probably remove the unbind calls in 2.0 - // all event bindings should go through this._on() - this.element - .unbind( this.eventNamespace ) - .removeData( this.widgetFullName ) - // support: jquery <1.6.3 - // http://bugs.jquery.com/ticket/9413 - .removeData( $.camelCase( this.widgetFullName ) ); - this.widget() - .unbind( this.eventNamespace ) - .removeAttr( "aria-disabled" ) - .removeClass( - this.widgetFullName + "-disabled " + - "ui-state-disabled" ); + $.widget.bridge( name, constructor ); - // clean up events and states - this.bindings.unbind( this.eventNamespace ); - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); - }, - _destroy: $.noop, + return constructor; + }; - widget: function() { - return this.element; - }, + $.widget.extend = function( target ) { + var input = widgetSlice.call( arguments, 1 ); + var inputIndex = 0; + var inputLength = input.length; + var key; + var value; - option: function( key, value ) { - var options = key, - parts, - curOption, - i; + for ( ; inputIndex < inputLength; inputIndex++ ) { + for ( key in input[ inputIndex ] ) { + value = input[ inputIndex ][ key ]; + if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { - if ( arguments.length === 0 ) { - // don't return a reference to the internal hash - return $.widget.extend( {}, this.options ); - } + // Clone objects + if ( $.isPlainObject( value ) ) { + target[ key ] = $.isPlainObject( target[ key ] ) ? + $.widget.extend( {}, target[ key ], value ) : - if ( typeof key === "string" ) { - // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } - options = {}; - parts = key.split( "." ); - key = parts.shift(); - if ( parts.length ) { - curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); - for ( i = 0; i < parts.length - 1; i++ ) { - curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; - curOption = curOption[ parts[ i ] ]; - } - key = parts.pop(); - if ( arguments.length === 1 ) { - return curOption[ key ] === undefined ? null : curOption[ key ]; - } - curOption[ key ] = value; - } else { - if ( arguments.length === 1 ) { - return this.options[ key ] === undefined ? null : this.options[ key ]; - } - options[ key ] = value; - } - } + // Don't extend strings, arrays, etc. with objects + $.widget.extend( {}, value ); - this._setOptions( options ); + // Copy everything else by reference + } else { + target[ key ] = value; + } + } + } + } + return target; + }; - return this; - }, - _setOptions: function( options ) { - var key; + $.widget.bridge = function( name, object ) { + var fullName = object.prototype.widgetFullName || name; + $.fn[ name ] = function( options ) { + var isMethodCall = typeof options === "string"; + var args = widgetSlice.call( arguments, 1 ); + var returnValue = this; - for ( key in options ) { - this._setOption( key, options[ key ] ); - } + if ( isMethodCall ) { - return this; - }, - _setOption: function( key, value ) { - this.options[ key ] = value; + // If this is an empty collection, we need to have the instance method + // return undefined instead of the jQuery instance + if ( !this.length && options === "instance" ) { + returnValue = undefined; + } else { + this.each( function() { + var methodValue; + var instance = $.data( this, fullName ); - if ( key === "disabled" ) { - this.widget() - .toggleClass( this.widgetFullName + "-disabled", !!value ); + if ( options === "instance" ) { + returnValue = instance; + return false; + } - // If the widget is becoming disabled, then nothing is interactive - if ( value ) { - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); - } - } + if ( !instance ) { + return $.error( "cannot call methods on " + name + + " prior to initialization; " + + "attempted to call method '" + options + "'" ); + } - return this; - }, + if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) { + return $.error( "no such method '" + options + "' for " + name + + " widget instance" ); + } - enable: function() { - return this._setOptions({ disabled: false }); - }, - disable: function() { - return this._setOptions({ disabled: true }); - }, + methodValue = instance[ options ].apply( instance, args ); - _on: function( suppressDisabledCheck, element, handlers ) { - var delegateElement, - instance = this; + if ( methodValue !== instance && methodValue !== undefined ) { + returnValue = methodValue && methodValue.jquery ? + returnValue.pushStack( methodValue.get() ) : + methodValue; + return false; + } + } ); + } + } else { - // no suppressDisabledCheck flag, shuffle arguments - if ( typeof suppressDisabledCheck !== "boolean" ) { - handlers = element; - element = suppressDisabledCheck; - suppressDisabledCheck = false; - } + // Allow multiple hashes to be passed on init + if ( args.length ) { + options = $.widget.extend.apply( null, [ options ].concat( args ) ); + } - // no element argument, shuffle and use this.element - if ( !handlers ) { - handlers = element; - element = this.element; - delegateElement = this.widget(); - } else { - element = delegateElement = $( element ); - this.bindings = this.bindings.add( element ); - } + this.each( function() { + var instance = $.data( this, fullName ); + if ( instance ) { + instance.option( options || {} ); + if ( instance._init ) { + instance._init(); + } + } else { + $.data( this, fullName, new object( options, this ) ); + } + } ); + } - $.each( handlers, function( event, handler ) { - function handlerProxy() { - // allow widgets to customize the disabled handling - // - disabled as an array instead of boolean - // - disabled class as method for disabling individual parts - if ( !suppressDisabledCheck && - ( instance.options.disabled === true || - $( this ).hasClass( "ui-state-disabled" ) ) ) { - return; - } - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } + return returnValue; + }; + }; - // copy the guid so direct unbinding works - if ( typeof handler !== "string" ) { - handlerProxy.guid = handler.guid = - handler.guid || handlerProxy.guid || $.guid++; - } + $.Widget = function( /* options, element */ ) {}; + $.Widget._childConstructors = []; - var match = event.match( /^([\w:-]*)\s*(.*)$/ ), - eventName = match[1] + instance.eventNamespace, - selector = match[2]; - if ( selector ) { - delegateElement.delegate( selector, eventName, handlerProxy ); - } else { - element.bind( eventName, handlerProxy ); - } - }); - }, + $.Widget.prototype = { + widgetName: "widget", + widgetEventPrefix: "", + defaultElement: "
    ", - _off: function( element, eventName ) { - eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + - this.eventNamespace; - element.unbind( eventName ).undelegate( eventName ); + options: { + classes: {}, + disabled: false, - // Clear the stack to avoid memory leaks (#10056) - this.bindings = $( this.bindings.not( element ).get() ); - this.focusable = $( this.focusable.not( element ).get() ); - this.hoverable = $( this.hoverable.not( element ).get() ); - }, + // Callbacks + create: null + }, - _delay: function( handler, delay ) { - function handlerProxy() { - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } - var instance = this; - return setTimeout( handlerProxy, delay || 0 ); - }, + _createWidget: function( options, element ) { + element = $( element || this.defaultElement || this )[ 0 ]; + this.element = $( element ); + this.uuid = widgetUuid++; + this.eventNamespace = "." + this.widgetName + this.uuid; - _hoverable: function( element ) { - this.hoverable = this.hoverable.add( element ); - this._on( element, { - mouseenter: function( event ) { - $( event.currentTarget ).addClass( "ui-state-hover" ); - }, - mouseleave: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-hover" ); - } - }); - }, + this.bindings = $(); + this.hoverable = $(); + this.focusable = $(); + this.classesElementLookup = {}; - _focusable: function( element ) { - this.focusable = this.focusable.add( element ); - this._on( element, { - focusin: function( event ) { - $( event.currentTarget ).addClass( "ui-state-focus" ); - }, - focusout: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-focus" ); - } - }); - }, + if ( element !== this ) { + $.data( element, this.widgetFullName, this ); + this._on( true, this.element, { + remove: function( event ) { + if ( event.target === element ) { + this.destroy(); + } + } + } ); + this.document = $( element.style ? - _trigger: function( type, event, data ) { - var prop, orig, - callback = this.options[ type ]; + // Element within the document + element.ownerDocument : - data = data || {}; - event = $.Event( event ); - event.type = ( type === this.widgetEventPrefix ? - type : - this.widgetEventPrefix + type ).toLowerCase(); - // the original event may come from any element - // so we need to reset the target on the new event - event.target = this.element[ 0 ]; + // Element is window or document + element.document || element ); + this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); + } - // copy original event properties over to the new event - orig = event.originalEvent; - if ( orig ) { - for ( prop in orig ) { - if ( !( prop in event ) ) { - event[ prop ] = orig[ prop ]; - } - } - } + this.options = $.widget.extend( {}, + this.options, + this._getCreateOptions(), + options ); - this.element.trigger( event, data ); - return !( $.isFunction( callback ) && - callback.apply( this.element[0], [ event ].concat( data ) ) === false || - event.isDefaultPrevented() ); - } -}; + this._create(); -$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { - $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { - if ( typeof options === "string" ) { - options = { effect: options }; - } - var hasOptions, - effectName = !options ? - method : - options === true || typeof options === "number" ? - defaultEffect : - options.effect || defaultEffect; - options = options || {}; - if ( typeof options === "number" ) { - options = { duration: options }; - } - hasOptions = !$.isEmptyObject( options ); - options.complete = callback; - if ( options.delay ) { - element.delay( options.delay ); - } - if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { - element[ method ]( options ); - } else if ( effectName !== method && element[ effectName ] ) { - element[ effectName ]( options.duration, options.easing, callback ); - } else { - element.queue(function( next ) { - $( this )[ method ](); - if ( callback ) { - callback.call( element[ 0 ] ); - } - next(); - }); - } - }; -}); + if ( this.options.disabled ) { + this._setOptionDisabled( this.options.disabled ); + } + + this._trigger( "create", null, this._getCreateEventData() ); + this._init(); + }, + + _getCreateOptions: function() { + return {}; + }, + + _getCreateEventData: $.noop, + + _create: $.noop, + + _init: $.noop, + + destroy: function() { + var that = this; + + this._destroy(); + $.each( this.classesElementLookup, function( key, value ) { + that._removeClass( value, key ); + } ); + + // We can probably remove the unbind calls in 2.0 + // all event bindings should go through this._on() + this.element + .off( this.eventNamespace ) + .removeData( this.widgetFullName ); + this.widget() + .off( this.eventNamespace ) + .removeAttr( "aria-disabled" ); + + // Clean up events and states + this.bindings.off( this.eventNamespace ); + }, + + _destroy: $.noop, + + widget: function() { + return this.element; + }, + + option: function( key, value ) { + var options = key; + var parts; + var curOption; + var i; + + if ( arguments.length === 0 ) { + + // Don't return a reference to the internal hash + return $.widget.extend( {}, this.options ); + } + + if ( typeof key === "string" ) { + + // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } + options = {}; + parts = key.split( "." ); + key = parts.shift(); + if ( parts.length ) { + curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); + for ( i = 0; i < parts.length - 1; i++ ) { + curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; + curOption = curOption[ parts[ i ] ]; + } + key = parts.pop(); + if ( arguments.length === 1 ) { + return curOption[ key ] === undefined ? null : curOption[ key ]; + } + curOption[ key ] = value; + } else { + if ( arguments.length === 1 ) { + return this.options[ key ] === undefined ? null : this.options[ key ]; + } + options[ key ] = value; + } + } + + this._setOptions( options ); + + return this; + }, + + _setOptions: function( options ) { + var key; + + for ( key in options ) { + this._setOption( key, options[ key ] ); + } + + return this; + }, + + _setOption: function( key, value ) { + if ( key === "classes" ) { + this._setOptionClasses( value ); + } + + this.options[ key ] = value; + + if ( key === "disabled" ) { + this._setOptionDisabled( value ); + } + + return this; + }, + + _setOptionClasses: function( value ) { + var classKey, elements, currentElements; + + for ( classKey in value ) { + currentElements = this.classesElementLookup[ classKey ]; + if ( value[ classKey ] === this.options.classes[ classKey ] || + !currentElements || + !currentElements.length ) { + continue; + } + + // We are doing this to create a new jQuery object because the _removeClass() call + // on the next line is going to destroy the reference to the current elements being + // tracked. We need to save a copy of this collection so that we can add the new classes + // below. + elements = $( currentElements.get() ); + this._removeClass( currentElements, classKey ); + + // We don't use _addClass() here, because that uses this.options.classes + // for generating the string of classes. We want to use the value passed in from + // _setOption(), this is the new value of the classes option which was passed to + // _setOption(). We pass this value directly to _classes(). + elements.addClass( this._classes( { + element: elements, + keys: classKey, + classes: value, + add: true + } ) ); + } + }, + + _setOptionDisabled: function( value ) { + this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); + + // If the widget is becoming disabled, then nothing is interactive + if ( value ) { + this._removeClass( this.hoverable, null, "ui-state-hover" ); + this._removeClass( this.focusable, null, "ui-state-focus" ); + } + }, + + enable: function() { + return this._setOptions( { disabled: false } ); + }, + + disable: function() { + return this._setOptions( { disabled: true } ); + }, + + _classes: function( options ) { + var full = []; + var that = this; + + options = $.extend( { + element: this.element, + classes: this.options.classes || {} + }, options ); + + function processClassString( classes, checkOption ) { + var current, i; + for ( i = 0; i < classes.length; i++ ) { + current = that.classesElementLookup[ classes[ i ] ] || $(); + if ( options.add ) { + current = $( $.unique( current.get().concat( options.element.get() ) ) ); + } else { + current = $( current.not( options.element ).get() ); + } + that.classesElementLookup[ classes[ i ] ] = current; + full.push( classes[ i ] ); + if ( checkOption && options.classes[ classes[ i ] ] ) { + full.push( options.classes[ classes[ i ] ] ); + } + } + } + + this._on( options.element, { + "remove": "_untrackClassesElement" + } ); + + if ( options.keys ) { + processClassString( options.keys.match( /\S+/g ) || [], true ); + } + if ( options.extra ) { + processClassString( options.extra.match( /\S+/g ) || [] ); + } + + return full.join( " " ); + }, + + _untrackClassesElement: function( event ) { + var that = this; + $.each( that.classesElementLookup, function( key, value ) { + if ( $.inArray( event.target, value ) !== -1 ) { + that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); + } + } ); + }, + + _removeClass: function( element, keys, extra ) { + return this._toggleClass( element, keys, extra, false ); + }, + + _addClass: function( element, keys, extra ) { + return this._toggleClass( element, keys, extra, true ); + }, + + _toggleClass: function( element, keys, extra, add ) { + add = ( typeof add === "boolean" ) ? add : extra; + var shift = ( typeof element === "string" || element === null ), + options = { + extra: shift ? keys : extra, + keys: shift ? element : keys, + element: shift ? this.element : element, + add: add + }; + options.element.toggleClass( this._classes( options ), add ); + return this; + }, + + _on: function( suppressDisabledCheck, element, handlers ) { + var delegateElement; + var instance = this; + + // No suppressDisabledCheck flag, shuffle arguments + if ( typeof suppressDisabledCheck !== "boolean" ) { + handlers = element; + element = suppressDisabledCheck; + suppressDisabledCheck = false; + } + + // No element argument, shuffle and use this.element + if ( !handlers ) { + handlers = element; + element = this.element; + delegateElement = this.widget(); + } else { + element = delegateElement = $( element ); + this.bindings = this.bindings.add( element ); + } + + $.each( handlers, function( event, handler ) { + function handlerProxy() { + + // Allow widgets to customize the disabled handling + // - disabled as an array instead of boolean + // - disabled class as method for disabling individual parts + if ( !suppressDisabledCheck && + ( instance.options.disabled === true || + $( this ).hasClass( "ui-state-disabled" ) ) ) { + return; + } + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + + // Copy the guid so direct unbinding works + if ( typeof handler !== "string" ) { + handlerProxy.guid = handler.guid = + handler.guid || handlerProxy.guid || $.guid++; + } + + var match = event.match( /^([\w:-]*)\s*(.*)$/ ); + var eventName = match[ 1 ] + instance.eventNamespace; + var selector = match[ 2 ]; + + if ( selector ) { + delegateElement.on( eventName, selector, handlerProxy ); + } else { + element.on( eventName, handlerProxy ); + } + } ); + }, + + _off: function( element, eventName ) { + eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + + this.eventNamespace; + element.off( eventName ).off( eventName ); + + // Clear the stack to avoid memory leaks (#10056) + this.bindings = $( this.bindings.not( element ).get() ); + this.focusable = $( this.focusable.not( element ).get() ); + this.hoverable = $( this.hoverable.not( element ).get() ); + }, + + _delay: function( handler, delay ) { + function handlerProxy() { + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + var instance = this; + return setTimeout( handlerProxy, delay || 0 ); + }, + + _hoverable: function( element ) { + this.hoverable = this.hoverable.add( element ); + this._on( element, { + mouseenter: function( event ) { + this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); + }, + mouseleave: function( event ) { + this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); + } + } ); + }, + + _focusable: function( element ) { + this.focusable = this.focusable.add( element ); + this._on( element, { + focusin: function( event ) { + this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); + }, + focusout: function( event ) { + this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); + } + } ); + }, + + _trigger: function( type, event, data ) { + var prop, orig; + var callback = this.options[ type ]; + + data = data || {}; + event = $.Event( event ); + event.type = ( type === this.widgetEventPrefix ? + type : + this.widgetEventPrefix + type ).toLowerCase(); + + // The original event may come from any element + // so we need to reset the target on the new event + event.target = this.element[ 0 ]; + + // Copy original event properties over to the new event + orig = event.originalEvent; + if ( orig ) { + for ( prop in orig ) { + if ( !( prop in event ) ) { + event[ prop ] = orig[ prop ]; + } + } + } + + this.element.trigger( event, data ); + return !( $.isFunction( callback ) && + callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || + event.isDefaultPrevented() ); + } + }; + + $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { + $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { + if ( typeof options === "string" ) { + options = { effect: options }; + } + + var hasOptions; + var effectName = !options ? + method : + options === true || typeof options === "number" ? + defaultEffect : + options.effect || defaultEffect; + + options = options || {}; + if ( typeof options === "number" ) { + options = { duration: options }; + } + + hasOptions = !$.isEmptyObject( options ); + options.complete = callback; + + if ( options.delay ) { + element.delay( options.delay ); + } + + if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { + element[ method ]( options ); + } else if ( effectName !== method && element[ effectName ] ) { + element[ effectName ]( options.duration, options.easing, callback ); + } else { + element.queue( function( next ) { + $( this )[ method ](); + if ( callback ) { + callback.call( element[ 0 ] ); + } + next(); + } ); + } + }; + } ); + + var widget = $.widget; -var widget = $.widget; diff --git a/library/blueimp_upload/package.json b/library/blueimp_upload/package.json index ed4d33681..4801d7913 100644 --- a/library/blueimp_upload/package.json +++ b/library/blueimp_upload/package.json @@ -1,6 +1,6 @@ { "name": "blueimp-file-upload", - "version": "9.18.0", + "version": "9.23.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/library/blueimp_upload/server/php/Dockerfile b/library/blueimp_upload/server/php/Dockerfile index ca88d3d0d..8633fee74 100644 --- a/library/blueimp_upload/server/php/Dockerfile +++ b/library/blueimp_upload/server/php/Dockerfile @@ -1,4 +1,4 @@ -FROM php:7.0-apache +FROM php:7-apache # Enable the Apache Headers module: RUN ln -s /etc/apache2/mods-available/headers.load \ diff --git a/library/blueimp_upload/server/php/UploadHandler.php b/library/blueimp_upload/server/php/UploadHandler.php index 1380d4739..285d046aa 100755 --- a/library/blueimp_upload/server/php/UploadHandler.php +++ b/library/blueimp_upload/server/php/UploadHandler.php @@ -131,18 +131,22 @@ class UploadHandler // Command or path for to the ImageMagick identify binary: 'identify_bin' => 'identify', 'image_versions' => array( - // The empty image version key defines options for the original image: + // The empty image version key defines options for the original image. + // Keep in mind: these image manipulations are inherited by all other image versions from this point onwards. + // Also note that the property 'no_cache' is not inherited, since it's not a manipulation. '' => array( // Automatically rotate images based on EXIF meta data: 'auto_orient' => true ), - // Uncomment the following to create medium sized images: + // You can add arrays to generate different versions. + // The name of the key is the name of the version (example: 'medium'). + // the array contains the options to apply. /* 'medium' => array( 'max_width' => 800, 'max_height' => 600 ), - */ + */ 'thumbnail' => array( // Uncomment the following to use a defined directory for the thumbnails // instead of a subdirectory based on the version identifier. @@ -153,9 +157,13 @@ class UploadHandler //'upload_url' => $this->get_full_url().'/thumb/', // Uncomment the following to force the max // dimensions and e.g. create square thumbnails: - //'crop' => true, - 'max_width' => 80, - 'max_height' => 80 + // 'auto_orient' => true, + // 'crop' => true, + // 'jpeg_quality' => 70, + // 'no_cache' => true, (there's a caching option, but this remembers thumbnail sizes from a previous action!) + // 'strip' => true, (this strips EXIF tags, such as geolocation) + 'max_width' => 80, // either specify width, or set to 0. Then width is automatically adjusted - keeping aspect ratio to a specified max_height. + 'max_height' => 80 // either specify height, or set to 0. Then height is automatically adjusted - keeping aspect ratio to a specified max_width. ) ), 'print_response' => true @@ -862,22 +870,32 @@ class UploadHandler $image_oriented = false; if (!empty($options['auto_orient'])) { $image_oriented = $this->imagick_orient_image($image); - } + } + + $image_resize = false; $new_width = $max_width = $img_width = $image->getImageWidth(); - $new_height = $max_height = $img_height = $image->getImageHeight(); - if (!empty($options['max_width'])) { - $new_width = $max_width = $options['max_width']; + $new_height = $max_height = $img_height = $image->getImageHeight(); + + // use isset(). User might be setting max_width = 0 (auto in regular resizing). Value 0 would be considered empty when you use empty() + if (isset($options['max_width'])) { + $image_resize = true; + $new_width = $max_width = $options['max_width']; } - if (!empty($options['max_height'])) { + if (isset($options['max_height'])) { + $image_resize = true; $new_height = $max_height = $options['max_height']; } - if (!($image_oriented || $max_width < $img_width || $max_height < $img_height)) { + + $image_strip = (isset($options['strip']) ? $options['strip'] : false); + + if ( !$image_oriented && ($max_width >= $img_width) && ($max_height >= $img_height) && !$image_strip && empty($options["jpeg_quality"]) ) { if ($file_path !== $new_file_path) { return copy($file_path, $new_file_path); } return true; } - $crop = !empty($options['crop']); + $crop = (isset($options['crop']) ? $options['crop'] : false); + if ($crop) { $x = 0; $y = 0; @@ -917,7 +935,7 @@ class UploadHandler } break; } - if (!empty($options['strip'])) { + if ( $image_strip ) { $image->stripImage(); } return $success && $image->writeImage($new_file_path); diff --git a/library/blueimp_upload/server/php/docker-compose.yml b/library/blueimp_upload/server/php/docker-compose.yml index 691ea9caa..74eabf7dc 100644 --- a/library/blueimp_upload/server/php/docker-compose.yml +++ b/library/blueimp_upload/server/php/docker-compose.yml @@ -1,6 +1,9 @@ -apache: - build: ./ - ports: - - "80:80" - volumes: - - "../../:/var/www/html" +version: '2.3' +services: + apache: + build: ./ + network_mode: bridge + ports: + - "80:80" + volumes: + - "../../:/var/www/html" diff --git a/library/blueimp_upload/test/index.html b/library/blueimp_upload/test/index.html index 4a9a6f328..0b5cf57b7 100644 --- a/library/blueimp_upload/test/index.html +++ b/library/blueimp_upload/test/index.html @@ -20,7 +20,7 @@ jQuery File Upload Plugin Test - +

    jQuery File Upload Plugin Test

    @@ -145,11 +145,11 @@ {% } %} - + - - - + + + - + diff --git a/library/jqupload/CONTRIBUTING.md b/library/jqupload/CONTRIBUTING.md deleted file mode 100644 index 2326ad031..000000000 --- a/library/jqupload/CONTRIBUTING.md +++ /dev/null @@ -1,42 +0,0 @@ -# Issue Guidelines - -The issues tracker should only be used for **bugs** or **feature requests**. - -Please post **support requests** and **general discussions** about this project to the [support forum](https://groups.google.com/d/forum/jquery-fileupload). - -## Bugs - -Please follow these guidelines before reporting a bug: - -1. **Update to the latest version** — Check if you can reproduce the issue with the latest version from the `master` branch. - -2. **Use the GitHub issue search** — check if the issue has already been reported. If it has been, please comment on the existing issue. - -3. **Isolate the demonstrable problem** — Try to reproduce the problem with the [Demo](http://blueimp.github.io/jQuery-File-Upload/) or with a reduced test case that includes the least amount of code necessary to reproduce the problem. - -4. **Provide a means to reproduce the problem** — Please provide as much details as possible, e.g. server information, browser and operating system versions, steps to reproduce the problem. If possible, provide a link to your reduced test case, e.g. via [JSFiddle](http://jsfiddle.net/). - - -## Feature requests - -Please follow the bug guidelines above for feature requests, i.e. update to the latest version and search for exising issues before posting a new request. - -Generally, feature requests might be accepted if the implementation would benefit a broader use case or the project could be considered incomplete without that feature. - -If you need help integrating this project into another framework, please post your request to the [support forum](https://groups.google.com/d/forum/jquery-fileupload). - -## Pull requests - -[Pull requests](https://help.github.com/articles/using-pull-requests) are welcome and the preferred way of accepting code contributions. - -However, if you add a server-side upload handler implementation for another framework, please continue to maintain this version in your own fork without sending a pull request. You are welcome to add a link and possibly documentation about your implementation to the [Wiki](https://github.com/blueimp/jQuery-File-Upload/wiki). - -Please follow these guidelines before sending a pull request: - -1. Update your fork to the latest upstream version. - -2. Follow the coding conventions of the original repository. Changes to one of the JavaScript source files are required to pass the [JSLint](http://jslint.com/) validation tool. - -3. Keep your commits as atomar as possible, i.e. create a new commit for every single bug fix or feature added. - -4. Always add meaningfull commit messages. diff --git a/library/jqupload/Gruntfile.js b/library/jqupload/Gruntfile.js deleted file mode 100644 index dcdb5d57a..000000000 --- a/library/jqupload/Gruntfile.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * jQuery File Upload Gruntfile - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2013, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -/*global module */ - -module.exports = function (grunt) { - 'use strict'; - - grunt.initConfig({ - jshint: { - options: { - jshintrc: '.jshintrc' - }, - all: [ - 'Gruntfile.js', - 'js/cors/*.js', - 'js/*.js', - 'server/node/server.js', - 'test/test.js' - ] - } - }); - - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-bump-build-git'); - grunt.registerTask('test', ['jshint']); - grunt.registerTask('default', ['test']); - -}; diff --git a/library/jqupload/README.md b/library/jqupload/README.md deleted file mode 100644 index 726e6b342..000000000 --- a/library/jqupload/README.md +++ /dev/null @@ -1,123 +0,0 @@ -# jQuery File Upload Plugin - -## Demo -[Demo File Upload](http://blueimp.github.io/jQuery-File-Upload/) - -## Description -File Upload widget with multiple file selection, drag&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. - -## Setup -* [How to setup the plugin on your website](https://github.com/blueimp/jQuery-File-Upload/wiki/Setup) -* [How to use only the basic plugin (minimal setup guide).](https://github.com/blueimp/jQuery-File-Upload/wiki/Basic-plugin) - -## Support - -* **[Support Forum](https://groups.google.com/d/forum/jquery-fileupload)** -**Support requests** and **general discussions** about the File Upload plugin can be posted to the official -[Support Forum](https://groups.google.com/d/forum/jquery-fileupload). -If your question is not directly related to the File Upload plugin, you might have a better chance to get a reply by posting to [Stack Overflow](http://stackoverflow.com/questions/tagged/blueimp+jquery+file-upload). - -* Bugs and Feature requests -**Bugs** and **Feature requests** can be reported using the [issues tracker](https://github.com/blueimp/jQuery-File-Upload/issues). -Please read the [issue guidelines](https://github.com/blueimp/jQuery-File-Upload/blob/master/CONTRIBUTING.md) before posting. - -## Features -* **Multiple file upload:** - Allows to select multiple files at once and upload them simultaneously. -* **Drag & Drop support:** - Allows to upload files by dragging them from your desktop or filemanager and dropping them on your browser window. -* **Upload progress bar:** - Shows a progress bar indicating the upload progress for individual files and for all uploads combined. -* **Cancelable uploads:** - Individual file uploads can be canceled to stop the upload progress. -* **Resumable uploads:** - Aborted uploads can be resumed with browsers supporting the Blob API. -* **Chunked uploads:** - Large files can be uploaded in smaller chunks with browsers supporting the Blob API. -* **Client-side image resizing:** - Images can be automatically resized on client-side with browsers supporting the required JS APIs. -* **Preview images, audio and video:** - A preview of image, audio and video files can be displayed before uploading with browsers supporting the required APIs. -* **No browser plugins (e.g. Adobe Flash) required:** - The implementation is based on open standards like HTML5 and JavaScript and requires no additional browser plugins. -* **Graceful fallback for legacy browsers:** - Uploads files via XMLHttpRequests if supported and uses iframes as fallback for legacy browsers. -* **HTML file upload form fallback:** - Allows progressive enhancement by using a standard HTML file upload form as widget element. -* **Cross-site file uploads:** - Supports uploading files to a different domain with cross-site XMLHttpRequests or iframe redirects. -* **Multiple plugin instances:** - Allows to use multiple plugin instances on the same webpage. -* **Customizable and extensible:** - Provides an API to set individual options and define callBack methods for various upload events. -* **Multipart and file contents stream uploads:** - Files can be uploaded as standard "multipart/form-data" or file contents stream (HTTP PUT file upload). -* **Compatible with any server-side application platform:** - Works with any server-side platform (PHP, Python, Ruby on Rails, Java, Node.js, Go etc.) that supports standard HTML form file uploads. - -## Requirements - -### Mandatory requirements -* [jQuery](http://jquery.com/) v. 1.6+ -* [jQuery UI widget factory](http://api.jqueryui.com/jQuery.widget/) v. 1.9+ (included) -* [jQuery Iframe Transport plugin](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.iframe-transport.js) (included) - -The jQuery UI widget factory is a requirement for the basic File Upload plugin, but very lightweight without any other dependencies from the jQuery UI suite. - -The jQuery Iframe Transport is required for [browsers without XHR file upload support](https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support). - -### Optional requirements -* [JavaScript Templates engine](https://github.com/blueimp/JavaScript-Templates) v. 2.5.3+ -* [JavaScript Load Image library](https://github.com/blueimp/JavaScript-Load-Image) v. 1.11.0+ -* [JavaScript Canvas to Blob polyfill](https://github.com/blueimp/JavaScript-Canvas-to-Blob) v. 2.1.0+ -* [blueimp Gallery](https://github.com/blueimp/Gallery) v. 2.12.0+ -* [Bootstrap CSS framework](http://getbootstrap.com/) v. 3.0.0+ -* [Glyphicons](http://glyphicons.com/) - -The JavaScript Templates engine is used to render the selected and uploaded files for the Basic Plus UI and jQuery UI versions. - -The JavaScript Load Image library and JavaScript Canvas to Blob polyfill are required for the image previews and resizing functionality. - -The blueimp Gallery is used to display the uploaded images in a lightbox. - -The user interface of all versions except the jQuery UI version is built with Twitter's [Bootstrap](http://getbootstrap.com/) framework and icons from [Glyphicons](http://glyphicons.com/). - -### Cross-domain requirements -[Cross-domain File Uploads](https://github.com/blueimp/jQuery-File-Upload/wiki/Cross-domain-uploads) using the [Iframe Transport plugin](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.iframe-transport.js) require a redirect back to the origin server to retrieve the upload results. The [example implementation](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/main.js) makes use of [result.html](https://github.com/blueimp/jQuery-File-Upload/blob/master/cors/result.html) as a static redirect page for the origin server. - -The repository also includes the [jQuery XDomainRequest Transport plugin](https://github.com/blueimp/jQuery-File-Upload/blob/master/js/cors/jquery.xdr-transport.js), which enables limited cross-domain AJAX requests in Microsoft Internet Explorer 8 and 9 (IE 10 supports cross-domain XHR requests). -The XDomainRequest object allows GET and POST requests only and doesn't support file uploads. It is used on the [Demo](http://blueimp.github.io/jQuery-File-Upload/) to delete uploaded files from the cross-domain demo file upload service. - -## Browsers - -### Desktop browsers -The File Upload plugin is regularly tested with the latest browser versions and supports the following minimal versions: - -* Google Chrome -* Apple Safari 4.0+ -* Mozilla Firefox 3.0+ -* Opera 11.0+ -* Microsoft Internet Explorer 6.0+ - -### Mobile browsers -The File Upload plugin has been tested with and supports the following mobile browsers: - -* Apple Safari on iOS 6.0+ -* Google Chrome on iOS 6.0+ -* Google Chrome on Android 4.0+ -* Default Browser on Android 2.3+ -* Opera Mobile 12.0+ - -### Supported features -For a detailed overview of the features supported by each browser version please have a look at the [Extended browser support information](https://github.com/blueimp/jQuery-File-Upload/wiki/Browser-support). - -## License -Released under the [MIT license](http://www.opensource.org/licenses/MIT). - -## Donations -jQuery File Upload is free software, but you can donate to support the developer, Sebastian Tschan: - -Flattr: [![Flattr](https://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/thing/286433/jQuery-File-Upload-Plugin) - -PayPal: [![PayPal](https://www.paypalobjects.com/WEBSCR-640-20110429-1/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=PYWYSYP77KL54) diff --git a/library/jqupload/angularjs.html b/library/jqupload/angularjs.html deleted file mode 100644 index d578cfa57..000000000 --- a/library/jqupload/angularjs.html +++ /dev/null @@ -1,211 +0,0 @@ - - - - - - - -jQuery File Upload Demo - AngularJS version - - - - - - - - - - - - - - - - - - -
    -

    jQuery File Upload Demo

    -

    AngularJS version

    - -
    -
    -

    File Upload widget with multiple file selection, drag&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.

    -
    -
    - - - - - -
    -
    - - - - Add files... - - - - - - -
    - -
    - -
    - -
     
    -
    -
    - - - - - - - - -
    -
    - -
    -
    -
    -

    - - {{file.name}} - {{file.name}} - - {{file.name}} -

    - {{file.error}} -
    -

    {{file.size | formatFileSize}}

    -
    -
    - - - -
    - -
    -
    -
    -

    Demo Notes

    -
    -
    -
      -
    • The maximum file size for uploads in this demo is 5 MB (default file size is unlimited).
    • -
    • Only image files (JPG, GIF, PNG) are allowed in this demo (by default there is no file type restriction).
    • -
    • Uploaded files will be deleted automatically after 5 minutes (demo setting).
    • -
    • You can drag & drop files from your desktop on this webpage (see Browser support).
    • -
    • Please refer to the project website and documentation for more information.
    • -
    • Built with Twitter's Bootstrap CSS framework and Icons from Glyphicons.
    • -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/library/jqupload/basic-plus.html b/library/jqupload/basic-plus.html deleted file mode 100644 index dc90bd768..000000000 --- a/library/jqupload/basic-plus.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - - -jQuery File Upload Demo - Basic Plus version - - - - - - - - - - - -
    -

    jQuery File Upload Demo

    -

    Basic Plus version

    - -
    -
    -

    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 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.

    -
    -
    - - - - Add files... - - - -
    -
    - -
    -
    -
    - -
    -
    -
    -
    -

    Demo Notes

    -
    -
    -
      -
    • The maximum file size for uploads in this demo is 5 MB (default file size is unlimited).
    • -
    • Only image files (JPG, GIF, PNG) are allowed in this demo (by default there is no file type restriction).
    • -
    • Uploaded files will be deleted automatically after 5 minutes (demo setting).
    • -
    • You can drag & drop files from your desktop on this webpage (see Browser support).
    • -
    • Please refer to the project website and documentation for more information.
    • -
    • Built with Twitter's Bootstrap CSS framework and Icons from Glyphicons.
    • -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/library/jqupload/basic.html b/library/jqupload/basic.html deleted file mode 100644 index ea5d0e66f..000000000 --- a/library/jqupload/basic.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - - -jQuery File Upload Demo - Basic version - - - - - - - - - - - -
    -

    jQuery File Upload Demo

    -

    Basic version

    - -
    -
    -

    File Upload widget with multiple file selection, drag&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.

    -
    -
    - - - - Select files... - - - -
    -
    - -
    -
    -
    - -
    -
    -
    -
    -

    Demo Notes

    -
    -
    -
      -
    • The maximum file size for uploads in this demo is 5 MB (default file size is unlimited).
    • -
    • Only image files (JPG, GIF, PNG) are allowed in this demo (by default there is no file type restriction).
    • -
    • Uploaded files will be deleted automatically after 5 minutes (demo setting).
    • -
    • You can drag & drop files from your desktop on this webpage (see Browser support).
    • -
    • Please refer to the project website and documentation for more information.
    • -
    • Built with Twitter's Bootstrap CSS framework and Icons from Glyphicons.
    • -
    -
    -
    -
    - - - - - - - - - - - - diff --git a/library/jqupload/blueimp-file-upload.jquery.json b/library/jqupload/blueimp-file-upload.jquery.json deleted file mode 100644 index 8382fb4b9..000000000 --- a/library/jqupload/blueimp-file-upload.jquery.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "blueimp-file-upload", - "version": "9.5.2", - "title": "jQuery File Upload", - "author": { - "name": "Sebastian Tschan", - "url": "https://blueimp.net" - }, - "licenses": [ - { - "type": "MIT", - "url": "http://www.opensource.org/licenses/MIT" - } - ], - "dependencies": { - "jquery": ">=1.6" - }, - "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": [ - "jquery", - "file", - "upload", - "widget", - "multiple", - "selection", - "drag", - "drop", - "progress", - "preview", - "cross-domain", - "cross-site", - "chunk", - "resume", - "gae", - "go", - "python", - "php", - "bootstrap" - ], - "homepage": "https://github.com/blueimp/jQuery-File-Upload", - "docs": "https://github.com/blueimp/jQuery-File-Upload/wiki", - "demo": "http://blueimp.github.io/jQuery-File-Upload/", - "bugs": "https://github.com/blueimp/jQuery-File-Upload/issues", - "maintainers": [ - { - "name": "Sebastian Tschan", - "url": "https://blueimp.net" - } - ] -} diff --git a/library/jqupload/bower.json b/library/jqupload/bower.json deleted file mode 100644 index 54ba68f82..000000000 --- a/library/jqupload/bower.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "name": "blueimp-file-upload", - "version": "9.5.2", - "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": [ - "jquery", - "file", - "upload", - "widget", - "multiple", - "selection", - "drag", - "drop", - "progress", - "preview", - "cross-domain", - "cross-site", - "chunk", - "resume", - "gae", - "go", - "python", - "php", - "bootstrap" - ], - "homepage": "https://github.com/blueimp/jQuery-File-Upload", - "author": { - "name": "Sebastian Tschan", - "url": "https://blueimp.net" - }, - "maintainers": [ - { - "name": "Sebastian Tschan", - "url": "https://blueimp.net" - } - ], - "repository": { - "type": "git", - "url": "git://github.com/blueimp/jQuery-File-Upload.git" - }, - "bugs": "https://github.com/blueimp/jQuery-File-Upload/issues", - "licenses": [ - { - "type": "MIT", - "url": "http://www.opensource.org/licenses/MIT" - } - ], - "dependencies": { - "jquery": ">=1.6", - "blueimp-tmpl": ">=2.5.3", - "blueimp-load-image": ">=1.11.0", - "blueimp-canvas-to-blob": ">=2.1.0" - }, - "main": [ - "css/jquery.fileupload.css", - "css/jquery.fileupload-ui.css", - "css/jquery.fileupload-noscript.css", - "css/jquery.fileupload-ui-noscript.css", - "js/cors/jquery.postmessage-transport.js", - "js/cors/jquery.xdr-transport.js", - "js/vendor/jquery.ui.widget.js", - "js/jquery.fileupload.js", - "js/jquery.fileupload-process.js", - "js/jquery.fileupload-validate.js", - "js/jquery.fileupload-image.js", - "js/jquery.fileupload-audio.js", - "js/jquery.fileupload-video.js", - "js/jquery.fileupload-ui.js", - "js/jquery.fileupload-jquery-ui.js", - "js/jquery.fileupload-angular.js", - "js/jquery.iframe-transport.js" - ], - "ignore": [ - "/*.*", - "/cors", - "css/demo-ie8.css", - "css/demo.css", - "css/style.css", - "js/app.js", - "js/main.js", - "server", - "test" - ] -} diff --git a/library/jqupload/cors/postmessage.html b/library/jqupload/cors/postmessage.html deleted file mode 100644 index 3d1448f08..000000000 --- a/library/jqupload/cors/postmessage.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - - -jQuery File Upload Plugin postMessage API - - - - - - \ No newline at end of file diff --git a/library/jqupload/cors/result.html b/library/jqupload/cors/result.html deleted file mode 100644 index 225131495..000000000 --- a/library/jqupload/cors/result.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - -jQuery Iframe Transport Plugin Redirect Page - - - - - diff --git a/library/jqupload/css/demo-ie8.css b/library/jqupload/css/demo-ie8.css deleted file mode 100644 index 262493d08..000000000 --- a/library/jqupload/css/demo-ie8.css +++ /dev/null @@ -1,21 +0,0 @@ -@charset "UTF-8"; -/* - * jQuery File Upload Demo CSS Fixes for IE<9 1.0.0 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2013, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -.navigation { - list-style: none; - padding: 0; - margin: 1em 0; -} -.navigation li { - display: inline; - margin-right: 10px; -} diff --git a/library/jqupload/css/demo.css b/library/jqupload/css/demo.css deleted file mode 100644 index 2b4d43934..000000000 --- a/library/jqupload/css/demo.css +++ /dev/null @@ -1,67 +0,0 @@ -@charset "UTF-8"; -/* - * jQuery File Upload Demo CSS 1.1.0 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2013, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -body { - max-width: 750px; - margin: 0 auto; - padding: 1em; - font-family: "Lucida Grande", "Lucida Sans Unicode", Arial, sans-serif; - font-size: 1em; - line-height: 1.4em; - background: #222; - color: #fff; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; -} -a { - color: orange; - text-decoration: none; -} -img { - border: 0; - vertical-align: middle; -} -h1 { - line-height: 1em; -} -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #eee; -} -table { - width: 100%; - margin: 10px 0; -} - -.fileupload-progress { - margin: 10px 0; -} -.fileupload-progress .progress-extended { - margin-top: 5px; -} -.error { - color: red; -} - -@media (min-width: 481px) { - .navigation { - list-style: none; - padding: 0; - } - .navigation li { - display: inline-block; - } - .navigation li:not(:first-child):before { - content: "| "; - } -} diff --git a/library/jqupload/css/jquery.fileupload-noscript.css b/library/jqupload/css/jquery.fileupload-noscript.css deleted file mode 100644 index 64d728fc3..000000000 --- a/library/jqupload/css/jquery.fileupload-noscript.css +++ /dev/null @@ -1,22 +0,0 @@ -@charset "UTF-8"; -/* - * jQuery File Upload Plugin NoScript CSS 1.2.0 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2013, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -.fileinput-button input { - position: static; - opacity: 1; - filter: none; - font-size: inherit; - direction: inherit; -} -.fileinput-button span { - display: none; -} diff --git a/library/jqupload/css/jquery.fileupload-ui-noscript.css b/library/jqupload/css/jquery.fileupload-ui-noscript.css deleted file mode 100644 index 87f110cdb..000000000 --- a/library/jqupload/css/jquery.fileupload-ui-noscript.css +++ /dev/null @@ -1,17 +0,0 @@ -@charset "UTF-8"; -/* - * jQuery File Upload UI Plugin NoScript CSS 8.8.5 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2012, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -.fileinput-button i, -.fileupload-buttonbar .delete, -.fileupload-buttonbar .toggle { - display: none; -} diff --git a/library/jqupload/css/jquery.fileupload-ui.css b/library/jqupload/css/jquery.fileupload-ui.css deleted file mode 100644 index 76fb376de..000000000 --- a/library/jqupload/css/jquery.fileupload-ui.css +++ /dev/null @@ -1,57 +0,0 @@ -@charset "UTF-8"; -/* - * jQuery File Upload UI Plugin CSS 9.0.0 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2010, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -.fileupload-buttonbar .btn, -.fileupload-buttonbar .toggle { - margin-bottom: 5px; -} -.progress-animated .progress-bar, -.progress-animated .bar { - background: url("../img/progressbar.gif") !important; - filter: none; -} -.fileupload-process { - float: right; - display: none; -} -.fileupload-processing .fileupload-process, -.files .processing .preview { - display: block; - width: 32px; - height: 32px; - background: url("../img/loading.gif") center no-repeat; - background-size: contain; -} -.files audio, -.files video { - max-width: 300px; -} - -@media (max-width: 767px) { - .fileupload-buttonbar .toggle, - .files .toggle, - .files .btn span { - display: none; - } - .files .name { - width: 80px; - word-wrap: break-word; - } - .files audio, - .files video { - max-width: 80px; - } - .files img, - .files canvas { - max-width: 100%; - } -} diff --git a/library/jqupload/css/jquery.fileupload.css b/library/jqupload/css/jquery.fileupload.css deleted file mode 100644 index fb6044d34..000000000 --- a/library/jqupload/css/jquery.fileupload.css +++ /dev/null @@ -1,36 +0,0 @@ -@charset "UTF-8"; -/* - * jQuery File Upload Plugin CSS 1.3.0 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2013, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -.fileinput-button { - position: relative; - overflow: hidden; -} -.fileinput-button input { - position: absolute; - top: 0; - right: 0; - margin: 0; - opacity: 0; - -ms-filter: 'alpha(opacity=0)'; - font-size: 200px; - direction: ltr; - cursor: pointer; -} - -/* Fixes for IE < 8 */ -@media screen\9 { - .fileinput-button input { - filter: alpha(opacity=0); - font-size: 100%; - height: 100%; - } -} diff --git a/library/jqupload/css/style.css b/library/jqupload/css/style.css deleted file mode 100644 index b2c60a6f1..000000000 --- a/library/jqupload/css/style.css +++ /dev/null @@ -1,15 +0,0 @@ -@charset "UTF-8"; -/* - * jQuery File Upload Plugin CSS Example 8.8.2 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2013, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -body { - padding-top: 60px; -} diff --git a/library/jqupload/img/loading.gif b/library/jqupload/img/loading.gif deleted file mode 100644 index 90f28cbdb..000000000 Binary files a/library/jqupload/img/loading.gif and /dev/null differ diff --git a/library/jqupload/img/progressbar.gif b/library/jqupload/img/progressbar.gif deleted file mode 100644 index fbcce6bc9..000000000 Binary files a/library/jqupload/img/progressbar.gif and /dev/null differ diff --git a/library/jqupload/index.html b/library/jqupload/index.html deleted file mode 100644 index a3a06aa9b..000000000 --- a/library/jqupload/index.html +++ /dev/null @@ -1,255 +0,0 @@ - - - - - - - -jQuery File Upload Demo - - - - - - - - - - - - - - - - - -
    -

    jQuery File Upload Demo

    -

    Basic Plus UI version

    - -
    -
    -

    File Upload widget with multiple file selection, drag&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.

    -
    -
    - -
    - - - -
    -
    - - - - Add files... - - - - - - - - -
    - -
    - -
    -
    -
    - -
     
    -
    -
    - - -
    -
    -
    -
    -

    Demo Notes

    -
    -
    -
      -
    • The maximum file size for uploads in this demo is 5 MB (default file size is unlimited).
    • -
    • Only image files (JPG, GIF, PNG) are allowed in this demo (by default there is no file type restriction).
    • -
    • Uploaded files will be deleted automatically after 5 minutes (demo setting).
    • -
    • You can drag & drop files from your desktop on this webpage (see Browser support).
    • -
    • Please refer to the project website and documentation for more information.
    • -
    • Built with Twitter's Bootstrap CSS framework and Icons from Glyphicons.
    • -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/library/jqupload/jquery-ui.html b/library/jqupload/jquery-ui.html deleted file mode 100644 index 993a4c815..000000000 --- a/library/jqupload/jquery-ui.html +++ /dev/null @@ -1,250 +0,0 @@ - - - - - - - -jQuery File Upload Demo - jQuery UI version - - - - - - - - - - - - - - - - - - - -

    jQuery File Upload Demo

    -

    jQuery UI version

    -
    - - -
    - -
    -

    File Upload widget with multiple file selection, drag&drop support, progress bars, validation and preview images, audio and video for jQuery UI.
    - 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.

    -
    - -
    - - - -
    -
    - - - Add files... - - - - - - - - -
    - - -
    - -
    -
    -
    -

    Demo Notes

    -
      -
    • The maximum file size for uploads in this demo is 5 MB (default file size is unlimited).
    • -
    • Only image files (JPG, GIF, PNG) are allowed in this demo (by default there is no file type restriction).
    • -
    • Uploaded files will be deleted automatically after 5 minutes (demo setting).
    • -
    • You can drag & drop files from your desktop on this webpage (see Browser support).
    • -
    • Please refer to the project website and documentation for more information.
    • -
    • Built with jQuery UI.
    • -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/library/jqupload/js/app.js b/library/jqupload/js/app.js deleted file mode 100644 index 47b4f923b..000000000 --- a/library/jqupload/js/app.js +++ /dev/null @@ -1,101 +0,0 @@ -/* - * jQuery File Upload Plugin Angular JS Example 1.2.1 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2013, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -/* jshint nomen:false */ -/* global window, angular */ - -(function () { - 'use strict'; - - var isOnGitHub = window.location.hostname === 'blueimp.github.io', - url = isOnGitHub ? '//jquery-file-upload.appspot.com/' : 'server/php/'; - - angular.module('demo', [ - 'blueimp.fileupload' - ]) - .config([ - '$httpProvider', 'fileUploadProvider', - function ($httpProvider, fileUploadProvider) { - delete $httpProvider.defaults.headers.common['X-Requested-With']; - fileUploadProvider.defaults.redirect = window.location.href.replace( - /\/[^\/]*$/, - '/cors/result.html?%s' - ); - if (isOnGitHub) { - // Demo settings: - angular.extend(fileUploadProvider.defaults, { - // Enable image resizing, except for Android and Opera, - // which actually support image resizing, but fail to - // send Blob objects via XHR requests: - disableImageResize: /Android(?!.*Chrome)|Opera/ - .test(window.navigator.userAgent), - maxFileSize: 5000000, - acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i - }); - } - } - ]) - - .controller('DemoFileUploadController', [ - '$scope', '$http', '$filter', '$window', - function ($scope, $http) { - $scope.options = { - url: url - }; - if (!isOnGitHub) { - $scope.loadingFiles = true; - $http.get(url) - .then( - function (response) { - $scope.loadingFiles = false; - $scope.queue = response.data.files || []; - }, - function () { - $scope.loadingFiles = false; - } - ); - } - } - ]) - - .controller('FileDestroyController', [ - '$scope', '$http', - function ($scope, $http) { - var file = $scope.file, - state; - if (file.url) { - file.$state = function () { - return state; - }; - file.$destroy = function () { - state = 'pending'; - return $http({ - url: file.deleteUrl, - method: file.deleteType - }).then( - function () { - state = 'resolved'; - $scope.clear(file); - }, - function () { - state = 'rejected'; - } - ); - }; - } else if (!file.$cancel && !file._index) { - file.$cancel = function () { - $scope.clear(file); - }; - } - } - ]); - -}()); diff --git a/library/jqupload/js/cors/jquery.postmessage-transport.js b/library/jqupload/js/cors/jquery.postmessage-transport.js deleted file mode 100644 index 2b4851e67..000000000 --- a/library/jqupload/js/cors/jquery.postmessage-transport.js +++ /dev/null @@ -1,117 +0,0 @@ -/* - * jQuery postMessage Transport Plugin 1.1.1 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2011, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -/* global define, window, document */ - -(function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define(['jquery'], factory); - } else { - // Browser globals: - factory(window.jQuery); - } -}(function ($) { - 'use strict'; - - var counter = 0, - names = [ - 'accepts', - 'cache', - 'contents', - 'contentType', - 'crossDomain', - 'data', - 'dataType', - 'headers', - 'ifModified', - 'mimeType', - 'password', - 'processData', - 'timeout', - 'traditional', - 'type', - 'url', - 'username' - ], - convert = function (p) { - return p; - }; - - $.ajaxSetup({ - converters: { - 'postmessage text': convert, - 'postmessage json': convert, - 'postmessage html': convert - } - }); - - $.ajaxTransport('postmessage', function (options) { - if (options.postMessage && window.postMessage) { - var iframe, - loc = $('').prop('href', options.postMessage)[0], - target = loc.protocol + '//' + loc.host, - xhrUpload = options.xhr().upload; - return { - send: function (_, completeCallback) { - counter += 1; - var message = { - id: 'postmessage-transport-' + counter - }, - eventName = 'message.' + message.id; - iframe = $( - '' - ).bind('load', function () { - $.each(names, function (i, name) { - message[name] = options[name]; - }); - message.dataType = message.dataType.replace('postmessage ', ''); - $(window).bind(eventName, function (e) { - e = e.originalEvent; - var data = e.data, - ev; - if (e.origin === target && data.id === message.id) { - if (data.type === 'progress') { - ev = document.createEvent('Event'); - ev.initEvent(data.type, false, true); - $.extend(ev, data); - xhrUpload.dispatchEvent(ev); - } else { - completeCallback( - data.status, - data.statusText, - {postmessage: data.result}, - data.headers - ); - iframe.remove(); - $(window).unbind(eventName); - } - } - }); - iframe[0].contentWindow.postMessage( - message, - target - ); - }).appendTo(document.body); - }, - abort: function () { - if (iframe) { - iframe.remove(); - } - } - }; - } - }); - -})); diff --git a/library/jqupload/js/cors/jquery.xdr-transport.js b/library/jqupload/js/cors/jquery.xdr-transport.js deleted file mode 100644 index 0044cc2d5..000000000 --- a/library/jqupload/js/cors/jquery.xdr-transport.js +++ /dev/null @@ -1,86 +0,0 @@ -/* - * jQuery XDomainRequest Transport Plugin 1.1.3 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2011, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - * - * Based on Julian Aubourg's ajaxHooks xdr.js: - * https://github.com/jaubourg/ajaxHooks/ - */ - -/* global define, window, XDomainRequest */ - -(function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define(['jquery'], factory); - } else { - // Browser globals: - factory(window.jQuery); - } -}(function ($) { - 'use strict'; - if (window.XDomainRequest && !$.support.cors) { - $.ajaxTransport(function (s) { - if (s.crossDomain && s.async) { - if (s.timeout) { - s.xdrTimeout = s.timeout; - delete s.timeout; - } - var xdr; - return { - send: function (headers, completeCallback) { - var addParamChar = /\?/.test(s.url) ? '&' : '?'; - function callback(status, statusText, responses, responseHeaders) { - xdr.onload = xdr.onerror = xdr.ontimeout = $.noop; - xdr = null; - completeCallback(status, statusText, responses, responseHeaders); - } - xdr = new XDomainRequest(); - // XDomainRequest only supports GET and POST: - if (s.type === 'DELETE') { - s.url = s.url + addParamChar + '_method=DELETE'; - s.type = 'POST'; - } else if (s.type === 'PUT') { - s.url = s.url + addParamChar + '_method=PUT'; - s.type = 'POST'; - } else if (s.type === 'PATCH') { - s.url = s.url + addParamChar + '_method=PATCH'; - s.type = 'POST'; - } - xdr.open(s.type, s.url); - xdr.onload = function () { - callback( - 200, - 'OK', - {text: xdr.responseText}, - 'Content-Type: ' + xdr.contentType - ); - }; - xdr.onerror = function () { - callback(404, 'Not Found'); - }; - if (s.xdrTimeout) { - xdr.ontimeout = function () { - callback(0, 'timeout'); - }; - xdr.timeout = s.xdrTimeout; - } - xdr.send((s.hasContent && s.data) || null); - }, - abort: function () { - if (xdr) { - xdr.onerror = $.noop(); - xdr.abort(); - } - } - }; - } - }); - } -})); diff --git a/library/jqupload/js/jquery.fileupload-angular.js b/library/jqupload/js/jquery.fileupload-angular.js deleted file mode 100644 index 666f51429..000000000 --- a/library/jqupload/js/jquery.fileupload-angular.js +++ /dev/null @@ -1,428 +0,0 @@ -/* - * jQuery File Upload AngularJS Plugin 2.1.3 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2013, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -/* jshint nomen:false */ -/* global define, angular */ - -(function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define([ - 'jquery', - 'angular', - './jquery.fileupload-image', - './jquery.fileupload-audio', - './jquery.fileupload-video', - './jquery.fileupload-validate' - ], factory); - } else { - factory(); - } -}(function () { - 'use strict'; - - angular.module('blueimp.fileupload', []) - - // The fileUpload service provides configuration options - // for the fileUpload directive and default handlers for - // File Upload events: - .provider('fileUpload', function () { - var scopeEvalAsync = function (expression) { - var scope = angular.element(this) - .fileupload('option', 'scope')(); - // Schedule a new $digest cycle if not already inside of one - // and evaluate the given expression: - scope.$evalAsync(expression); - }, - addFileMethods = function (scope, data) { - var files = data.files, - file = files[0]; - angular.forEach(files, function (file, index) { - file._index = index; - file.$state = function () { - return data.state(); - }; - file.$processing = function () { - return data.processing(); - }; - file.$progress = function () { - return data.progress(); - }; - file.$response = function () { - return data.response(); - }; - }); - file.$submit = function () { - if (!file.error) { - return data.submit(); - } - }; - file.$cancel = function () { - return data.abort(); - }; - }, - $config; - $config = this.defaults = { - handleResponse: function (e, data) { - var files = data.result && data.result.files; - if (files) { - data.scope().replace(data.files, files); - } else if (data.errorThrown || - data.textStatus === 'error') { - data.files[0].error = data.errorThrown || - data.textStatus; - } - }, - add: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - var scope = data.scope(), - filesCopy = []; - angular.forEach(data.files, function (file) { - filesCopy.push(file); - }); - scope.$apply(function () { - addFileMethods(scope, data); - var method = scope.option('prependFiles') ? - 'unshift' : 'push'; - Array.prototype[method].apply(scope.queue, data.files); - }); - data.process(function () { - return scope.process(data); - }).always(function () { - scope.$apply(function () { - addFileMethods(scope, data); - scope.replace(filesCopy, data.files); - }); - }).then(function () { - if ((scope.option('autoUpload') || - data.autoUpload) && - data.autoUpload !== false) { - data.submit(); - } - }); - }, - progress: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - data.scope().$apply(); - }, - done: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - var that = this; - data.scope().$apply(function () { - data.handleResponse.call(that, e, data); - }); - }, - fail: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - var that = this, - scope = data.scope(); - if (data.errorThrown === 'abort') { - scope.clear(data.files); - return; - } - scope.$apply(function () { - data.handleResponse.call(that, e, data); - }); - }, - stop: scopeEvalAsync, - processstart: scopeEvalAsync, - processstop: scopeEvalAsync, - getNumberOfFiles: function () { - var scope = this.scope(); - return scope.queue.length - scope.processing(); - }, - dataType: 'json', - autoUpload: false - }; - this.$get = [ - function () { - return { - defaults: $config - }; - } - ]; - }) - - // Format byte numbers to readable presentations: - .provider('formatFileSizeFilter', function () { - var $config = { - // Byte units following the IEC format - // http://en.wikipedia.org/wiki/Kilobyte - units: [ - {size: 1000000000, suffix: ' GB'}, - {size: 1000000, suffix: ' MB'}, - {size: 1000, suffix: ' KB'} - ] - }; - this.defaults = $config; - this.$get = function () { - return function (bytes) { - if (!angular.isNumber(bytes)) { - return ''; - } - var unit = true, - i = 0, - prefix, - suffix; - while (unit) { - unit = $config.units[i]; - prefix = unit.prefix || ''; - suffix = unit.suffix || ''; - if (i === $config.units.length - 1 || bytes >= unit.size) { - return prefix + (bytes / unit.size).toFixed(2) + suffix; - } - i += 1; - } - }; - }; - }) - - // The FileUploadController initializes the fileupload widget and - // provides scope methods to control the File Upload functionality: - .controller('FileUploadController', [ - '$scope', '$element', '$attrs', '$window', 'fileUpload', - function ($scope, $element, $attrs, $window, fileUpload) { - var uploadMethods = { - progress: function () { - return $element.fileupload('progress'); - }, - active: function () { - return $element.fileupload('active'); - }, - option: function (option, data) { - return $element.fileupload('option', option, data); - }, - add: function (data) { - return $element.fileupload('add', data); - }, - send: function (data) { - return $element.fileupload('send', data); - }, - process: function (data) { - return $element.fileupload('process', data); - }, - processing: function (data) { - return $element.fileupload('processing', data); - } - }; - $scope.disabled = !$window.jQuery.support.fileInput; - $scope.queue = $scope.queue || []; - $scope.clear = function (files) { - var queue = this.queue, - i = queue.length, - file = files, - length = 1; - if (angular.isArray(files)) { - file = files[0]; - length = files.length; - } - while (i) { - i -= 1; - if (queue[i] === file) { - return queue.splice(i, length); - } - } - }; - $scope.replace = function (oldFiles, newFiles) { - var queue = this.queue, - file = oldFiles[0], - i, - j; - for (i = 0; i < queue.length; i += 1) { - if (queue[i] === file) { - for (j = 0; j < newFiles.length; j += 1) { - queue[i + j] = newFiles[j]; - } - return; - } - } - }; - $scope.applyOnQueue = function (method) { - var list = this.queue.slice(0), - i, - file; - for (i = 0; i < list.length; i += 1) { - file = list[i]; - if (file[method]) { - file[method](); - } - } - }; - $scope.submit = function () { - this.applyOnQueue('$submit'); - }; - $scope.cancel = function () { - this.applyOnQueue('$cancel'); - }; - // Add upload methods to the scope: - angular.extend($scope, uploadMethods); - // The fileupload widget will initialize with - // the options provided via "data-"-parameters, - // as well as those given via options object: - $element.fileupload(angular.extend( - {scope: function () { - return $scope; - }}, - fileUpload.defaults - )).on('fileuploadadd', function (e, data) { - data.scope = $scope.option('scope'); - }).on('fileuploadfail', function (e, data) { - if (data.errorThrown === 'abort') { - return; - } - if (data.dataType && - data.dataType.indexOf('json') === data.dataType.length - 4) { - try { - data.result = angular.fromJson(data.jqXHR.responseText); - } catch (ignore) {} - } - }).on([ - 'fileuploadadd', - 'fileuploadsubmit', - 'fileuploadsend', - 'fileuploaddone', - 'fileuploadfail', - 'fileuploadalways', - 'fileuploadprogress', - 'fileuploadprogressall', - 'fileuploadstart', - 'fileuploadstop', - 'fileuploadchange', - 'fileuploadpaste', - 'fileuploaddrop', - 'fileuploaddragover', - 'fileuploadchunksend', - 'fileuploadchunkdone', - 'fileuploadchunkfail', - 'fileuploadchunkalways', - 'fileuploadprocessstart', - 'fileuploadprocess', - 'fileuploadprocessdone', - 'fileuploadprocessfail', - 'fileuploadprocessalways', - 'fileuploadprocessstop' - ].join(' '), function (e, data) { - if ($scope.$emit(e.type, data).defaultPrevented) { - e.preventDefault(); - } - }).on('remove', function () { - // Remove upload methods from the scope, - // when the widget is removed: - var method; - for (method in uploadMethods) { - if (uploadMethods.hasOwnProperty(method)) { - delete $scope[method]; - } - } - }); - // Observe option changes: - $scope.$watch( - $attrs.fileUpload, - function (newOptions) { - if (newOptions) { - $element.fileupload('option', newOptions); - } - } - ); - } - ]) - - // Provide File Upload progress feedback: - .controller('FileUploadProgressController', [ - '$scope', '$attrs', '$parse', - function ($scope, $attrs, $parse) { - var fn = $parse($attrs.fileUploadProgress), - update = function () { - var progress = fn($scope); - if (!progress || !progress.total) { - return; - } - $scope.num = Math.floor( - progress.loaded / progress.total * 100 - ); - }; - update(); - $scope.$watch( - $attrs.fileUploadProgress + '.loaded', - function (newValue, oldValue) { - if (newValue !== oldValue) { - update(); - } - } - ); - } - ]) - - // Display File Upload previews: - .controller('FileUploadPreviewController', [ - '$scope', '$element', '$attrs', - function ($scope, $element, $attrs) { - $scope.$watch( - $attrs.fileUploadPreview + '.preview', - function (preview) { - $element.empty(); - if (preview) { - $element.append(preview); - } - } - ); - } - ]) - - .directive('fileUpload', function () { - return { - controller: 'FileUploadController', - scope: true - }; - }) - - .directive('fileUploadProgress', function () { - return { - controller: 'FileUploadProgressController', - scope: true - }; - }) - - .directive('fileUploadPreview', function () { - return { - controller: 'FileUploadPreviewController' - }; - }) - - // Enhance the HTML5 download attribute to - // allow drag&drop of files to the desktop: - .directive('download', function () { - return function (scope, elm) { - elm.on('dragstart', function (e) { - try { - e.originalEvent.dataTransfer.setData( - 'DownloadURL', - [ - 'application/octet-stream', - elm.prop('download'), - elm.prop('href') - ].join(':') - ); - } catch (ignore) {} - }); - }; - }); - -})); diff --git a/library/jqupload/js/jquery.fileupload-audio.js b/library/jqupload/js/jquery.fileupload-audio.js deleted file mode 100644 index 575800e82..000000000 --- a/library/jqupload/js/jquery.fileupload-audio.js +++ /dev/null @@ -1,106 +0,0 @@ -/* - * jQuery File Upload Audio Preview Plugin 1.0.3 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2013, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -/* jshint nomen:false */ -/* global define, window, document */ - -(function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define([ - 'jquery', - 'load-image', - './jquery.fileupload-process' - ], factory); - } else { - // Browser globals: - factory( - window.jQuery, - window.loadImage - ); - } -}(function ($, loadImage) { - 'use strict'; - - // Prepend to the default processQueue: - $.blueimp.fileupload.prototype.options.processQueue.unshift( - { - action: 'loadAudio', - // Use the action as prefix for the "@" options: - prefix: true, - fileTypes: '@', - maxFileSize: '@', - disabled: '@disableAudioPreview' - }, - { - action: 'setAudio', - name: '@audioPreviewName', - disabled: '@disableAudioPreview' - } - ); - - // The File Upload Audio Preview plugin extends the fileupload widget - // with audio preview functionality: - $.widget('blueimp.fileupload', $.blueimp.fileupload, { - - options: { - // The regular expression for the types of audio files to load, - // matched against the file type: - loadAudioFileTypes: /^audio\/.*$/ - }, - - _audioElement: document.createElement('audio'), - - processActions: { - - // Loads the audio file given via data.files and data.index - // as audio element if the browser supports playing it. - // Accepts the options fileTypes (regular expression) - // and maxFileSize (integer) to limit the files to load: - loadAudio: function (data, options) { - if (options.disabled) { - return data; - } - var file = data.files[data.index], - url, - audio; - if (this._audioElement.canPlayType && - this._audioElement.canPlayType(file.type) && - ($.type(options.maxFileSize) !== 'number' || - file.size <= options.maxFileSize) && - (!options.fileTypes || - options.fileTypes.test(file.type))) { - url = loadImage.createObjectURL(file); - if (url) { - audio = this._audioElement.cloneNode(false); - audio.src = url; - audio.controls = true; - data.audio = audio; - return data; - } - } - return data; - }, - - // Sets the audio element as a property of the file object: - setAudio: function (data, options) { - if (data.audio && !options.disabled) { - data.files[data.index][options.name || 'preview'] = data.audio; - } - return data; - } - - } - - }); - -})); diff --git a/library/jqupload/js/jquery.fileupload-image.js b/library/jqupload/js/jquery.fileupload-image.js deleted file mode 100644 index 8fbf7d42c..000000000 --- a/library/jqupload/js/jquery.fileupload-image.js +++ /dev/null @@ -1,309 +0,0 @@ -/* - * jQuery File Upload Image Preview & Resize Plugin 1.7.0 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2013, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -/* jshint nomen:false */ -/* global define, window, Blob */ - -(function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define([ - 'jquery', - 'load-image', - 'load-image-meta', - 'load-image-exif', - 'load-image-ios', - 'canvas-to-blob', - './jquery.fileupload-process' - ], factory); - } else { - // Browser globals: - factory( - window.jQuery, - window.loadImage - ); - } -}(function ($, loadImage) { - 'use strict'; - - // Prepend to the default processQueue: - $.blueimp.fileupload.prototype.options.processQueue.unshift( - { - action: 'loadImageMetaData', - disableImageHead: '@', - disableExif: '@', - disableExifThumbnail: '@', - disableExifSub: '@', - disableExifGps: '@', - disabled: '@disableImageMetaDataLoad' - }, - { - action: 'loadImage', - // Use the action as prefix for the "@" options: - prefix: true, - fileTypes: '@', - maxFileSize: '@', - noRevoke: '@', - disabled: '@disableImageLoad' - }, - { - action: 'resizeImage', - // Use "image" as prefix for the "@" options: - prefix: 'image', - maxWidth: '@', - maxHeight: '@', - minWidth: '@', - minHeight: '@', - crop: '@', - orientation: '@', - forceResize: '@', - disabled: '@disableImageResize' - }, - { - action: 'saveImage', - quality: '@imageQuality', - type: '@imageType', - disabled: '@disableImageResize' - }, - { - action: 'saveImageMetaData', - disabled: '@disableImageMetaDataSave' - }, - { - action: 'resizeImage', - // Use "preview" as prefix for the "@" options: - prefix: 'preview', - maxWidth: '@', - maxHeight: '@', - minWidth: '@', - minHeight: '@', - crop: '@', - orientation: '@', - thumbnail: '@', - canvas: '@', - disabled: '@disableImagePreview' - }, - { - action: 'setImage', - name: '@imagePreviewName', - disabled: '@disableImagePreview' - }, - { - action: 'deleteImageReferences', - disabled: '@disableImageReferencesDeletion' - } - ); - - // The File Upload Resize plugin extends the fileupload widget - // with image resize functionality: - $.widget('blueimp.fileupload', $.blueimp.fileupload, { - - options: { - // The regular expression for the types of images to load: - // matched against the file type: - loadImageFileTypes: /^image\/(gif|jpeg|png)$/, - // The maximum file size of images to load: - loadImageMaxFileSize: 10000000, // 10MB - // The maximum width of resized images: - imageMaxWidth: 1920, - // The maximum height of resized images: - imageMaxHeight: 1080, - // Defines the image orientation (1-8) or takes the orientation - // value from Exif data if set to true: - imageOrientation: false, - // Define if resized images should be cropped or only scaled: - imageCrop: false, - // Disable the resize image functionality by default: - disableImageResize: true, - // The maximum width of the preview images: - previewMaxWidth: 80, - // The maximum height of the preview images: - previewMaxHeight: 80, - // Defines the preview orientation (1-8) or takes the orientation - // value from Exif data if set to true: - previewOrientation: true, - // Create the preview using the Exif data thumbnail: - previewThumbnail: true, - // Define if preview images should be cropped or only scaled: - previewCrop: false, - // Define if preview images should be resized as canvas elements: - previewCanvas: true - }, - - processActions: { - - // Loads the image given via data.files and data.index - // as img element, if the browser supports the File API. - // Accepts the options fileTypes (regular expression) - // and maxFileSize (integer) to limit the files to load: - loadImage: function (data, options) { - if (options.disabled) { - return data; - } - var that = this, - file = data.files[data.index], - dfd = $.Deferred(); - if (($.type(options.maxFileSize) === 'number' && - file.size > options.maxFileSize) || - (options.fileTypes && - !options.fileTypes.test(file.type)) || - !loadImage( - file, - function (img) { - if (img.src) { - data.img = img; - } - dfd.resolveWith(that, [data]); - }, - options - )) { - return data; - } - return dfd.promise(); - }, - - // Resizes the image given as data.canvas or data.img - // and updates data.canvas or data.img with the resized image. - // Also stores the resized image as preview property. - // Accepts the options maxWidth, maxHeight, minWidth, - // minHeight, canvas and crop: - resizeImage: function (data, options) { - if (options.disabled || !(data.canvas || data.img)) { - return data; - } - options = $.extend({canvas: true}, options); - var that = this, - dfd = $.Deferred(), - img = (options.canvas && data.canvas) || data.img, - resolve = function (newImg) { - if (newImg && (newImg.width !== img.width || - newImg.height !== img.height || - options.forceResize)) { - data[newImg.getContext ? 'canvas' : 'img'] = newImg; - } - data.preview = newImg; - dfd.resolveWith(that, [data]); - }, - thumbnail; - if (data.exif) { - if (options.orientation === true) { - options.orientation = data.exif.get('Orientation'); - } - if (options.thumbnail) { - thumbnail = data.exif.get('Thumbnail'); - if (thumbnail) { - loadImage(thumbnail, resolve, options); - return dfd.promise(); - } - } - } - if (img) { - resolve(loadImage.scale(img, options)); - return dfd.promise(); - } - return data; - }, - - // Saves the processed image given as data.canvas - // inplace at data.index of data.files: - saveImage: function (data, options) { - if (!data.canvas || options.disabled) { - return data; - } - var that = this, - file = data.files[data.index], - dfd = $.Deferred(); - if (data.canvas.toBlob) { - data.canvas.toBlob( - function (blob) { - if (!blob.name) { - if (file.type === blob.type) { - blob.name = file.name; - } else if (file.name) { - blob.name = file.name.replace( - /\..+$/, - '.' + blob.type.substr(6) - ); - } - } - // Don't restore invalid meta data: - if (file.type !== blob.type) { - delete data.imageHead; - } - // Store the created blob at the position - // of the original file in the files list: - data.files[data.index] = blob; - dfd.resolveWith(that, [data]); - }, - options.type || file.type, - options.quality - ); - } else { - return data; - } - return dfd.promise(); - }, - - loadImageMetaData: function (data, options) { - if (options.disabled) { - return data; - } - var that = this, - dfd = $.Deferred(); - loadImage.parseMetaData(data.files[data.index], function (result) { - $.extend(data, result); - dfd.resolveWith(that, [data]); - }, options); - return dfd.promise(); - }, - - saveImageMetaData: function (data, options) { - if (!(data.imageHead && data.canvas && - data.canvas.toBlob && !options.disabled)) { - return data; - } - var file = data.files[data.index], - blob = new Blob([ - data.imageHead, - // Resized images always have a head size of 20 bytes, - // including the JPEG marker and a minimal JFIF header: - this._blobSlice.call(file, 20) - ], {type: file.type}); - blob.name = file.name; - data.files[data.index] = blob; - return data; - }, - - // Sets the resized version of the image as a property of the - // file object, must be called after "saveImage": - setImage: function (data, options) { - if (data.preview && !options.disabled) { - data.files[data.index][options.name || 'preview'] = data.preview; - } - return data; - }, - - deleteImageReferences: function (data, options) { - if (!options.disabled) { - delete data.img; - delete data.canvas; - delete data.preview; - delete data.imageHead; - } - return data; - } - - } - - }); - -})); diff --git a/library/jqupload/js/jquery.fileupload-jquery-ui.js b/library/jqupload/js/jquery.fileupload-jquery-ui.js deleted file mode 100755 index 7b4ffdf05..000000000 --- a/library/jqupload/js/jquery.fileupload-jquery-ui.js +++ /dev/null @@ -1,144 +0,0 @@ -/* - * jQuery File Upload jQuery UI Plugin 8.7.0 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2013, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -/* jshint nomen:false */ -/* global define, window */ - -(function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define(['jquery', './jquery.fileupload-ui'], factory); - } else { - // Browser globals: - factory(window.jQuery); - } -}(function ($) { - 'use strict'; - - $.widget('blueimp.fileupload', $.blueimp.fileupload, { - - options: { - progress: function (e, data) { - if (data.context) { - data.context.find('.progress').progressbar( - 'option', - 'value', - parseInt(data.loaded / data.total * 100, 10) - ); - } - }, - progressall: function (e, data) { - var $this = $(this); - $this.find('.fileupload-progress') - .find('.progress').progressbar( - 'option', - 'value', - parseInt(data.loaded / data.total * 100, 10) - ).end() - .find('.progress-extended').each(function () { - $(this).html( - ($this.data('blueimp-fileupload') || - $this.data('fileupload')) - ._renderExtendedProgress(data) - ); - }); - } - }, - - _renderUpload: function (func, files) { - var node = this._super(func, files), - showIconText = $(window).width() > 480; - node.find('.progress').empty().progressbar(); - node.find('.start').button({ - icons: {primary: 'ui-icon-circle-arrow-e'}, - text: showIconText - }); - node.find('.cancel').button({ - icons: {primary: 'ui-icon-cancel'}, - text: showIconText - }); - if (node.hasClass('fade')) { - node.hide(); - } - return node; - }, - - _renderDownload: function (func, files) { - var node = this._super(func, files), - showIconText = $(window).width() > 480; - node.find('.delete').button({ - icons: {primary: 'ui-icon-trash'}, - text: showIconText - }); - if (node.hasClass('fade')) { - node.hide(); - } - return node; - }, - - _transition: function (node) { - var deferred = $.Deferred(); - if (node.hasClass('fade')) { - node.fadeToggle( - this.options.transitionDuration, - this.options.transitionEasing, - function () { - deferred.resolveWith(node); - } - ); - } else { - deferred.resolveWith(node); - } - return deferred; - }, - - _create: function () { - this._super(); - this.element - .find('.fileupload-buttonbar') - .find('.fileinput-button').each(function () { - var input = $(this).find('input:file').detach(); - $(this) - .button({icons: {primary: 'ui-icon-plusthick'}}) - .append(input); - }) - .end().find('.start') - .button({icons: {primary: 'ui-icon-circle-arrow-e'}}) - .end().find('.cancel') - .button({icons: {primary: 'ui-icon-cancel'}}) - .end().find('.delete') - .button({icons: {primary: 'ui-icon-trash'}}) - .end().find('.progress').progressbar(); - }, - - _destroy: function () { - this.element - .find('.fileupload-buttonbar') - .find('.fileinput-button').each(function () { - var input = $(this).find('input:file').detach(); - $(this) - .button('destroy') - .append(input); - }) - .end().find('.start') - .button('destroy') - .end().find('.cancel') - .button('destroy') - .end().find('.delete') - .button('destroy') - .end().find('.progress').progressbar('destroy'); - this._super(); - } - - }); - -})); diff --git a/library/jqupload/js/jquery.fileupload-process.js b/library/jqupload/js/jquery.fileupload-process.js deleted file mode 100644 index 8a6b929a6..000000000 --- a/library/jqupload/js/jquery.fileupload-process.js +++ /dev/null @@ -1,172 +0,0 @@ -/* - * jQuery File Upload Processing Plugin 1.3.0 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2012, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -/* jshint nomen:false */ -/* global define, window */ - -(function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define([ - 'jquery', - './jquery.fileupload' - ], factory); - } else { - // Browser globals: - factory( - window.jQuery - ); - } -}(function ($) { - 'use strict'; - - var originalAdd = $.blueimp.fileupload.prototype.options.add; - - // The File Upload Processing plugin extends the fileupload widget - // with file processing functionality: - $.widget('blueimp.fileupload', $.blueimp.fileupload, { - - options: { - // The list of processing actions: - processQueue: [ - /* - { - action: 'log', - type: 'debug' - } - */ - ], - add: function (e, data) { - var $this = $(this); - data.process(function () { - return $this.fileupload('process', data); - }); - originalAdd.call(this, e, data); - } - }, - - processActions: { - /* - log: function (data, options) { - console[options.type]( - 'Processing "' + data.files[data.index].name + '"' - ); - } - */ - }, - - _processFile: function (data, originalData) { - var that = this, - dfd = $.Deferred().resolveWith(that, [data]), - chain = dfd.promise(); - this._trigger('process', null, data); - $.each(data.processQueue, function (i, settings) { - var func = function (data) { - if (originalData.errorThrown) { - return $.Deferred() - .rejectWith(that, [originalData]).promise(); - } - return that.processActions[settings.action].call( - that, - data, - settings - ); - }; - chain = chain.pipe(func, settings.always && func); - }); - chain - .done(function () { - that._trigger('processdone', null, data); - that._trigger('processalways', null, data); - }) - .fail(function () { - that._trigger('processfail', null, data); - that._trigger('processalways', null, data); - }); - return chain; - }, - - // Replaces the settings of each processQueue item that - // are strings starting with an "@", using the remaining - // substring as key for the option map, - // e.g. "@autoUpload" is replaced with options.autoUpload: - _transformProcessQueue: function (options) { - var processQueue = []; - $.each(options.processQueue, function () { - var settings = {}, - action = this.action, - prefix = this.prefix === true ? action : this.prefix; - $.each(this, function (key, value) { - if ($.type(value) === 'string' && - value.charAt(0) === '@') { - settings[key] = options[ - value.slice(1) || (prefix ? prefix + - key.charAt(0).toUpperCase() + key.slice(1) : key) - ]; - } else { - settings[key] = value; - } - - }); - processQueue.push(settings); - }); - options.processQueue = processQueue; - }, - - // Returns the number of files currently in the processsing queue: - processing: function () { - return this._processing; - }, - - // Processes the files given as files property of the data parameter, - // returns a Promise object that allows to bind callbacks: - process: function (data) { - var that = this, - options = $.extend({}, this.options, data); - if (options.processQueue && options.processQueue.length) { - this._transformProcessQueue(options); - if (this._processing === 0) { - this._trigger('processstart'); - } - $.each(data.files, function (index) { - var opts = index ? $.extend({}, options) : options, - func = function () { - if (data.errorThrown) { - return $.Deferred() - .rejectWith(that, [data]).promise(); - } - return that._processFile(opts, data); - }; - opts.index = index; - that._processing += 1; - that._processingQueue = that._processingQueue.pipe(func, func) - .always(function () { - that._processing -= 1; - if (that._processing === 0) { - that._trigger('processstop'); - } - }); - }); - } - return this._processingQueue; - }, - - _create: function () { - this._super(); - this._processing = 0; - this._processingQueue = $.Deferred().resolveWith(this) - .promise(); - } - - }); - -})); diff --git a/library/jqupload/js/jquery.fileupload-ui.js b/library/jqupload/js/jquery.fileupload-ui.js deleted file mode 100644 index 417edb73f..000000000 --- a/library/jqupload/js/jquery.fileupload-ui.js +++ /dev/null @@ -1,701 +0,0 @@ -/* - * jQuery File Upload User Interface Plugin 9.5.1 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2010, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -/* jshint nomen:false */ -/* global define, window */ - -(function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define([ - 'jquery', - 'tmpl', - './jquery.fileupload-image', - './jquery.fileupload-audio', - './jquery.fileupload-video', - './jquery.fileupload-validate' - ], factory); - } else { - // Browser globals: - factory( - window.jQuery, - window.tmpl - ); - } -}(function ($, tmpl) { - 'use strict'; - - $.blueimp.fileupload.prototype._specialOptions.push( - 'filesContainer', - 'uploadTemplateId', - 'downloadTemplateId' - ); - - // The UI version extends the file upload widget - // and adds complete user interface interaction: - $.widget('blueimp.fileupload', $.blueimp.fileupload, { - - options: { - // By default, files added to the widget are uploaded as soon - // as the user clicks on the start buttons. To enable automatic - // uploads, set the following option to true: - autoUpload: false, - // The ID of the upload template: - uploadTemplateId: 'template-upload', - // The ID of the download template: - downloadTemplateId: 'template-download', - // The container for the list of files. If undefined, it is set to - // an element with class "files" inside of the widget element: - filesContainer: undefined, - // By default, files are appended to the files container. - // Set the following option to true, to prepend files instead: - prependFiles: false, - // The expected data type of the upload response, sets the dataType - // option of the $.ajax upload requests: - dataType: 'json', - - // Function returning the current number of files, - // used by the maxNumberOfFiles validation: - getNumberOfFiles: function () { - return this.filesContainer.children() - .not('.processing').length; - }, - - // Callback to retrieve the list of files from the server response: - getFilesFromResponse: function (data) { - if (data.result && $.isArray(data.result.files)) { - return data.result.files; - } - return []; - }, - - // The add callback is invoked as soon as files are added to the fileupload - // widget (via file input selection, drag & drop or add API call). - // See the basic file upload widget for more information: - add: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - var $this = $(this), - that = $this.data('blueimp-fileupload') || - $this.data('fileupload'), - options = that.options; - data.context = that._renderUpload(data.files) - .data('data', data) - .addClass('processing'); - options.filesContainer[ - options.prependFiles ? 'prepend' : 'append' - ](data.context); - that._forceReflow(data.context); - $.when( - that._transition(data.context), - data.process(function () { - return $this.fileupload('process', data); - }) - ).always(function () { - data.context.each(function (index) { - $(this).find('.size').text( - that._formatFileSize(data.files[index].size) - ); - }).removeClass('processing'); - that._renderPreviews(data); - }).done(function () { - data.context.find('.start').prop('disabled', false); - if ((that._trigger('added', e, data) !== false) && - (options.autoUpload || data.autoUpload) && - data.autoUpload !== false) { - data.submit(); - } - }).fail(function () { - if (data.files.error) { - data.context.each(function (index) { - var error = data.files[index].error; - if (error) { - $(this).find('.error').text(error); - } - }); - } - }); - }, - // Callback for the start of each file upload request: - send: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - var that = $(this).data('blueimp-fileupload') || - $(this).data('fileupload'); - if (data.context && data.dataType && - data.dataType.substr(0, 6) === 'iframe') { - // Iframe Transport does not support progress events. - // In lack of an indeterminate progress bar, we set - // the progress to 100%, showing the full animated bar: - data.context - .find('.progress').addClass( - !$.support.transition && 'progress-animated' - ) - .attr('aria-valuenow', 100) - .children().first().css( - 'width', - '100%' - ); - } - return that._trigger('sent', e, data); - }, - // Callback for successful uploads: - done: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - var that = $(this).data('blueimp-fileupload') || - $(this).data('fileupload'), - getFilesFromResponse = data.getFilesFromResponse || - that.options.getFilesFromResponse, - files = getFilesFromResponse(data), - template, - deferred; - if (data.context) { - data.context.each(function (index) { - var file = files[index] || - {error: 'Empty file upload result'}; - deferred = that._addFinishedDeferreds(); - that._transition($(this)).done( - function () { - var node = $(this); - template = that._renderDownload([file]) - .replaceAll(node); - that._forceReflow(template); - that._transition(template).done( - function () { - data.context = $(this); - that._trigger('completed', e, data); - that._trigger('finished', e, data); - deferred.resolve(); - } - ); - } - ); - }); - } else { - template = that._renderDownload(files)[ - that.options.prependFiles ? 'prependTo' : 'appendTo' - ](that.options.filesContainer); - that._forceReflow(template); - deferred = that._addFinishedDeferreds(); - that._transition(template).done( - function () { - data.context = $(this); - that._trigger('completed', e, data); - that._trigger('finished', e, data); - deferred.resolve(); - } - ); - } - }, - // Callback for failed (abort or error) uploads: - fail: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - var that = $(this).data('blueimp-fileupload') || - $(this).data('fileupload'), - template, - deferred; - if (data.context) { - data.context.each(function (index) { - if (data.errorThrown !== 'abort') { - var file = data.files[index]; - file.error = file.error || data.errorThrown || - true; - deferred = that._addFinishedDeferreds(); - that._transition($(this)).done( - function () { - var node = $(this); - template = that._renderDownload([file]) - .replaceAll(node); - that._forceReflow(template); - that._transition(template).done( - function () { - data.context = $(this); - that._trigger('failed', e, data); - that._trigger('finished', e, data); - deferred.resolve(); - } - ); - } - ); - } else { - deferred = that._addFinishedDeferreds(); - that._transition($(this)).done( - function () { - $(this).remove(); - that._trigger('failed', e, data); - that._trigger('finished', e, data); - deferred.resolve(); - } - ); - } - }); - } else if (data.errorThrown !== 'abort') { - data.context = that._renderUpload(data.files)[ - that.options.prependFiles ? 'prependTo' : 'appendTo' - ](that.options.filesContainer) - .data('data', data); - that._forceReflow(data.context); - deferred = that._addFinishedDeferreds(); - that._transition(data.context).done( - function () { - data.context = $(this); - that._trigger('failed', e, data); - that._trigger('finished', e, data); - deferred.resolve(); - } - ); - } else { - that._trigger('failed', e, data); - that._trigger('finished', e, data); - that._addFinishedDeferreds().resolve(); - } - }, - // Callback for upload progress events: - progress: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - var progress = Math.floor(data.loaded / data.total * 100); - if (data.context) { - data.context.each(function () { - $(this).find('.progress') - .attr('aria-valuenow', progress) - .children().first().css( - 'width', - progress + '%' - ); - }); - } - }, - // Callback for global upload progress events: - progressall: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - var $this = $(this), - progress = Math.floor(data.loaded / data.total * 100), - globalProgressNode = $this.find('.fileupload-progress'), - extendedProgressNode = globalProgressNode - .find('.progress-extended'); - if (extendedProgressNode.length) { - extendedProgressNode.html( - ($this.data('blueimp-fileupload') || $this.data('fileupload')) - ._renderExtendedProgress(data) - ); - } - globalProgressNode - .find('.progress') - .attr('aria-valuenow', progress) - .children().first().css( - 'width', - progress + '%' - ); - }, - // Callback for uploads start, equivalent to the global ajaxStart event: - start: function (e) { - if (e.isDefaultPrevented()) { - return false; - } - var that = $(this).data('blueimp-fileupload') || - $(this).data('fileupload'); - that._resetFinishedDeferreds(); - that._transition($(this).find('.fileupload-progress')).done( - function () { - that._trigger('started', e); - } - ); - }, - // Callback for uploads stop, equivalent to the global ajaxStop event: - stop: function (e) { - if (e.isDefaultPrevented()) { - return false; - } - var that = $(this).data('blueimp-fileupload') || - $(this).data('fileupload'), - deferred = that._addFinishedDeferreds(); - $.when.apply($, that._getFinishedDeferreds()) - .done(function () { - that._trigger('stopped', e); - }); - that._transition($(this).find('.fileupload-progress')).done( - function () { - $(this).find('.progress') - .attr('aria-valuenow', '0') - .children().first().css('width', '0%'); - $(this).find('.progress-extended').html(' '); - deferred.resolve(); - } - ); - }, - processstart: function (e) { - if (e.isDefaultPrevented()) { - return false; - } - $(this).addClass('fileupload-processing'); - }, - processstop: function (e) { - if (e.isDefaultPrevented()) { - return false; - } - $(this).removeClass('fileupload-processing'); - }, - // Callback for file deletion: - destroy: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - var that = $(this).data('blueimp-fileupload') || - $(this).data('fileupload'), - removeNode = function () { - that._transition(data.context).done( - function () { - $(this).remove(); - that._trigger('destroyed', e, data); - } - ); - }; - if (data.url) { - data.dataType = data.dataType || that.options.dataType; - $.ajax(data).done(removeNode).fail(function () { - that._trigger('destroyfailed', e, data); - }); - } else { - removeNode(); - } - } - }, - - _resetFinishedDeferreds: function () { - this._finishedUploads = []; - }, - - _addFinishedDeferreds: function (deferred) { - if (!deferred) { - deferred = $.Deferred(); - } - this._finishedUploads.push(deferred); - return deferred; - }, - - _getFinishedDeferreds: function () { - return this._finishedUploads; - }, - - // Link handler, that allows to download files - // by drag & drop of the links to the desktop: - _enableDragToDesktop: function () { - var link = $(this), - url = link.prop('href'), - name = link.prop('download'), - type = 'application/octet-stream'; - link.bind('dragstart', function (e) { - try { - e.originalEvent.dataTransfer.setData( - 'DownloadURL', - [type, name, url].join(':') - ); - } catch (ignore) {} - }); - }, - - _formatFileSize: function (bytes) { - if (typeof bytes !== 'number') { - return ''; - } - if (bytes >= 1000000000) { - return (bytes / 1000000000).toFixed(2) + ' GB'; - } - if (bytes >= 1000000) { - return (bytes / 1000000).toFixed(2) + ' MB'; - } - return (bytes / 1000).toFixed(2) + ' KB'; - }, - - _formatBitrate: function (bits) { - if (typeof bits !== 'number') { - return ''; - } - if (bits >= 1000000000) { - return (bits / 1000000000).toFixed(2) + ' Gbit/s'; - } - if (bits >= 1000000) { - return (bits / 1000000).toFixed(2) + ' Mbit/s'; - } - if (bits >= 1000) { - return (bits / 1000).toFixed(2) + ' kbit/s'; - } - return bits.toFixed(2) + ' bit/s'; - }, - - _formatTime: function (seconds) { - var date = new Date(seconds * 1000), - days = Math.floor(seconds / 86400); - days = days ? days + 'd ' : ''; - return days + - ('0' + date.getUTCHours()).slice(-2) + ':' + - ('0' + date.getUTCMinutes()).slice(-2) + ':' + - ('0' + date.getUTCSeconds()).slice(-2); - }, - - _formatPercentage: function (floatValue) { - return (floatValue * 100).toFixed(2) + ' %'; - }, - - _renderExtendedProgress: function (data) { - return this._formatBitrate(data.bitrate) + ' | ' + - this._formatTime( - (data.total - data.loaded) * 8 / data.bitrate - ) + ' | ' + - this._formatPercentage( - data.loaded / data.total - ) + ' | ' + - this._formatFileSize(data.loaded) + ' / ' + - this._formatFileSize(data.total); - }, - - _renderTemplate: function (func, files) { - if (!func) { - return $(); - } - var result = func({ - files: files, - formatFileSize: this._formatFileSize, - options: this.options - }); - if (result instanceof $) { - return result; - } - return $(this.options.templatesContainer).html(result).children(); - }, - - _renderPreviews: function (data) { - data.context.find('.preview').each(function (index, elm) { - $(elm).append(data.files[index].preview); - }); - }, - - _renderUpload: function (files) { - return this._renderTemplate( - this.options.uploadTemplate, - files - ); - }, - - _renderDownload: function (files) { - return this._renderTemplate( - this.options.downloadTemplate, - files - ).find('a[download]').each(this._enableDragToDesktop).end(); - }, - - _startHandler: function (e) { - e.preventDefault(); - var button = $(e.currentTarget), - template = button.closest('.template-upload'), - data = template.data('data'); - button.prop('disabled', true); - if (data && data.submit) { - data.submit(); - } - }, - - _cancelHandler: function (e) { - e.preventDefault(); - var template = $(e.currentTarget) - .closest('.template-upload,.template-download'), - data = template.data('data') || {}; - data.context = data.context || template; - if (data.abort) { - data.abort(); - } else { - data.errorThrown = 'abort'; - this._trigger('fail', e, data); - } - }, - - _deleteHandler: function (e) { - e.preventDefault(); - var button = $(e.currentTarget); - this._trigger('destroy', e, $.extend({ - context: button.closest('.template-download'), - type: 'DELETE' - }, button.data())); - }, - - _forceReflow: function (node) { - return $.support.transition && node.length && - node[0].offsetWidth; - }, - - _transition: function (node) { - var dfd = $.Deferred(); - if ($.support.transition && node.hasClass('fade') && node.is(':visible')) { - node.bind( - $.support.transition.end, - function (e) { - // Make sure we don't respond to other transitions events - // in the container element, e.g. from button elements: - if (e.target === node[0]) { - node.unbind($.support.transition.end); - dfd.resolveWith(node); - } - } - ).toggleClass('in'); - } else { - node.toggleClass('in'); - dfd.resolveWith(node); - } - return dfd; - }, - - _initButtonBarEventHandlers: function () { - var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'), - filesList = this.options.filesContainer; - this._on(fileUploadButtonBar.find('.start'), { - click: function (e) { - e.preventDefault(); - filesList.find('.start').click(); - } - }); - this._on(fileUploadButtonBar.find('.cancel'), { - click: function (e) { - e.preventDefault(); - filesList.find('.cancel').click(); - } - }); - this._on(fileUploadButtonBar.find('.delete'), { - click: function (e) { - e.preventDefault(); - filesList.find('.toggle:checked') - .closest('.template-download') - .find('.delete').click(); - fileUploadButtonBar.find('.toggle') - .prop('checked', false); - } - }); - this._on(fileUploadButtonBar.find('.toggle'), { - change: function (e) { - filesList.find('.toggle').prop( - 'checked', - $(e.currentTarget).is(':checked') - ); - } - }); - }, - - _destroyButtonBarEventHandlers: function () { - this._off( - this.element.find('.fileupload-buttonbar') - .find('.start, .cancel, .delete'), - 'click' - ); - this._off( - this.element.find('.fileupload-buttonbar .toggle'), - 'change.' - ); - }, - - _initEventHandlers: function () { - this._super(); - this._on(this.options.filesContainer, { - 'click .start': this._startHandler, - 'click .cancel': this._cancelHandler, - 'click .delete': this._deleteHandler - }); - this._initButtonBarEventHandlers(); - }, - - _destroyEventHandlers: function () { - this._destroyButtonBarEventHandlers(); - this._off(this.options.filesContainer, 'click'); - this._super(); - }, - - _enableFileInputButton: function () { - this.element.find('.fileinput-button input') - .prop('disabled', false) - .parent().removeClass('disabled'); - }, - - _disableFileInputButton: function () { - this.element.find('.fileinput-button input') - .prop('disabled', true) - .parent().addClass('disabled'); - }, - - _initTemplates: function () { - var options = this.options; - options.templatesContainer = this.document[0].createElement( - options.filesContainer.prop('nodeName') - ); - if (tmpl) { - if (options.uploadTemplateId) { - options.uploadTemplate = tmpl(options.uploadTemplateId); - } - if (options.downloadTemplateId) { - options.downloadTemplate = tmpl(options.downloadTemplateId); - } - } - }, - - _initFilesContainer: function () { - var options = this.options; - if (options.filesContainer === undefined) { - options.filesContainer = this.element.find('.files'); - } else if (!(options.filesContainer instanceof $)) { - options.filesContainer = $(options.filesContainer); - } - }, - - _initSpecialOptions: function () { - this._super(); - this._initFilesContainer(); - this._initTemplates(); - }, - - _create: function () { - this._super(); - this._resetFinishedDeferreds(); - if (!$.support.fileInput) { - this._disableFileInputButton(); - } - }, - - enable: function () { - var wasDisabled = false; - if (this.options.disabled) { - wasDisabled = true; - } - this._super(); - if (wasDisabled) { - this.element.find('input, button').prop('disabled', false); - this._enableFileInputButton(); - } - }, - - disable: function () { - if (!this.options.disabled) { - this.element.find('input, button').prop('disabled', true); - this._disableFileInputButton(); - } - this._super(); - } - - }); - -})); diff --git a/library/jqupload/js/jquery.fileupload-validate.js b/library/jqupload/js/jquery.fileupload-validate.js deleted file mode 100644 index f93a18fa2..000000000 --- a/library/jqupload/js/jquery.fileupload-validate.js +++ /dev/null @@ -1,119 +0,0 @@ -/* - * jQuery File Upload Validation Plugin 1.1.2 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2013, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -/* global define, window */ - -(function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define([ - 'jquery', - './jquery.fileupload-process' - ], factory); - } else { - // Browser globals: - factory( - window.jQuery - ); - } -}(function ($) { - 'use strict'; - - // Append to the default processQueue: - $.blueimp.fileupload.prototype.options.processQueue.push( - { - action: 'validate', - // Always trigger this action, - // even if the previous action was rejected: - always: true, - // Options taken from the global options map: - acceptFileTypes: '@', - maxFileSize: '@', - minFileSize: '@', - maxNumberOfFiles: '@', - disabled: '@disableValidation' - } - ); - - // The File Upload Validation plugin extends the fileupload widget - // with file validation functionality: - $.widget('blueimp.fileupload', $.blueimp.fileupload, { - - options: { - /* - // The regular expression for allowed file types, matches - // against either file type or file name: - acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i, - // The maximum allowed file size in bytes: - maxFileSize: 10000000, // 10 MB - // The minimum allowed file size in bytes: - minFileSize: undefined, // No minimal file size - // The limit of files to be uploaded: - maxNumberOfFiles: 10, - */ - - // Function returning the current number of files, - // has to be overriden for maxNumberOfFiles validation: - getNumberOfFiles: $.noop, - - // Error and info messages: - messages: { - maxNumberOfFiles: 'Maximum number of files exceeded', - acceptFileTypes: 'File type not allowed', - maxFileSize: 'File is too large', - minFileSize: 'File is too small' - } - }, - - processActions: { - - validate: function (data, options) { - if (options.disabled) { - return data; - } - var dfd = $.Deferred(), - settings = this.options, - file = data.files[data.index], - fileSize; - if (options.minFileSize || options.maxFileSize) { - fileSize = file.size; - } - if ($.type(options.maxNumberOfFiles) === 'number' && - (settings.getNumberOfFiles() || 0) + data.files.length > - options.maxNumberOfFiles) { - file.error = settings.i18n('maxNumberOfFiles'); - } else if (options.acceptFileTypes && - !(options.acceptFileTypes.test(file.type) || - options.acceptFileTypes.test(file.name))) { - file.error = settings.i18n('acceptFileTypes'); - } else if (fileSize > options.maxFileSize) { - file.error = settings.i18n('maxFileSize'); - } else if ($.type(fileSize) === 'number' && - fileSize < options.minFileSize) { - file.error = settings.i18n('minFileSize'); - } else { - delete file.error; - } - if (file.error || data.files.error) { - data.files.error = true; - dfd.rejectWith(this, [data]); - } else { - dfd.resolveWith(this, [data]); - } - return dfd.promise(); - } - - } - - }); - -})); diff --git a/library/jqupload/js/jquery.fileupload-video.js b/library/jqupload/js/jquery.fileupload-video.js deleted file mode 100644 index 3764b27a2..000000000 --- a/library/jqupload/js/jquery.fileupload-video.js +++ /dev/null @@ -1,106 +0,0 @@ -/* - * jQuery File Upload Video Preview Plugin 1.0.3 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2013, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -/* jshint nomen:false */ -/* global define, window, document */ - -(function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define([ - 'jquery', - 'load-image', - './jquery.fileupload-process' - ], factory); - } else { - // Browser globals: - factory( - window.jQuery, - window.loadImage - ); - } -}(function ($, loadImage) { - 'use strict'; - - // Prepend to the default processQueue: - $.blueimp.fileupload.prototype.options.processQueue.unshift( - { - action: 'loadVideo', - // Use the action as prefix for the "@" options: - prefix: true, - fileTypes: '@', - maxFileSize: '@', - disabled: '@disableVideoPreview' - }, - { - action: 'setVideo', - name: '@videoPreviewName', - disabled: '@disableVideoPreview' - } - ); - - // The File Upload Video Preview plugin extends the fileupload widget - // with video preview functionality: - $.widget('blueimp.fileupload', $.blueimp.fileupload, { - - options: { - // The regular expression for the types of video files to load, - // matched against the file type: - loadVideoFileTypes: /^video\/.*$/ - }, - - _videoElement: document.createElement('video'), - - processActions: { - - // Loads the video file given via data.files and data.index - // as video element if the browser supports playing it. - // Accepts the options fileTypes (regular expression) - // and maxFileSize (integer) to limit the files to load: - loadVideo: function (data, options) { - if (options.disabled) { - return data; - } - var file = data.files[data.index], - url, - video; - if (this._videoElement.canPlayType && - this._videoElement.canPlayType(file.type) && - ($.type(options.maxFileSize) !== 'number' || - file.size <= options.maxFileSize) && - (!options.fileTypes || - options.fileTypes.test(file.type))) { - url = loadImage.createObjectURL(file); - if (url) { - video = this._videoElement.cloneNode(false); - video.src = url; - video.controls = true; - data.video = video; - return data; - } - } - return data; - }, - - // Sets the video element as a property of the file object: - setVideo: function (data, options) { - if (data.video && !options.disabled) { - data.files[data.index][options.name || 'preview'] = data.video; - } - return data; - } - - } - - }); - -})); diff --git a/library/jqupload/js/jquery.fileupload.js b/library/jqupload/js/jquery.fileupload.js deleted file mode 100644 index b52af0654..000000000 --- a/library/jqupload/js/jquery.fileupload.js +++ /dev/null @@ -1,1420 +0,0 @@ -/* - * jQuery File Upload Plugin 5.40.0 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2010, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -/* jshint nomen:false */ -/* global define, window, document, location, Blob, FormData */ - -(function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define([ - 'jquery', - 'jquery.ui.widget' - ], factory); - } else { - // Browser globals: - factory(window.jQuery); - } -}(function ($) { - 'use strict'; - - // Detect file input support, based on - // http://viljamis.com/blog/2012/file-upload-support-on-mobile/ - $.support.fileInput = !(new RegExp( - // Handle devices which give false positives for the feature detection: - '(Android (1\\.[0156]|2\\.[01]))' + - '|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' + - '|(w(eb)?OSBrowser)|(webOS)' + - '|(Kindle/(1\\.0|2\\.[05]|3\\.0))' - ).test(window.navigator.userAgent) || - // Feature detection for all other devices: - $('').prop('disabled')); - - // The FileReader API is not actually used, but works as feature detection, - // as some Safari versions (5?) support XHR file uploads via the FormData API, - // but not non-multipart XHR file uploads. - // window.XMLHttpRequestUpload is not available on IE10, so we check for - // window.ProgressEvent instead to detect XHR2 file upload capability: - $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader); - $.support.xhrFormDataFileUpload = !!window.FormData; - - // Detect support for Blob slicing (required for chunked uploads): - $.support.blobSlice = window.Blob && (Blob.prototype.slice || - Blob.prototype.webkitSlice || Blob.prototype.mozSlice); - - // The fileupload widget listens for change events on file input fields defined - // via fileInput setting and paste or drop events of the given dropZone. - // In addition to the default jQuery Widget methods, the fileupload widget - // exposes the "add" and "send" methods, to add or directly send files using - // the fileupload API. - // By default, files added via file input selection, paste, drag & drop or - // "add" method are uploaded immediately, but it is possible to override - // the "add" callback option to queue file uploads. - $.widget('blueimp.fileupload', { - - options: { - // The drop target element(s), by the default the complete document. - // Set to null to disable drag & drop support: - dropZone: $(document), - // The paste target element(s), by the default the complete document. - // Set to null to disable paste support: - pasteZone: $(document), - // The file input field(s), that are listened to for change events. - // If undefined, it is set to the file input fields inside - // of the widget element on plugin initialization. - // Set to null to disable the change listener. - fileInput: undefined, - // By default, the file input field is replaced with a clone after - // each input field change event. This is required for iframe transport - // queues and allows change events to be fired for the same file - // selection, but can be disabled by setting the following option to false: - replaceFileInput: true, - // The parameter name for the file form data (the request argument name). - // If undefined or empty, the name property of the file input field is - // used, or "files[]" if the file input name property is also empty, - // can be a string or an array of strings: - paramName: undefined, - // By default, each file of a selection is uploaded using an individual - // request for XHR type uploads. Set to false to upload file - // selections in one request each: - singleFileUploads: true, - // To limit the number of files uploaded with one XHR request, - // set the following option to an integer greater than 0: - limitMultiFileUploads: undefined, - // The following option limits the number of files uploaded with one - // XHR request to keep the request size under or equal to the defined - // limit in bytes: - limitMultiFileUploadSize: undefined, - // Multipart file uploads add a number of bytes to each uploaded file, - // therefore the following option adds an overhead for each file used - // in the limitMultiFileUploadSize configuration: - limitMultiFileUploadSizeOverhead: 512, - // Set the following option to true to issue all file upload requests - // in a sequential order: - sequentialUploads: false, - // To limit the number of concurrent uploads, - // set the following option to an integer greater than 0: - limitConcurrentUploads: undefined, - // Set the following option to true to force iframe transport uploads: - forceIframeTransport: false, - // Set the following option to the location of a redirect url on the - // origin server, for cross-domain iframe transport uploads: - redirect: undefined, - // The parameter name for the redirect url, sent as part of the form - // data and set to 'redirect' if this option is empty: - redirectParamName: undefined, - // Set the following option to the location of a postMessage window, - // to enable postMessage transport uploads: - postMessage: undefined, - // By default, XHR file uploads are sent as multipart/form-data. - // The iframe transport is always using multipart/form-data. - // Set to false to enable non-multipart XHR uploads: - multipart: true, - // To upload large files in smaller chunks, set the following option - // to a preferred maximum chunk size. If set to 0, null or undefined, - // or the browser does not support the required Blob API, files will - // be uploaded as a whole. - maxChunkSize: undefined, - // When a non-multipart upload or a chunked multipart upload has been - // aborted, this option can be used to resume the upload by setting - // it to the size of the already uploaded bytes. This option is most - // useful when modifying the options object inside of the "add" or - // "send" callbacks, as the options are cloned for each file upload. - uploadedBytes: undefined, - // By default, failed (abort or error) file uploads are removed from the - // global progress calculation. Set the following option to false to - // prevent recalculating the global progress data: - recalculateProgress: true, - // Interval in milliseconds to calculate and trigger progress events: - progressInterval: 100, - // Interval in milliseconds to calculate progress bitrate: - bitrateInterval: 500, - // By default, uploads are started automatically when adding files: - autoUpload: true, - - // Error and info messages: - messages: { - uploadedBytes: 'Uploaded bytes exceed file size' - }, - - // Translation function, gets the message key to be translated - // and an object with context specific data as arguments: - i18n: function (message, context) { - message = this.messages[message] || message.toString(); - if (context) { - $.each(context, function (key, value) { - message = message.replace('{' + key + '}', value); - }); - } - return message; - }, - - // Additional form data to be sent along with the file uploads can be set - // using this option, which accepts an array of objects with name and - // value properties, a function returning such an array, a FormData - // object (for XHR file uploads), or a simple object. - // The form of the first fileInput is given as parameter to the function: - formData: function (form) { - return form.serializeArray(); - }, - - // The add callback is invoked as soon as files are added to the fileupload - // widget (via file input selection, drag & drop, paste or add API call). - // If the singleFileUploads option is enabled, this callback will be - // called once for each file in the selection for XHR file uploads, else - // once for each file selection. - // - // The upload starts when the submit method is invoked on the data parameter. - // The data object contains a files property holding the added files - // and allows you to override plugin options as well as define ajax settings. - // - // Listeners for this callback can also be bound the following way: - // .bind('fileuploadadd', func); - // - // data.submit() returns a Promise object and allows to attach additional - // handlers using jQuery's Deferred callbacks: - // data.submit().done(func).fail(func).always(func); - add: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - if (data.autoUpload || (data.autoUpload !== false && - $(this).fileupload('option', 'autoUpload'))) { - data.process().done(function () { - data.submit(); - }); - } - }, - - // Other callbacks: - - // Callback for the submit event of each file upload: - // submit: function (e, data) {}, // .bind('fileuploadsubmit', func); - - // Callback for the start of each file upload request: - // send: function (e, data) {}, // .bind('fileuploadsend', func); - - // Callback for successful uploads: - // done: function (e, data) {}, // .bind('fileuploaddone', func); - - // Callback for failed (abort or error) uploads: - // fail: function (e, data) {}, // .bind('fileuploadfail', func); - - // Callback for completed (success, abort or error) requests: - // always: function (e, data) {}, // .bind('fileuploadalways', func); - - // Callback for upload progress events: - // progress: function (e, data) {}, // .bind('fileuploadprogress', func); - - // Callback for global upload progress events: - // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func); - - // Callback for uploads start, equivalent to the global ajaxStart event: - // start: function (e) {}, // .bind('fileuploadstart', func); - - // Callback for uploads stop, equivalent to the global ajaxStop event: - // stop: function (e) {}, // .bind('fileuploadstop', func); - - // Callback for change events of the fileInput(s): - // change: function (e, data) {}, // .bind('fileuploadchange', func); - - // Callback for paste events to the pasteZone(s): - // paste: function (e, data) {}, // .bind('fileuploadpaste', func); - - // Callback for drop events of the dropZone(s): - // drop: function (e, data) {}, // .bind('fileuploaddrop', func); - - // Callback for dragover events of the dropZone(s): - // dragover: function (e) {}, // .bind('fileuploaddragover', func); - - // Callback for the start of each chunk upload request: - // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func); - - // Callback for successful chunk uploads: - // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func); - - // Callback for failed (abort or error) chunk uploads: - // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func); - - // Callback for completed (success, abort or error) chunk upload requests: - // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func); - - // The plugin options are used as settings object for the ajax calls. - // The following are jQuery ajax settings required for the file uploads: - processData: false, - contentType: false, - cache: false - }, - - // A list of options that require reinitializing event listeners and/or - // special initialization code: - _specialOptions: [ - 'fileInput', - 'dropZone', - 'pasteZone', - 'multipart', - 'forceIframeTransport' - ], - - _blobSlice: $.support.blobSlice && function () { - var slice = this.slice || this.webkitSlice || this.mozSlice; - return slice.apply(this, arguments); - }, - - _BitrateTimer: function () { - this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime()); - this.loaded = 0; - this.bitrate = 0; - this.getBitrate = function (now, loaded, interval) { - var timeDiff = now - this.timestamp; - if (!this.bitrate || !interval || timeDiff > interval) { - this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8; - this.loaded = loaded; - this.timestamp = now; - } - return this.bitrate; - }; - }, - - _isXHRUpload: function (options) { - return !options.forceIframeTransport && - ((!options.multipart && $.support.xhrFileUpload) || - $.support.xhrFormDataFileUpload); - }, - - _getFormData: function (options) { - var formData; - if ($.type(options.formData) === 'function') { - return options.formData(options.form); - } - if ($.isArray(options.formData)) { - return options.formData; - } - if ($.type(options.formData) === 'object') { - formData = []; - $.each(options.formData, function (name, value) { - formData.push({name: name, value: value}); - }); - return formData; - } - return []; - }, - - _getTotal: function (files) { - var total = 0; - $.each(files, function (index, file) { - total += file.size || 1; - }); - return total; - }, - - _initProgressObject: function (obj) { - var progress = { - loaded: 0, - total: 0, - bitrate: 0 - }; - if (obj._progress) { - $.extend(obj._progress, progress); - } else { - obj._progress = progress; - } - }, - - _initResponseObject: function (obj) { - var prop; - if (obj._response) { - for (prop in obj._response) { - if (obj._response.hasOwnProperty(prop)) { - delete obj._response[prop]; - } - } - } else { - obj._response = {}; - } - }, - - _onProgress: function (e, data) { - if (e.lengthComputable) { - var now = ((Date.now) ? Date.now() : (new Date()).getTime()), - loaded; - if (data._time && data.progressInterval && - (now - data._time < data.progressInterval) && - e.loaded !== e.total) { - return; - } - data._time = now; - loaded = Math.floor( - e.loaded / e.total * (data.chunkSize || data._progress.total) - ) + (data.uploadedBytes || 0); - // Add the difference from the previously loaded state - // to the global loaded counter: - this._progress.loaded += (loaded - data._progress.loaded); - this._progress.bitrate = this._bitrateTimer.getBitrate( - now, - this._progress.loaded, - data.bitrateInterval - ); - data._progress.loaded = data.loaded = loaded; - data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate( - now, - loaded, - data.bitrateInterval - ); - // Trigger a custom progress event with a total data property set - // to the file size(s) of the current upload and a loaded data - // property calculated accordingly: - this._trigger( - 'progress', - $.Event('progress', {delegatedEvent: e}), - data - ); - // Trigger a global progress event for all current file uploads, - // including ajax calls queued for sequential file uploads: - this._trigger( - 'progressall', - $.Event('progressall', {delegatedEvent: e}), - this._progress - ); - } - }, - - _initProgressListener: function (options) { - var that = this, - xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr(); - // Accesss to the native XHR object is required to add event listeners - // for the upload progress event: - if (xhr.upload) { - $(xhr.upload).bind('progress', function (e) { - var oe = e.originalEvent; - // Make sure the progress event properties get copied over: - e.lengthComputable = oe.lengthComputable; - e.loaded = oe.loaded; - e.total = oe.total; - that._onProgress(e, options); - }); - options.xhr = function () { - return xhr; - }; - } - }, - - _isInstanceOf: function (type, obj) { - // Cross-frame instanceof check - return Object.prototype.toString.call(obj) === '[object ' + type + ']'; - }, - - _initXHRData: function (options) { - var that = this, - formData, - file = options.files[0], - // Ignore non-multipart setting if not supported: - multipart = options.multipart || !$.support.xhrFileUpload, - paramName = $.type(options.paramName) === 'array' ? - options.paramName[0] : options.paramName; - options.headers = $.extend({}, options.headers); - if (options.contentRange) { - options.headers['Content-Range'] = options.contentRange; - } - if (!multipart || options.blob || !this._isInstanceOf('File', file)) { - options.headers['Content-Disposition'] = 'attachment; filename="' + - encodeURI(file.name) + '"'; - } - if (!multipart) { - options.contentType = file.type || 'application/octet-stream'; - options.data = options.blob || file; - } else if ($.support.xhrFormDataFileUpload) { - if (options.postMessage) { - // window.postMessage does not allow sending FormData - // objects, so we just add the File/Blob objects to - // the formData array and let the postMessage window - // create the FormData object out of this array: - formData = this._getFormData(options); - if (options.blob) { - formData.push({ - name: paramName, - value: options.blob - }); - } else { - $.each(options.files, function (index, file) { - formData.push({ - name: ($.type(options.paramName) === 'array' && - options.paramName[index]) || paramName, - value: file - }); - }); - } - } else { - if (that._isInstanceOf('FormData', options.formData)) { - formData = options.formData; - } else { - formData = new FormData(); - $.each(this._getFormData(options), function (index, field) { - formData.append(field.name, field.value); - }); - } - if (options.blob) { - formData.append(paramName, options.blob, file.name); - } else { - $.each(options.files, function (index, file) { - // This check allows the tests to run with - // dummy objects: - if (that._isInstanceOf('File', file) || - that._isInstanceOf('Blob', file)) { - formData.append( - ($.type(options.paramName) === 'array' && - options.paramName[index]) || paramName, - file, - file.uploadName || file.name - ); - } - }); - } - } - options.data = formData; - } - // Blob reference is not needed anymore, free memory: - options.blob = null; - }, - - _initIframeSettings: function (options) { - var targetHost = $('').prop('href', options.url).prop('host'); - // Setting the dataType to iframe enables the iframe transport: - options.dataType = 'iframe ' + (options.dataType || ''); - // The iframe transport accepts a serialized array as form data: - options.formData = this._getFormData(options); - // Add redirect url to form data on cross-domain uploads: - if (options.redirect && targetHost && targetHost !== location.host) { - options.formData.push({ - name: options.redirectParamName || 'redirect', - value: options.redirect - }); - } - }, - - _initDataSettings: function (options) { - if (this._isXHRUpload(options)) { - if (!this._chunkedUpload(options, true)) { - if (!options.data) { - this._initXHRData(options); - } - this._initProgressListener(options); - } - if (options.postMessage) { - // Setting the dataType to postmessage enables the - // postMessage transport: - options.dataType = 'postmessage ' + (options.dataType || ''); - } - } else { - this._initIframeSettings(options); - } - }, - - _getParamName: function (options) { - var fileInput = $(options.fileInput), - paramName = options.paramName; - if (!paramName) { - paramName = []; - fileInput.each(function () { - var input = $(this), - name = input.prop('name') || 'files[]', - i = (input.prop('files') || [1]).length; - while (i) { - paramName.push(name); - i -= 1; - } - }); - if (!paramName.length) { - paramName = [fileInput.prop('name') || 'files[]']; - } - } else if (!$.isArray(paramName)) { - paramName = [paramName]; - } - return paramName; - }, - - _initFormSettings: function (options) { - // Retrieve missing options from the input field and the - // associated form, if available: - if (!options.form || !options.form.length) { - options.form = $(options.fileInput.prop('form')); - // If the given file input doesn't have an associated form, - // use the default widget file input's form: - if (!options.form.length) { - options.form = $(this.options.fileInput.prop('form')); - } - } - options.paramName = this._getParamName(options); - if (!options.url) { - options.url = options.form.prop('action') || location.href; - } - // The HTTP request method must be "POST" or "PUT": - options.type = (options.type || - ($.type(options.form.prop('method')) === 'string' && - options.form.prop('method')) || '' - ).toUpperCase(); - if (options.type !== 'POST' && options.type !== 'PUT' && - options.type !== 'PATCH') { - options.type = 'POST'; - } - if (!options.formAcceptCharset) { - options.formAcceptCharset = options.form.attr('accept-charset'); - } - }, - - _getAJAXSettings: function (data) { - var options = $.extend({}, this.options, data); - this._initFormSettings(options); - this._initDataSettings(options); - return options; - }, - - // jQuery 1.6 doesn't provide .state(), - // while jQuery 1.8+ removed .isRejected() and .isResolved(): - _getDeferredState: function (deferred) { - if (deferred.state) { - return deferred.state(); - } - if (deferred.isResolved()) { - return 'resolved'; - } - if (deferred.isRejected()) { - return 'rejected'; - } - return 'pending'; - }, - - // Maps jqXHR callbacks to the equivalent - // methods of the given Promise object: - _enhancePromise: function (promise) { - promise.success = promise.done; - promise.error = promise.fail; - promise.complete = promise.always; - return promise; - }, - - // Creates and returns a Promise object enhanced with - // the jqXHR methods abort, success, error and complete: - _getXHRPromise: function (resolveOrReject, context, args) { - var dfd = $.Deferred(), - promise = dfd.promise(); - context = context || this.options.context || promise; - if (resolveOrReject === true) { - dfd.resolveWith(context, args); - } else if (resolveOrReject === false) { - dfd.rejectWith(context, args); - } - promise.abort = dfd.promise; - return this._enhancePromise(promise); - }, - - // Adds convenience methods to the data callback argument: - _addConvenienceMethods: function (e, data) { - var that = this, - getPromise = function (args) { - return $.Deferred().resolveWith(that, args).promise(); - }; - data.process = function (resolveFunc, rejectFunc) { - if (resolveFunc || rejectFunc) { - data._processQueue = this._processQueue = - (this._processQueue || getPromise([this])).pipe( - function () { - if (data.errorThrown) { - return $.Deferred() - .rejectWith(that, [data]).promise(); - } - return getPromise(arguments); - } - ).pipe(resolveFunc, rejectFunc); - } - return this._processQueue || getPromise([this]); - }; - data.submit = function () { - if (this.state() !== 'pending') { - data.jqXHR = this.jqXHR = - (that._trigger( - 'submit', - $.Event('submit', {delegatedEvent: e}), - this - ) !== false) && that._onSend(e, this); - } - return this.jqXHR || that._getXHRPromise(); - }; - data.abort = function () { - if (this.jqXHR) { - return this.jqXHR.abort(); - } - this.errorThrown = 'abort'; - that._trigger('fail', null, this); - return that._getXHRPromise(false); - }; - data.state = function () { - if (this.jqXHR) { - return that._getDeferredState(this.jqXHR); - } - if (this._processQueue) { - return that._getDeferredState(this._processQueue); - } - }; - data.processing = function () { - return !this.jqXHR && this._processQueue && that - ._getDeferredState(this._processQueue) === 'pending'; - }; - data.progress = function () { - return this._progress; - }; - data.response = function () { - return this._response; - }; - }, - - // Parses the Range header from the server response - // and returns the uploaded bytes: - _getUploadedBytes: function (jqXHR) { - var range = jqXHR.getResponseHeader('Range'), - parts = range && range.split('-'), - upperBytesPos = parts && parts.length > 1 && - parseInt(parts[1], 10); - return upperBytesPos && upperBytesPos + 1; - }, - - // Uploads a file in multiple, sequential requests - // by splitting the file up in multiple blob chunks. - // If the second parameter is true, only tests if the file - // should be uploaded in chunks, but does not invoke any - // upload requests: - _chunkedUpload: function (options, testOnly) { - options.uploadedBytes = options.uploadedBytes || 0; - var that = this, - file = options.files[0], - fs = file.size, - ub = options.uploadedBytes, - mcs = options.maxChunkSize || fs, - slice = this._blobSlice, - dfd = $.Deferred(), - promise = dfd.promise(), - jqXHR, - upload; - if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) || - options.data) { - return false; - } - if (testOnly) { - return true; - } - if (ub >= fs) { - file.error = options.i18n('uploadedBytes'); - return this._getXHRPromise( - false, - options.context, - [null, 'error', file.error] - ); - } - // The chunk upload method: - upload = function () { - // Clone the options object for each chunk upload: - var o = $.extend({}, options), - currentLoaded = o._progress.loaded; - o.blob = slice.call( - file, - ub, - ub + mcs, - file.type - ); - // Store the current chunk size, as the blob itself - // will be dereferenced after data processing: - o.chunkSize = o.blob.size; - // Expose the chunk bytes position range: - o.contentRange = 'bytes ' + ub + '-' + - (ub + o.chunkSize - 1) + '/' + fs; - // Process the upload data (the blob and potential form data): - that._initXHRData(o); - // Add progress listeners for this chunk upload: - that._initProgressListener(o); - jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) || - that._getXHRPromise(false, o.context)) - .done(function (result, textStatus, jqXHR) { - ub = that._getUploadedBytes(jqXHR) || - (ub + o.chunkSize); - // Create a progress event if no final progress event - // with loaded equaling total has been triggered - // for this chunk: - if (currentLoaded + o.chunkSize - o._progress.loaded) { - that._onProgress($.Event('progress', { - lengthComputable: true, - loaded: ub - o.uploadedBytes, - total: ub - o.uploadedBytes - }), o); - } - options.uploadedBytes = o.uploadedBytes = ub; - o.result = result; - o.textStatus = textStatus; - o.jqXHR = jqXHR; - that._trigger('chunkdone', null, o); - that._trigger('chunkalways', null, o); - if (ub < fs) { - // File upload not yet complete, - // continue with the next chunk: - upload(); - } else { - dfd.resolveWith( - o.context, - [result, textStatus, jqXHR] - ); - } - }) - .fail(function (jqXHR, textStatus, errorThrown) { - o.jqXHR = jqXHR; - o.textStatus = textStatus; - o.errorThrown = errorThrown; - that._trigger('chunkfail', null, o); - that._trigger('chunkalways', null, o); - dfd.rejectWith( - o.context, - [jqXHR, textStatus, errorThrown] - ); - }); - }; - this._enhancePromise(promise); - promise.abort = function () { - return jqXHR.abort(); - }; - upload(); - return promise; - }, - - _beforeSend: function (e, data) { - if (this._active === 0) { - // the start callback is triggered when an upload starts - // and no other uploads are currently running, - // equivalent to the global ajaxStart event: - this._trigger('start'); - // Set timer for global bitrate progress calculation: - this._bitrateTimer = new this._BitrateTimer(); - // Reset the global progress values: - this._progress.loaded = this._progress.total = 0; - this._progress.bitrate = 0; - } - // Make sure the container objects for the .response() and - // .progress() methods on the data object are available - // and reset to their initial state: - this._initResponseObject(data); - this._initProgressObject(data); - data._progress.loaded = data.loaded = data.uploadedBytes || 0; - data._progress.total = data.total = this._getTotal(data.files) || 1; - data._progress.bitrate = data.bitrate = 0; - this._active += 1; - // Initialize the global progress values: - this._progress.loaded += data.loaded; - this._progress.total += data.total; - }, - - _onDone: function (result, textStatus, jqXHR, options) { - var total = options._progress.total, - response = options._response; - if (options._progress.loaded < total) { - // Create a progress event if no final progress event - // with loaded equaling total has been triggered: - this._onProgress($.Event('progress', { - lengthComputable: true, - loaded: total, - total: total - }), options); - } - response.result = options.result = result; - response.textStatus = options.textStatus = textStatus; - response.jqXHR = options.jqXHR = jqXHR; - this._trigger('done', null, options); - }, - - _onFail: function (jqXHR, textStatus, errorThrown, options) { - var response = options._response; - if (options.recalculateProgress) { - // Remove the failed (error or abort) file upload from - // the global progress calculation: - this._progress.loaded -= options._progress.loaded; - this._progress.total -= options._progress.total; - } - response.jqXHR = options.jqXHR = jqXHR; - response.textStatus = options.textStatus = textStatus; - response.errorThrown = options.errorThrown = errorThrown; - this._trigger('fail', null, options); - }, - - _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) { - // jqXHRorResult, textStatus and jqXHRorError are added to the - // options object via done and fail callbacks - this._trigger('always', null, options); - }, - - _onSend: function (e, data) { - if (!data.submit) { - this._addConvenienceMethods(e, data); - } - var that = this, - jqXHR, - aborted, - slot, - pipe, - options = that._getAJAXSettings(data), - send = function () { - that._sending += 1; - // Set timer for bitrate progress calculation: - options._bitrateTimer = new that._BitrateTimer(); - jqXHR = jqXHR || ( - ((aborted || that._trigger( - 'send', - $.Event('send', {delegatedEvent: e}), - options - ) === false) && - that._getXHRPromise(false, options.context, aborted)) || - that._chunkedUpload(options) || $.ajax(options) - ).done(function (result, textStatus, jqXHR) { - that._onDone(result, textStatus, jqXHR, options); - }).fail(function (jqXHR, textStatus, errorThrown) { - that._onFail(jqXHR, textStatus, errorThrown, options); - }).always(function (jqXHRorResult, textStatus, jqXHRorError) { - that._onAlways( - jqXHRorResult, - textStatus, - jqXHRorError, - options - ); - that._sending -= 1; - that._active -= 1; - if (options.limitConcurrentUploads && - options.limitConcurrentUploads > that._sending) { - // Start the next queued upload, - // that has not been aborted: - var nextSlot = that._slots.shift(); - while (nextSlot) { - if (that._getDeferredState(nextSlot) === 'pending') { - nextSlot.resolve(); - break; - } - nextSlot = that._slots.shift(); - } - } - if (that._active === 0) { - // The stop callback is triggered when all uploads have - // been completed, equivalent to the global ajaxStop event: - that._trigger('stop'); - } - }); - return jqXHR; - }; - this._beforeSend(e, options); - if (this.options.sequentialUploads || - (this.options.limitConcurrentUploads && - this.options.limitConcurrentUploads <= this._sending)) { - if (this.options.limitConcurrentUploads > 1) { - slot = $.Deferred(); - this._slots.push(slot); - pipe = slot.pipe(send); - } else { - this._sequence = this._sequence.pipe(send, send); - pipe = this._sequence; - } - // Return the piped Promise object, enhanced with an abort method, - // which is delegated to the jqXHR object of the current upload, - // and jqXHR callbacks mapped to the equivalent Promise methods: - pipe.abort = function () { - aborted = [undefined, 'abort', 'abort']; - if (!jqXHR) { - if (slot) { - slot.rejectWith(options.context, aborted); - } - return send(); - } - return jqXHR.abort(); - }; - return this._enhancePromise(pipe); - } - return send(); - }, - - _onAdd: function (e, data) { - var that = this, - result = true, - options = $.extend({}, this.options, data), - files = data.files, - filesLength = files.length, - limit = options.limitMultiFileUploads, - limitSize = options.limitMultiFileUploadSize, - overhead = options.limitMultiFileUploadSizeOverhead, - batchSize = 0, - paramName = this._getParamName(options), - paramNameSet, - paramNameSlice, - fileSet, - i, - j = 0; - if (limitSize && (!filesLength || files[0].size === undefined)) { - limitSize = undefined; - } - if (!(options.singleFileUploads || limit || limitSize) || - !this._isXHRUpload(options)) { - fileSet = [files]; - paramNameSet = [paramName]; - } else if (!(options.singleFileUploads || limitSize) && limit) { - fileSet = []; - paramNameSet = []; - for (i = 0; i < filesLength; i += limit) { - fileSet.push(files.slice(i, i + limit)); - paramNameSlice = paramName.slice(i, i + limit); - if (!paramNameSlice.length) { - paramNameSlice = paramName; - } - paramNameSet.push(paramNameSlice); - } - } else if (!options.singleFileUploads && limitSize) { - fileSet = []; - paramNameSet = []; - for (i = 0; i < filesLength; i = i + 1) { - batchSize += files[i].size + overhead; - if (i + 1 === filesLength || - ((batchSize + files[i + 1].size + overhead) > limitSize) || - (limit && i + 1 - j >= limit)) { - fileSet.push(files.slice(j, i + 1)); - paramNameSlice = paramName.slice(j, i + 1); - if (!paramNameSlice.length) { - paramNameSlice = paramName; - } - paramNameSet.push(paramNameSlice); - j = i + 1; - batchSize = 0; - } - } - } else { - paramNameSet = paramName; - } - data.originalFiles = files; - $.each(fileSet || files, function (index, element) { - var newData = $.extend({}, data); - newData.files = fileSet ? element : [element]; - newData.paramName = paramNameSet[index]; - that._initResponseObject(newData); - that._initProgressObject(newData); - that._addConvenienceMethods(e, newData); - result = that._trigger( - 'add', - $.Event('add', {delegatedEvent: e}), - newData - ); - return result; - }); - return result; - }, - - _replaceFileInput: function (input) { - var inputClone = input.clone(true); - $('
    ').append(inputClone)[0].reset(); - // Detaching allows to insert the fileInput on another form - // without loosing the file input value: - input.after(inputClone).detach(); - // Avoid memory leaks with the detached file input: - $.cleanData(input.unbind('remove')); - // Replace the original file input element in the fileInput - // elements set with the clone, which has been copied including - // event handlers: - this.options.fileInput = this.options.fileInput.map(function (i, el) { - if (el === input[0]) { - return inputClone[0]; - } - return el; - }); - // If the widget has been initialized on the file input itself, - // override this.element with the file input clone: - if (input[0] === this.element[0]) { - this.element = inputClone; - } - }, - - _handleFileTreeEntry: function (entry, path) { - var that = this, - dfd = $.Deferred(), - errorHandler = function (e) { - if (e && !e.entry) { - e.entry = entry; - } - // Since $.when returns immediately if one - // Deferred is rejected, we use resolve instead. - // This allows valid files and invalid items - // to be returned together in one set: - dfd.resolve([e]); - }, - dirReader; - path = path || ''; - if (entry.isFile) { - if (entry._file) { - // Workaround for Chrome bug #149735 - entry._file.relativePath = path; - dfd.resolve(entry._file); - } else { - entry.file(function (file) { - file.relativePath = path; - dfd.resolve(file); - }, errorHandler); - } - } else if (entry.isDirectory) { - dirReader = entry.createReader(); - dirReader.readEntries(function (entries) { - that._handleFileTreeEntries( - entries, - path + entry.name + '/' - ).done(function (files) { - dfd.resolve(files); - }).fail(errorHandler); - }, errorHandler); - } else { - // Return an empy list for file system items - // other than files or directories: - dfd.resolve([]); - } - return dfd.promise(); - }, - - _handleFileTreeEntries: function (entries, path) { - var that = this; - return $.when.apply( - $, - $.map(entries, function (entry) { - return that._handleFileTreeEntry(entry, path); - }) - ).pipe(function () { - return Array.prototype.concat.apply( - [], - arguments - ); - }); - }, - - _getDroppedFiles: function (dataTransfer) { - dataTransfer = dataTransfer || {}; - var items = dataTransfer.items; - if (items && items.length && (items[0].webkitGetAsEntry || - items[0].getAsEntry)) { - return this._handleFileTreeEntries( - $.map(items, function (item) { - var entry; - if (item.webkitGetAsEntry) { - entry = item.webkitGetAsEntry(); - if (entry) { - // Workaround for Chrome bug #149735: - entry._file = item.getAsFile(); - } - return entry; - } - return item.getAsEntry(); - }) - ); - } - return $.Deferred().resolve( - $.makeArray(dataTransfer.files) - ).promise(); - }, - - _getSingleFileInputFiles: function (fileInput) { - fileInput = $(fileInput); - var entries = fileInput.prop('webkitEntries') || - fileInput.prop('entries'), - files, - value; - if (entries && entries.length) { - return this._handleFileTreeEntries(entries); - } - files = $.makeArray(fileInput.prop('files')); - if (!files.length) { - value = fileInput.prop('value'); - if (!value) { - return $.Deferred().resolve([]).promise(); - } - // If the files property is not available, the browser does not - // support the File API and we add a pseudo File object with - // the input value as name with path information removed: - files = [{name: value.replace(/^.*\\/, '')}]; - } else if (files[0].name === undefined && files[0].fileName) { - // File normalization for Safari 4 and Firefox 3: - $.each(files, function (index, file) { - file.name = file.fileName; - file.size = file.fileSize; - }); - } - return $.Deferred().resolve(files).promise(); - }, - - _getFileInputFiles: function (fileInput) { - if (!(fileInput instanceof $) || fileInput.length === 1) { - return this._getSingleFileInputFiles(fileInput); - } - return $.when.apply( - $, - $.map(fileInput, this._getSingleFileInputFiles) - ).pipe(function () { - return Array.prototype.concat.apply( - [], - arguments - ); - }); - }, - - _onChange: function (e) { - var that = this, - data = { - fileInput: $(e.target), - form: $(e.target.form) - }; - this._getFileInputFiles(data.fileInput).always(function (files) { - data.files = files; - if (that.options.replaceFileInput) { - that._replaceFileInput(data.fileInput); - } - if (that._trigger( - 'change', - $.Event('change', {delegatedEvent: e}), - data - ) !== false) { - that._onAdd(e, data); - } - }); - }, - - _onPaste: function (e) { - var items = e.originalEvent && e.originalEvent.clipboardData && - e.originalEvent.clipboardData.items, - data = {files: []}; - if (items && items.length) { - $.each(items, function (index, item) { - var file = item.getAsFile && item.getAsFile(); - if (file) { - data.files.push(file); - } - }); - if (this._trigger( - 'paste', - $.Event('paste', {delegatedEvent: e}), - data - ) !== false) { - this._onAdd(e, data); - } - } - }, - - _onDrop: function (e) { - e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer; - var that = this, - dataTransfer = e.dataTransfer, - data = {}; - if (dataTransfer && dataTransfer.files && dataTransfer.files.length) { - e.preventDefault(); - this._getDroppedFiles(dataTransfer).always(function (files) { - data.files = files; - if (that._trigger( - 'drop', - $.Event('drop', {delegatedEvent: e}), - data - ) !== false) { - that._onAdd(e, data); - } - }); - } - }, - - _onDragOver: function (e) { - e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer; - var dataTransfer = e.dataTransfer; - if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 && - this._trigger( - 'dragover', - $.Event('dragover', {delegatedEvent: e}) - ) !== false) { - e.preventDefault(); - dataTransfer.dropEffect = 'copy'; - } - }, - - _initEventHandlers: function () { - if (this._isXHRUpload(this.options)) { - this._on(this.options.dropZone, { - dragover: this._onDragOver, - drop: this._onDrop - }); - this._on(this.options.pasteZone, { - paste: this._onPaste - }); - } - if ($.support.fileInput) { - this._on(this.options.fileInput, { - change: this._onChange - }); - } - }, - - _destroyEventHandlers: function () { - this._off(this.options.dropZone, 'dragover drop'); - this._off(this.options.pasteZone, 'paste'); - this._off(this.options.fileInput, 'change'); - }, - - _setOption: function (key, value) { - var reinit = $.inArray(key, this._specialOptions) !== -1; - if (reinit) { - this._destroyEventHandlers(); - } - this._super(key, value); - if (reinit) { - this._initSpecialOptions(); - this._initEventHandlers(); - } - }, - - _initSpecialOptions: function () { - var options = this.options; - if (options.fileInput === undefined) { - options.fileInput = this.element.is('input[type="file"]') ? - this.element : this.element.find('input[type="file"]'); - } else if (!(options.fileInput instanceof $)) { - options.fileInput = $(options.fileInput); - } - if (!(options.dropZone instanceof $)) { - options.dropZone = $(options.dropZone); - } - if (!(options.pasteZone instanceof $)) { - options.pasteZone = $(options.pasteZone); - } - }, - - _getRegExp: function (str) { - var parts = str.split('/'), - modifiers = parts.pop(); - parts.shift(); - return new RegExp(parts.join('/'), modifiers); - }, - - _isRegExpOption: function (key, value) { - return key !== 'url' && $.type(value) === 'string' && - /^\/.*\/[igm]{0,3}$/.test(value); - }, - - _initDataAttributes: function () { - var that = this, - options = this.options; - // Initialize options set via HTML5 data-attributes: - $.each( - $(this.element[0].cloneNode(false)).data(), - function (key, value) { - if (that._isRegExpOption(key, value)) { - value = that._getRegExp(value); - } - options[key] = value; - } - ); - }, - - _create: function () { - this._initDataAttributes(); - this._initSpecialOptions(); - this._slots = []; - this._sequence = this._getXHRPromise(true); - this._sending = this._active = 0; - this._initProgressObject(this); - this._initEventHandlers(); - }, - - // This method is exposed to the widget API and allows to query - // the number of active uploads: - active: function () { - return this._active; - }, - - // This method is exposed to the widget API and allows to query - // the widget upload progress. - // It returns an object with loaded, total and bitrate properties - // for the running uploads: - progress: function () { - return this._progress; - }, - - // This method is exposed to the widget API and allows adding files - // using the fileupload API. The data parameter accepts an object which - // must have a files property and can contain additional options: - // .fileupload('add', {files: filesList}); - add: function (data) { - var that = this; - if (!data || this.options.disabled) { - return; - } - if (data.fileInput && !data.files) { - this._getFileInputFiles(data.fileInput).always(function (files) { - data.files = files; - that._onAdd(null, data); - }); - } else { - data.files = $.makeArray(data.files); - this._onAdd(null, data); - } - }, - - // This method is exposed to the widget API and allows sending files - // using the fileupload API. The data parameter accepts an object which - // must have a files or fileInput property and can contain additional options: - // .fileupload('send', {files: filesList}); - // The method returns a Promise object for the file upload call. - send: function (data) { - if (data && !this.options.disabled) { - if (data.fileInput && !data.files) { - var that = this, - dfd = $.Deferred(), - promise = dfd.promise(), - jqXHR, - aborted; - promise.abort = function () { - aborted = true; - if (jqXHR) { - return jqXHR.abort(); - } - dfd.reject(null, 'abort', 'abort'); - return promise; - }; - this._getFileInputFiles(data.fileInput).always( - function (files) { - if (aborted) { - return; - } - if (!files.length) { - dfd.reject(); - return; - } - data.files = files; - jqXHR = that._onSend(null, data).then( - function (result, textStatus, jqXHR) { - dfd.resolve(result, textStatus, jqXHR); - }, - function (jqXHR, textStatus, errorThrown) { - dfd.reject(jqXHR, textStatus, errorThrown); - } - ); - } - ); - return this._enhancePromise(promise); - } - data.files = $.makeArray(data.files); - if (data.files.length) { - return this._onSend(null, data); - } - } - return this._getXHRPromise(false, data && data.context); - } - - }); - -})); diff --git a/library/jqupload/js/jquery.iframe-transport.js b/library/jqupload/js/jquery.iframe-transport.js deleted file mode 100644 index 8d64b591b..000000000 --- a/library/jqupload/js/jquery.iframe-transport.js +++ /dev/null @@ -1,214 +0,0 @@ -/* - * jQuery Iframe Transport Plugin 1.8.2 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2011, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -/* global define, window, document */ - -(function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define(['jquery'], factory); - } else { - // Browser globals: - factory(window.jQuery); - } -}(function ($) { - 'use strict'; - - // Helper variable to create unique names for the transport iframes: - var counter = 0; - - // The iframe transport accepts four additional options: - // options.fileInput: a jQuery collection of file input fields - // options.paramName: the parameter name for the file form data, - // overrides the name property of the file input field(s), - // can be a string or an array of strings. - // options.formData: an array of objects with name and value properties, - // equivalent to the return data of .serializeArray(), e.g.: - // [{name: 'a', value: 1}, {name: 'b', value: 2}] - // options.initialIframeSrc: the URL of the initial iframe src, - // by default set to "javascript:false;" - $.ajaxTransport('iframe', function (options) { - if (options.async) { - // javascript:false as initial iframe src - // prevents warning popups on HTTPS in IE6: - /*jshint scripturl: true */ - var initialIframeSrc = options.initialIframeSrc || 'javascript:false;', - /*jshint scripturl: false */ - form, - iframe, - addParamChar; - return { - send: function (_, completeCallback) { - form = $('
    '); - form.attr('accept-charset', options.formAcceptCharset); - addParamChar = /\?/.test(options.url) ? '&' : '?'; - // XDomainRequest only supports GET and POST: - if (options.type === 'DELETE') { - options.url = options.url + addParamChar + '_method=DELETE'; - options.type = 'POST'; - } else if (options.type === 'PUT') { - options.url = options.url + addParamChar + '_method=PUT'; - options.type = 'POST'; - } else if (options.type === 'PATCH') { - options.url = options.url + addParamChar + '_method=PATCH'; - options.type = 'POST'; - } - // IE versions below IE8 cannot set the name property of - // elements that have already been added to the DOM, - // so we set the name along with the iframe HTML markup: - counter += 1; - iframe = $( - '' - ).bind('load', function () { - var fileInputClones, - paramNames = $.isArray(options.paramName) ? - options.paramName : [options.paramName]; - iframe - .unbind('load') - .bind('load', function () { - var response; - // Wrap in a try/catch block to catch exceptions thrown - // when trying to access cross-domain iframe contents: - try { - response = iframe.contents(); - // Google Chrome and Firefox do not throw an - // exception when calling iframe.contents() on - // cross-domain requests, so we unify the response: - if (!response.length || !response[0].firstChild) { - throw new Error(); - } - } catch (e) { - response = undefined; - } - // The complete callback returns the - // iframe content document as response object: - completeCallback( - 200, - 'success', - {'iframe': response} - ); - // Fix for IE endless progress bar activity bug - // (happens on form submits to iframe targets): - $('') - .appendTo(form); - window.setTimeout(function () { - // Removing the form in a setTimeout call - // allows Chrome's developer tools to display - // the response result - form.remove(); - }, 0); - }); - form - .prop('target', iframe.prop('name')) - .prop('action', options.url) - .prop('method', options.type); - if (options.formData) { - $.each(options.formData, function (index, field) { - $('') - .prop('name', field.name) - .val(field.value) - .appendTo(form); - }); - } - if (options.fileInput && options.fileInput.length && - options.type === 'POST') { - fileInputClones = options.fileInput.clone(); - // Insert a clone for each file input field: - options.fileInput.after(function (index) { - return fileInputClones[index]; - }); - if (options.paramName) { - options.fileInput.each(function (index) { - $(this).prop( - 'name', - paramNames[index] || options.paramName - ); - }); - } - // Appending the file input fields to the hidden form - // removes them from their original location: - form - .append(options.fileInput) - .prop('enctype', 'multipart/form-data') - // enctype must be set as encoding for IE: - .prop('encoding', 'multipart/form-data'); - // Remove the HTML5 form attribute from the input(s): - options.fileInput.removeAttr('form'); - } - form.submit(); - // Insert the file input fields at their original location - // by replacing the clones with the originals: - if (fileInputClones && fileInputClones.length) { - options.fileInput.each(function (index, input) { - var clone = $(fileInputClones[index]); - // Restore the original name and form properties: - $(input) - .prop('name', clone.prop('name')) - .attr('form', clone.attr('form')); - clone.replaceWith(input); - }); - } - }); - form.append(iframe).appendTo(document.body); - }, - abort: function () { - if (iframe) { - // javascript:false as iframe src aborts the request - // and prevents warning popups on HTTPS in IE6. - // concat is used to avoid the "Script URL" JSLint error: - iframe - .unbind('load') - .prop('src', initialIframeSrc); - } - if (form) { - form.remove(); - } - } - }; - } - }); - - // The iframe transport returns the iframe content document as response. - // The following adds converters from iframe to text, json, html, xml - // and script. - // Please note that the Content-Type for JSON responses has to be text/plain - // or text/html, if the browser doesn't include application/json in the - // Accept header, else IE will show a download dialog. - // The Content-Type for XML responses on the other hand has to be always - // application/xml or text/xml, so IE properly parses the XML response. - // See also - // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation - $.ajaxSetup({ - converters: { - 'iframe text': function (iframe) { - return iframe && $(iframe[0].body).text(); - }, - 'iframe json': function (iframe) { - return iframe && $.parseJSON($(iframe[0].body).text()); - }, - 'iframe html': function (iframe) { - return iframe && $(iframe[0].body).html(); - }, - 'iframe xml': function (iframe) { - var xmlDoc = iframe && iframe[0]; - return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc : - $.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) || - $(xmlDoc.body).html()); - }, - 'iframe script': function (iframe) { - return iframe && $.globalEval($(iframe[0].body).text()); - } - } - }); - -})); diff --git a/library/jqupload/js/main.js b/library/jqupload/js/main.js deleted file mode 100644 index 8f57967a3..000000000 --- a/library/jqupload/js/main.js +++ /dev/null @@ -1,75 +0,0 @@ -/* - * jQuery File Upload Plugin JS Example 8.9.1 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2010, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -/* global $, window */ - -$(function () { - 'use strict'; - - // Initialize the jQuery File Upload widget: - $('#fileupload').fileupload({ - // Uncomment the following to send cross-domain cookies: - //xhrFields: {withCredentials: true}, - url: 'server/php/' - }); - - // Enable iframe cross-domain access via redirect option: - $('#fileupload').fileupload( - 'option', - 'redirect', - window.location.href.replace( - /\/[^\/]*$/, - '/cors/result.html?%s' - ) - ); - - if (window.location.hostname === 'blueimp.github.io') { - // Demo settings: - $('#fileupload').fileupload('option', { - url: '//jquery-file-upload.appspot.com/', - // Enable image resizing, except for Android and Opera, - // which actually support image resizing, but fail to - // send Blob objects via XHR requests: - disableImageResize: /Android(?!.*Chrome)|Opera/ - .test(window.navigator.userAgent), - maxFileSize: 5000000, - acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i - }); - // Upload server status check for browsers with CORS support: - if ($.support.cors) { - $.ajax({ - url: '//jquery-file-upload.appspot.com/', - type: 'HEAD' - }).fail(function () { - $('
    ') - .text('Upload server currently unavailable - ' + - new Date()) - .appendTo('#fileupload'); - }); - } - } else { - // Load existing files: - $('#fileupload').addClass('fileupload-processing'); - $.ajax({ - // Uncomment the following to send cross-domain cookies: - //xhrFields: {withCredentials: true}, - url: $('#fileupload').fileupload('option', 'url'), - dataType: 'json', - context: $('#fileupload')[0] - }).always(function () { - $(this).removeClass('fileupload-processing'); - }).done(function (result) { - $(this).fileupload('option', 'done') - .call(this, $.Event('done'), {result: result}); - }); - } - -}); diff --git a/library/jqupload/js/vendor/jquery.ui.widget.js b/library/jqupload/js/vendor/jquery.ui.widget.js deleted file mode 100644 index 2d370893a..000000000 --- a/library/jqupload/js/vendor/jquery.ui.widget.js +++ /dev/null @@ -1,530 +0,0 @@ -/* - * jQuery UI Widget 1.10.3+amd - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2013 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/jQuery.widget/ - */ - -(function (factory) { - if (typeof define === "function" && define.amd) { - // Register as an anonymous AMD module: - define(["jquery"], factory); - } else { - // Browser globals: - factory(jQuery); - } -}(function( $, undefined ) { - -var uuid = 0, - slice = Array.prototype.slice, - _cleanData = $.cleanData; -$.cleanData = function( elems ) { - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { - try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} - } - _cleanData( elems ); -}; - -$.widget = function( name, base, prototype ) { - var fullName, existingConstructor, constructor, basePrototype, - // proxiedPrototype allows the provided prototype to remain unmodified - // so that it can be used as a mixin for multiple widgets (#8876) - proxiedPrototype = {}, - namespace = name.split( "." )[ 0 ]; - - name = name.split( "." )[ 1 ]; - fullName = namespace + "-" + name; - - if ( !prototype ) { - prototype = base; - base = $.Widget; - } - - // create selector for plugin - $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { - return !!$.data( elem, fullName ); - }; - - $[ namespace ] = $[ namespace ] || {}; - existingConstructor = $[ namespace ][ name ]; - constructor = $[ namespace ][ name ] = function( options, element ) { - // allow instantiation without "new" keyword - if ( !this._createWidget ) { - return new constructor( options, element ); - } - - // allow instantiation without initializing for simple inheritance - // must use "new" keyword (the code above always passes args) - if ( arguments.length ) { - this._createWidget( options, element ); - } - }; - // extend with the existing constructor to carry over any static properties - $.extend( constructor, existingConstructor, { - version: prototype.version, - // copy the object used to create the prototype in case we need to - // redefine the widget later - _proto: $.extend( {}, prototype ), - // track widgets that inherit from this widget in case this widget is - // redefined after a widget inherits from it - _childConstructors: [] - }); - - basePrototype = new base(); - // we need to make the options hash a property directly on the new instance - // otherwise we'll modify the options hash on the prototype that we're - // inheriting from - basePrototype.options = $.widget.extend( {}, basePrototype.options ); - $.each( prototype, function( prop, value ) { - if ( !$.isFunction( value ) ) { - proxiedPrototype[ prop ] = value; - return; - } - proxiedPrototype[ prop ] = (function() { - var _super = function() { - return base.prototype[ prop ].apply( this, arguments ); - }, - _superApply = function( args ) { - return base.prototype[ prop ].apply( this, args ); - }; - return function() { - var __super = this._super, - __superApply = this._superApply, - returnValue; - - this._super = _super; - this._superApply = _superApply; - - returnValue = value.apply( this, arguments ); - - this._super = __super; - this._superApply = __superApply; - - return returnValue; - }; - })(); - }); - constructor.prototype = $.widget.extend( basePrototype, { - // TODO: remove support for widgetEventPrefix - // always use the name + a colon as the prefix, e.g., draggable:start - // don't prefix for widgets that aren't DOM-based - widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name - }, proxiedPrototype, { - constructor: constructor, - namespace: namespace, - widgetName: name, - widgetFullName: fullName - }); - - // If this widget is being redefined then we need to find all widgets that - // are inheriting from it and redefine all of them so that they inherit from - // the new version of this widget. We're essentially trying to replace one - // level in the prototype chain. - if ( existingConstructor ) { - $.each( existingConstructor._childConstructors, function( i, child ) { - var childPrototype = child.prototype; - - // redefine the child widget using the same prototype that was - // originally used, but inherit from the new version of the base - $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); - }); - // remove the list of existing child constructors from the old constructor - // so the old child constructors can be garbage collected - delete existingConstructor._childConstructors; - } else { - base._childConstructors.push( constructor ); - } - - $.widget.bridge( name, constructor ); -}; - -$.widget.extend = function( target ) { - var input = slice.call( arguments, 1 ), - inputIndex = 0, - inputLength = input.length, - key, - value; - for ( ; inputIndex < inputLength; inputIndex++ ) { - for ( key in input[ inputIndex ] ) { - value = input[ inputIndex ][ key ]; - if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { - // Clone objects - if ( $.isPlainObject( value ) ) { - target[ key ] = $.isPlainObject( target[ key ] ) ? - $.widget.extend( {}, target[ key ], value ) : - // Don't extend strings, arrays, etc. with objects - $.widget.extend( {}, value ); - // Copy everything else by reference - } else { - target[ key ] = value; - } - } - } - } - return target; -}; - -$.widget.bridge = function( name, object ) { - var fullName = object.prototype.widgetFullName || name; - $.fn[ name ] = function( options ) { - var isMethodCall = typeof options === "string", - args = slice.call( arguments, 1 ), - returnValue = this; - - // allow multiple hashes to be passed on init - options = !isMethodCall && args.length ? - $.widget.extend.apply( null, [ options ].concat(args) ) : - options; - - if ( isMethodCall ) { - this.each(function() { - var methodValue, - instance = $.data( this, fullName ); - if ( !instance ) { - return $.error( "cannot call methods on " + name + " prior to initialization; " + - "attempted to call method '" + options + "'" ); - } - if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { - return $.error( "no such method '" + options + "' for " + name + " widget instance" ); - } - methodValue = instance[ options ].apply( instance, args ); - if ( methodValue !== instance && methodValue !== undefined ) { - returnValue = methodValue && methodValue.jquery ? - returnValue.pushStack( methodValue.get() ) : - methodValue; - return false; - } - }); - } else { - this.each(function() { - var instance = $.data( this, fullName ); - if ( instance ) { - instance.option( options || {} )._init(); - } else { - $.data( this, fullName, new object( options, this ) ); - } - }); - } - - return returnValue; - }; -}; - -$.Widget = function( /* options, element */ ) {}; -$.Widget._childConstructors = []; - -$.Widget.prototype = { - widgetName: "widget", - widgetEventPrefix: "", - defaultElement: "
    ", - options: { - disabled: false, - - // callbacks - create: null - }, - _createWidget: function( options, element ) { - element = $( element || this.defaultElement || this )[ 0 ]; - this.element = $( element ); - this.uuid = uuid++; - this.eventNamespace = "." + this.widgetName + this.uuid; - this.options = $.widget.extend( {}, - this.options, - this._getCreateOptions(), - options ); - - this.bindings = $(); - this.hoverable = $(); - this.focusable = $(); - - if ( element !== this ) { - $.data( element, this.widgetFullName, this ); - this._on( true, this.element, { - remove: function( event ) { - if ( event.target === element ) { - this.destroy(); - } - } - }); - this.document = $( element.style ? - // element within the document - element.ownerDocument : - // element is window or document - element.document || element ); - this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); - } - - this._create(); - this._trigger( "create", null, this._getCreateEventData() ); - this._init(); - }, - _getCreateOptions: $.noop, - _getCreateEventData: $.noop, - _create: $.noop, - _init: $.noop, - - destroy: function() { - this._destroy(); - // we can probably remove the unbind calls in 2.0 - // all event bindings should go through this._on() - this.element - .unbind( this.eventNamespace ) - // 1.9 BC for #7810 - // TODO remove dual storage - .removeData( this.widgetName ) - .removeData( this.widgetFullName ) - // support: jquery <1.6.3 - // http://bugs.jquery.com/ticket/9413 - .removeData( $.camelCase( this.widgetFullName ) ); - this.widget() - .unbind( this.eventNamespace ) - .removeAttr( "aria-disabled" ) - .removeClass( - this.widgetFullName + "-disabled " + - "ui-state-disabled" ); - - // clean up events and states - this.bindings.unbind( this.eventNamespace ); - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); - }, - _destroy: $.noop, - - widget: function() { - return this.element; - }, - - option: function( key, value ) { - var options = key, - parts, - curOption, - i; - - if ( arguments.length === 0 ) { - // don't return a reference to the internal hash - return $.widget.extend( {}, this.options ); - } - - if ( typeof key === "string" ) { - // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } - options = {}; - parts = key.split( "." ); - key = parts.shift(); - if ( parts.length ) { - curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); - for ( i = 0; i < parts.length - 1; i++ ) { - curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; - curOption = curOption[ parts[ i ] ]; - } - key = parts.pop(); - if ( value === undefined ) { - return curOption[ key ] === undefined ? null : curOption[ key ]; - } - curOption[ key ] = value; - } else { - if ( value === undefined ) { - return this.options[ key ] === undefined ? null : this.options[ key ]; - } - options[ key ] = value; - } - } - - this._setOptions( options ); - - return this; - }, - _setOptions: function( options ) { - var key; - - for ( key in options ) { - this._setOption( key, options[ key ] ); - } - - return this; - }, - _setOption: function( key, value ) { - this.options[ key ] = value; - - if ( key === "disabled" ) { - this.widget() - .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) - .attr( "aria-disabled", value ); - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); - } - - return this; - }, - - enable: function() { - return this._setOption( "disabled", false ); - }, - disable: function() { - return this._setOption( "disabled", true ); - }, - - _on: function( suppressDisabledCheck, element, handlers ) { - var delegateElement, - instance = this; - - // no suppressDisabledCheck flag, shuffle arguments - if ( typeof suppressDisabledCheck !== "boolean" ) { - handlers = element; - element = suppressDisabledCheck; - suppressDisabledCheck = false; - } - - // no element argument, shuffle and use this.element - if ( !handlers ) { - handlers = element; - element = this.element; - delegateElement = this.widget(); - } else { - // accept selectors, DOM elements - element = delegateElement = $( element ); - this.bindings = this.bindings.add( element ); - } - - $.each( handlers, function( event, handler ) { - function handlerProxy() { - // allow widgets to customize the disabled handling - // - disabled as an array instead of boolean - // - disabled class as method for disabling individual parts - if ( !suppressDisabledCheck && - ( instance.options.disabled === true || - $( this ).hasClass( "ui-state-disabled" ) ) ) { - return; - } - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } - - // copy the guid so direct unbinding works - if ( typeof handler !== "string" ) { - handlerProxy.guid = handler.guid = - handler.guid || handlerProxy.guid || $.guid++; - } - - var match = event.match( /^(\w+)\s*(.*)$/ ), - eventName = match[1] + instance.eventNamespace, - selector = match[2]; - if ( selector ) { - delegateElement.delegate( selector, eventName, handlerProxy ); - } else { - element.bind( eventName, handlerProxy ); - } - }); - }, - - _off: function( element, eventName ) { - eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; - element.unbind( eventName ).undelegate( eventName ); - }, - - _delay: function( handler, delay ) { - function handlerProxy() { - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } - var instance = this; - return setTimeout( handlerProxy, delay || 0 ); - }, - - _hoverable: function( element ) { - this.hoverable = this.hoverable.add( element ); - this._on( element, { - mouseenter: function( event ) { - $( event.currentTarget ).addClass( "ui-state-hover" ); - }, - mouseleave: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-hover" ); - } - }); - }, - - _focusable: function( element ) { - this.focusable = this.focusable.add( element ); - this._on( element, { - focusin: function( event ) { - $( event.currentTarget ).addClass( "ui-state-focus" ); - }, - focusout: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-focus" ); - } - }); - }, - - _trigger: function( type, event, data ) { - var prop, orig, - callback = this.options[ type ]; - - data = data || {}; - event = $.Event( event ); - event.type = ( type === this.widgetEventPrefix ? - type : - this.widgetEventPrefix + type ).toLowerCase(); - // the original event may come from any element - // so we need to reset the target on the new event - event.target = this.element[ 0 ]; - - // copy original event properties over to the new event - orig = event.originalEvent; - if ( orig ) { - for ( prop in orig ) { - if ( !( prop in event ) ) { - event[ prop ] = orig[ prop ]; - } - } - } - - this.element.trigger( event, data ); - return !( $.isFunction( callback ) && - callback.apply( this.element[0], [ event ].concat( data ) ) === false || - event.isDefaultPrevented() ); - } -}; - -$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { - $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { - if ( typeof options === "string" ) { - options = { effect: options }; - } - var hasOptions, - effectName = !options ? - method : - options === true || typeof options === "number" ? - defaultEffect : - options.effect || defaultEffect; - options = options || {}; - if ( typeof options === "number" ) { - options = { duration: options }; - } - hasOptions = !$.isEmptyObject( options ); - options.complete = callback; - if ( options.delay ) { - element.delay( options.delay ); - } - if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { - element[ method ]( options ); - } else if ( effectName !== method && element[ effectName ] ) { - element[ effectName ]( options.duration, options.easing, callback ); - } else { - element.queue(function( next ) { - $( this )[ method ](); - if ( callback ) { - callback.call( element[ 0 ] ); - } - next(); - }); - } - }; -}); - -})); diff --git a/library/jqupload/package.json b/library/jqupload/package.json deleted file mode 100644 index 85852c35a..000000000 --- a/library/jqupload/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "blueimp-file-upload", - "version": "9.5.2", - "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": [ - "jquery", - "file", - "upload", - "widget", - "multiple", - "selection", - "drag", - "drop", - "progress", - "preview", - "cross-domain", - "cross-site", - "chunk", - "resume", - "gae", - "go", - "python", - "php", - "bootstrap" - ], - "homepage": "https://github.com/blueimp/jQuery-File-Upload", - "author": { - "name": "Sebastian Tschan", - "url": "https://blueimp.net" - }, - "maintainers": [ - { - "name": "Sebastian Tschan", - "url": "https://blueimp.net" - } - ], - "repository": { - "type": "git", - "url": "git://github.com/blueimp/jQuery-File-Upload.git" - }, - "bugs": "https://github.com/blueimp/jQuery-File-Upload/issues", - "licenses": [ - { - "type": "MIT", - "url": "http://www.opensource.org/licenses/MIT" - } - ], - "devDependencies": { - "grunt": "~0.4.2", - "grunt-bump-build-git": "~1.1.1", - "grunt-contrib-jshint": "~0.8.0" - } -} diff --git a/library/jqupload/server/gae-go/app.yaml b/library/jqupload/server/gae-go/app.yaml deleted file mode 100644 index 2d09daa56..000000000 --- a/library/jqupload/server/gae-go/app.yaml +++ /dev/null @@ -1,12 +0,0 @@ -application: jquery-file-upload -version: 2 -runtime: go -api_version: go1 - -handlers: -- url: /(favicon\.ico|robots\.txt) - static_files: static/\1 - upload: static/(.*) - expiration: '1d' -- url: /.* - script: _go_app diff --git a/library/jqupload/server/gae-go/app/main.go b/library/jqupload/server/gae-go/app/main.go deleted file mode 100644 index f995f73a8..000000000 --- a/library/jqupload/server/gae-go/app/main.go +++ /dev/null @@ -1,296 +0,0 @@ -/* - * jQuery File Upload Plugin GAE Go Example 3.1.1 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2011, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -package app - -import ( - "appengine" - "appengine/blobstore" - "appengine/image" - "appengine/taskqueue" - "bytes" - "encoding/json" - "fmt" - "io" - "log" - "mime/multipart" - "net/http" - "net/url" - "regexp" - "strings" - "time" -) - -const ( - WEBSITE = "http://blueimp.github.io/jQuery-File-Upload/" - MIN_FILE_SIZE = 1 // bytes - MAX_FILE_SIZE = 5000000 // bytes - IMAGE_TYPES = "image/(gif|p?jpeg|(x-)?png)" - ACCEPT_FILE_TYPES = IMAGE_TYPES - EXPIRATION_TIME = 300 // seconds - THUMBNAIL_PARAM = "=s80" -) - -var ( - imageTypes = regexp.MustCompile(IMAGE_TYPES) - acceptFileTypes = regexp.MustCompile(ACCEPT_FILE_TYPES) -) - -type FileInfo struct { - Key appengine.BlobKey `json:"-"` - Url string `json:"url,omitempty"` - ThumbnailUrl string `json:"thumbnailUrl,omitempty"` - Name string `json:"name"` - Type string `json:"type"` - Size int64 `json:"size"` - Error string `json:"error,omitempty"` - DeleteUrl string `json:"deleteUrl,omitempty"` - DeleteType string `json:"deleteType,omitempty"` -} - -func (fi *FileInfo) ValidateType() (valid bool) { - if acceptFileTypes.MatchString(fi.Type) { - return true - } - fi.Error = "Filetype not allowed" - return false -} - -func (fi *FileInfo) ValidateSize() (valid bool) { - if fi.Size < MIN_FILE_SIZE { - fi.Error = "File is too small" - } else if fi.Size > MAX_FILE_SIZE { - fi.Error = "File is too big" - } else { - return true - } - return false -} - -func (fi *FileInfo) CreateUrls(r *http.Request, c appengine.Context) { - u := &url.URL{ - Scheme: r.URL.Scheme, - Host: appengine.DefaultVersionHostname(c), - Path: "/", - } - uString := u.String() - fi.Url = uString + escape(string(fi.Key)) + "/" + - escape(string(fi.Name)) - fi.DeleteUrl = fi.Url + "?delete=true" - fi.DeleteType = "DELETE" - if imageTypes.MatchString(fi.Type) { - servingUrl, err := image.ServingURL( - c, - fi.Key, - &image.ServingURLOptions{ - Secure: strings.HasSuffix(u.Scheme, "s"), - Size: 0, - Crop: false, - }, - ) - check(err) - fi.ThumbnailUrl = servingUrl.String() + THUMBNAIL_PARAM - } -} - -func check(err error) { - if err != nil { - panic(err) - } -} - -func escape(s string) string { - return strings.Replace(url.QueryEscape(s), "+", "%20", -1) -} - -func delayedDelete(c appengine.Context, fi *FileInfo) { - if key := string(fi.Key); key != "" { - task := &taskqueue.Task{ - Path: "/" + escape(key) + "/-", - Method: "DELETE", - Delay: time.Duration(EXPIRATION_TIME) * time.Second, - } - taskqueue.Add(c, task, "") - } -} - -func handleUpload(r *http.Request, p *multipart.Part) (fi *FileInfo) { - fi = &FileInfo{ - Name: p.FileName(), - Type: p.Header.Get("Content-Type"), - } - if !fi.ValidateType() { - return - } - defer func() { - if rec := recover(); rec != nil { - log.Println(rec) - fi.Error = rec.(error).Error() - } - }() - lr := &io.LimitedReader{R: p, N: MAX_FILE_SIZE + 1} - context := appengine.NewContext(r) - w, err := blobstore.Create(context, fi.Type) - defer func() { - w.Close() - fi.Size = MAX_FILE_SIZE + 1 - lr.N - fi.Key, err = w.Key() - check(err) - if !fi.ValidateSize() { - err := blobstore.Delete(context, fi.Key) - check(err) - return - } - delayedDelete(context, fi) - fi.CreateUrls(r, context) - }() - check(err) - _, err = io.Copy(w, lr) - return -} - -func getFormValue(p *multipart.Part) string { - var b bytes.Buffer - io.CopyN(&b, p, int64(1<<20)) // Copy max: 1 MiB - return b.String() -} - -func handleUploads(r *http.Request) (fileInfos []*FileInfo) { - fileInfos = make([]*FileInfo, 0) - mr, err := r.MultipartReader() - check(err) - r.Form, err = url.ParseQuery(r.URL.RawQuery) - check(err) - part, err := mr.NextPart() - for err == nil { - if name := part.FormName(); name != "" { - if part.FileName() != "" { - fileInfos = append(fileInfos, handleUpload(r, part)) - } else { - r.Form[name] = append(r.Form[name], getFormValue(part)) - } - } - part, err = mr.NextPart() - } - return -} - -func get(w http.ResponseWriter, r *http.Request) { - if r.URL.Path == "/" { - http.Redirect(w, r, WEBSITE, http.StatusFound) - return - } - parts := strings.Split(r.URL.Path, "/") - if len(parts) == 3 { - if key := parts[1]; key != "" { - blobKey := appengine.BlobKey(key) - bi, err := blobstore.Stat(appengine.NewContext(r), blobKey) - if err == nil { - w.Header().Add("X-Content-Type-Options", "nosniff") - if !imageTypes.MatchString(bi.ContentType) { - w.Header().Add("Content-Type", "application/octet-stream") - w.Header().Add( - "Content-Disposition", - fmt.Sprintf("attachment; filename=\"%s\"", parts[2]), - ) - } - w.Header().Add( - "Cache-Control", - fmt.Sprintf("public,max-age=%d", EXPIRATION_TIME), - ) - blobstore.Send(w, blobKey) - return - } - } - } - http.Error(w, "404 Not Found", http.StatusNotFound) -} - -func post(w http.ResponseWriter, r *http.Request) { - result := make(map[string][]*FileInfo, 1) - result["files"] = handleUploads(r) - b, err := json.Marshal(result) - check(err) - if redirect := r.FormValue("redirect"); redirect != "" { - if strings.Contains(redirect, "%s") { - redirect = fmt.Sprintf( - redirect, - escape(string(b)), - ) - } - http.Redirect(w, r, redirect, http.StatusFound) - return - } - w.Header().Set("Cache-Control", "no-cache") - jsonType := "application/json" - if strings.Index(r.Header.Get("Accept"), jsonType) != -1 { - w.Header().Set("Content-Type", jsonType) - } - fmt.Fprintln(w, string(b)) -} - -func delete(w http.ResponseWriter, r *http.Request) { - parts := strings.Split(r.URL.Path, "/") - if len(parts) != 3 { - return - } - result := make(map[string]bool, 1) - if key := parts[1]; key != "" { - c := appengine.NewContext(r) - blobKey := appengine.BlobKey(key) - err := blobstore.Delete(c, blobKey) - check(err) - err = image.DeleteServingURL(c, blobKey) - check(err) - result[key] = true - } - jsonType := "application/json" - if strings.Index(r.Header.Get("Accept"), jsonType) != -1 { - w.Header().Set("Content-Type", jsonType) - } - b, err := json.Marshal(result) - check(err) - fmt.Fprintln(w, string(b)) -} - -func handle(w http.ResponseWriter, r *http.Request) { - params, err := url.ParseQuery(r.URL.RawQuery) - check(err) - w.Header().Add("Access-Control-Allow-Origin", "*") - w.Header().Add( - "Access-Control-Allow-Methods", - "OPTIONS, HEAD, GET, POST, PUT, DELETE", - ) - w.Header().Add( - "Access-Control-Allow-Headers", - "Content-Type, Content-Range, Content-Disposition", - ) - switch r.Method { - case "OPTIONS": - case "HEAD": - case "GET": - get(w, r) - case "POST": - if len(params["_method"]) > 0 && params["_method"][0] == "DELETE" { - delete(w, r) - } else { - post(w, r) - } - case "DELETE": - delete(w, r) - default: - http.Error(w, "501 Not Implemented", http.StatusNotImplemented) - } -} - -func init() { - http.HandleFunc("/", handle) -} diff --git a/library/jqupload/server/gae-go/static/robots.txt b/library/jqupload/server/gae-go/static/robots.txt deleted file mode 100644 index eb0536286..000000000 --- a/library/jqupload/server/gae-go/static/robots.txt +++ /dev/null @@ -1,2 +0,0 @@ -User-agent: * -Disallow: diff --git a/library/jqupload/server/gae-python/app.yaml b/library/jqupload/server/gae-python/app.yaml deleted file mode 100644 index 5fe123f59..000000000 --- a/library/jqupload/server/gae-python/app.yaml +++ /dev/null @@ -1,16 +0,0 @@ -application: jquery-file-upload -version: 1 -runtime: python27 -api_version: 1 -threadsafe: true - -builtins: -- deferred: on - -handlers: -- url: /(favicon\.ico|robots\.txt) - static_files: static/\1 - upload: static/(.*) - expiration: '1d' -- url: /.* - script: main.app diff --git a/library/jqupload/server/gae-python/main.py b/library/jqupload/server/gae-python/main.py deleted file mode 100644 index 37aa44e38..000000000 --- a/library/jqupload/server/gae-python/main.py +++ /dev/null @@ -1,170 +0,0 @@ -# -*- coding: utf-8 -*- -# -# jQuery File Upload Plugin GAE Python Example 2.1.1 -# https://github.com/blueimp/jQuery-File-Upload -# -# Copyright 2011, Sebastian Tschan -# https://blueimp.net -# -# Licensed under the MIT license: -# http://www.opensource.org/licenses/MIT -# - -from __future__ import with_statement -from google.appengine.api import files, images -from google.appengine.ext import blobstore, deferred -from google.appengine.ext.webapp import blobstore_handlers -import json -import re -import urllib -import webapp2 - -WEBSITE = 'http://blueimp.github.io/jQuery-File-Upload/' -MIN_FILE_SIZE = 1 # bytes -MAX_FILE_SIZE = 5000000 # bytes -IMAGE_TYPES = re.compile('image/(gif|p?jpeg|(x-)?png)') -ACCEPT_FILE_TYPES = IMAGE_TYPES -THUMBNAIL_MODIFICATOR = '=s80' # max width / height -EXPIRATION_TIME = 300 # seconds - - -def cleanup(blob_keys): - blobstore.delete(blob_keys) - - -class UploadHandler(webapp2.RequestHandler): - - def initialize(self, request, response): - super(UploadHandler, self).initialize(request, response) - self.response.headers['Access-Control-Allow-Origin'] = '*' - self.response.headers[ - 'Access-Control-Allow-Methods' - ] = 'OPTIONS, HEAD, GET, POST, PUT, DELETE' - self.response.headers[ - 'Access-Control-Allow-Headers' - ] = 'Content-Type, Content-Range, Content-Disposition' - - def validate(self, file): - if file['size'] < MIN_FILE_SIZE: - file['error'] = 'File is too small' - elif file['size'] > MAX_FILE_SIZE: - file['error'] = 'File is too big' - elif not ACCEPT_FILE_TYPES.match(file['type']): - file['error'] = 'Filetype not allowed' - else: - return True - return False - - def get_file_size(self, file): - file.seek(0, 2) # Seek to the end of the file - size = file.tell() # Get the position of EOF - file.seek(0) # Reset the file position to the beginning - return size - - def write_blob(self, data, info): - blob = files.blobstore.create( - mime_type=info['type'], - _blobinfo_uploaded_filename=info['name'] - ) - with files.open(blob, 'a') as f: - f.write(data) - files.finalize(blob) - return files.blobstore.get_blob_key(blob) - - def handle_upload(self): - results = [] - blob_keys = [] - for name, fieldStorage in self.request.POST.items(): - if type(fieldStorage) is unicode: - continue - result = {} - result['name'] = re.sub( - r'^.*\\', - '', - fieldStorage.filename - ) - result['type'] = fieldStorage.type - result['size'] = self.get_file_size(fieldStorage.file) - if self.validate(result): - blob_key = str( - self.write_blob(fieldStorage.value, result) - ) - blob_keys.append(blob_key) - result['deleteType'] = 'DELETE' - result['deleteUrl'] = self.request.host_url +\ - '/?key=' + urllib.quote(blob_key, '') - if (IMAGE_TYPES.match(result['type'])): - try: - result['url'] = images.get_serving_url( - blob_key, - secure_url=self.request.host_url.startswith( - 'https' - ) - ) - result['thumbnailUrl'] = result['url'] +\ - THUMBNAIL_MODIFICATOR - except: # Could not get an image serving url - pass - if not 'url' in result: - result['url'] = self.request.host_url +\ - '/' + blob_key + '/' + urllib.quote( - result['name'].encode('utf-8'), '') - results.append(result) - deferred.defer( - cleanup, - blob_keys, - _countdown=EXPIRATION_TIME - ) - return results - - def options(self): - pass - - def head(self): - pass - - def get(self): - self.redirect(WEBSITE) - - def post(self): - if (self.request.get('_method') == 'DELETE'): - return self.delete() - result = {'files': self.handle_upload()} - s = json.dumps(result, separators=(',', ':')) - redirect = self.request.get('redirect') - if redirect: - return self.redirect(str( - redirect.replace('%s', urllib.quote(s, ''), 1) - )) - if 'application/json' in self.request.headers.get('Accept'): - self.response.headers['Content-Type'] = 'application/json' - self.response.write(s) - - def delete(self): - key = self.request.get('key') or '' - blobstore.delete(key) - s = json.dumps({key: True}, separators=(',', ':')) - if 'application/json' in self.request.headers.get('Accept'): - self.response.headers['Content-Type'] = 'application/json' - self.response.write(s) - - -class DownloadHandler(blobstore_handlers.BlobstoreDownloadHandler): - def get(self, key, filename): - if not blobstore.get(key): - self.error(404) - else: - # Prevent browsers from MIME-sniffing the content-type: - self.response.headers['X-Content-Type-Options'] = 'nosniff' - # Cache for the expiration time: - self.response.headers['Cache-Control'] = 'public,max-age=%d' % EXPIRATION_TIME - # Send the file forcing a download dialog: - self.send_blob(key, save_as=filename, content_type='application/octet-stream') - -app = webapp2.WSGIApplication( - [ - ('/', UploadHandler), - ('/([^/]+)/([^/]+)', DownloadHandler) - ], - debug=True -) diff --git a/library/jqupload/server/gae-python/static/robots.txt b/library/jqupload/server/gae-python/static/robots.txt deleted file mode 100644 index eb0536286..000000000 --- a/library/jqupload/server/gae-python/static/robots.txt +++ /dev/null @@ -1,2 +0,0 @@ -User-agent: * -Disallow: diff --git a/library/jqupload/server/node/.gitignore b/library/jqupload/server/node/.gitignore deleted file mode 100644 index 9daa8247d..000000000 --- a/library/jqupload/server/node/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.DS_Store -node_modules diff --git a/library/jqupload/server/node/package.json b/library/jqupload/server/node/package.json deleted file mode 100644 index dd38c50ca..000000000 --- a/library/jqupload/server/node/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "blueimp-file-upload-node", - "version": "2.1.0", - "title": "jQuery File Upload Node.js example", - "description": "Node.js implementation example of a file upload handler for jQuery File Upload.", - "keywords": [ - "file", - "upload", - "cross-domain", - "cross-site", - "node" - ], - "homepage": "https://github.com/blueimp/jQuery-File-Upload", - "author": { - "name": "Sebastian Tschan", - "url": "https://blueimp.net" - }, - "maintainers": [ - { - "name": "Sebastian Tschan", - "url": "https://blueimp.net" - } - ], - "repository": { - "type": "git", - "url": "git://github.com/blueimp/jQuery-File-Upload.git" - }, - "bugs": "https://github.com/blueimp/jQuery-File-Upload/issues", - "licenses": [ - { - "type": "MIT", - "url": "http://www.opensource.org/licenses/MIT" - } - ], - "dependencies": { - "formidable": ">=1.0.11", - "node-static": ">=0.6.5", - "imagemagick": ">=0.1.3" - }, - "main": "server.js" -} diff --git a/library/jqupload/server/node/public/files/.gitignore b/library/jqupload/server/node/public/files/.gitignore deleted file mode 100644 index d6b7ef32c..000000000 --- a/library/jqupload/server/node/public/files/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/library/jqupload/server/node/server.js b/library/jqupload/server/node/server.js deleted file mode 100755 index e489772b5..000000000 --- a/library/jqupload/server/node/server.js +++ /dev/null @@ -1,292 +0,0 @@ -#!/usr/bin/nodejs -/* - * jQuery File Upload Plugin Node.js Example 2.1.1 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2012, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -/* jshint nomen:false */ -/* global require, __dirname, unescape, console */ - -(function (port) { - 'use strict'; - var path = require('path'), - fs = require('fs'), - // Since Node 0.8, .existsSync() moved from path to fs: - _existsSync = fs.existsSync || path.existsSync, - formidable = require('formidable'), - nodeStatic = require('node-static'), - imageMagick = require('imagemagick'), - options = { - tmpDir: __dirname + '/tmp', - publicDir: __dirname + '/public', - uploadDir: __dirname + '/public/files', - uploadUrl: '/files/', - maxPostSize: 11000000000, // 11 GB - minFileSize: 1, - maxFileSize: 10000000000, // 10 GB - acceptFileTypes: /.+/i, - // Files not matched by this regular expression force a download dialog, - // to prevent executing any scripts in the context of the service domain: - inlineFileTypes: /\.(gif|jpe?g|png)$/i, - imageTypes: /\.(gif|jpe?g|png)$/i, - imageVersions: { - 'thumbnail': { - width: 80, - height: 80 - } - }, - accessControl: { - allowOrigin: '*', - allowMethods: 'OPTIONS, HEAD, GET, POST, PUT, DELETE', - allowHeaders: 'Content-Type, Content-Range, Content-Disposition' - }, - /* Uncomment and edit this section to provide the service via HTTPS: - ssl: { - key: fs.readFileSync('/Applications/XAMPP/etc/ssl.key/server.key'), - cert: fs.readFileSync('/Applications/XAMPP/etc/ssl.crt/server.crt') - }, - */ - nodeStatic: { - cache: 3600 // seconds to cache served files - } - }, - utf8encode = function (str) { - return unescape(encodeURIComponent(str)); - }, - fileServer = new nodeStatic.Server(options.publicDir, options.nodeStatic), - nameCountRegexp = /(?:(?: \(([\d]+)\))?(\.[^.]+))?$/, - nameCountFunc = function (s, index, ext) { - return ' (' + ((parseInt(index, 10) || 0) + 1) + ')' + (ext || ''); - }, - FileInfo = function (file) { - this.name = file.name; - this.size = file.size; - this.type = file.type; - this.deleteType = 'DELETE'; - }, - UploadHandler = function (req, res, callback) { - this.req = req; - this.res = res; - this.callback = callback; - }, - serve = function (req, res) { - res.setHeader( - 'Access-Control-Allow-Origin', - options.accessControl.allowOrigin - ); - res.setHeader( - 'Access-Control-Allow-Methods', - options.accessControl.allowMethods - ); - res.setHeader( - 'Access-Control-Allow-Headers', - options.accessControl.allowHeaders - ); - var handleResult = function (result, redirect) { - if (redirect) { - res.writeHead(302, { - 'Location': redirect.replace( - /%s/, - encodeURIComponent(JSON.stringify(result)) - ) - }); - res.end(); - } else { - res.writeHead(200, { - 'Content-Type': req.headers.accept - .indexOf('application/json') !== -1 ? - 'application/json' : 'text/plain' - }); - res.end(JSON.stringify(result)); - } - }, - setNoCacheHeaders = function () { - res.setHeader('Pragma', 'no-cache'); - res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate'); - res.setHeader('Content-Disposition', 'inline; filename="files.json"'); - }, - handler = new UploadHandler(req, res, handleResult); - switch (req.method) { - case 'OPTIONS': - res.end(); - break; - case 'HEAD': - case 'GET': - if (req.url === '/') { - setNoCacheHeaders(); - if (req.method === 'GET') { - handler.get(); - } else { - res.end(); - } - } else { - fileServer.serve(req, res); - } - break; - case 'POST': - setNoCacheHeaders(); - handler.post(); - break; - case 'DELETE': - handler.destroy(); - break; - default: - res.statusCode = 405; - res.end(); - } - }; - fileServer.respond = function (pathname, status, _headers, files, stat, req, res, finish) { - // Prevent browsers from MIME-sniffing the content-type: - _headers['X-Content-Type-Options'] = 'nosniff'; - if (!options.inlineFileTypes.test(files[0])) { - // Force a download dialog for unsafe file extensions: - _headers['Content-Type'] = 'application/octet-stream'; - _headers['Content-Disposition'] = 'attachment; filename="' + - utf8encode(path.basename(files[0])) + '"'; - } - nodeStatic.Server.prototype.respond - .call(this, pathname, status, _headers, files, stat, req, res, finish); - }; - FileInfo.prototype.validate = function () { - if (options.minFileSize && options.minFileSize > this.size) { - this.error = 'File is too small'; - } else if (options.maxFileSize && options.maxFileSize < this.size) { - this.error = 'File is too big'; - } else if (!options.acceptFileTypes.test(this.name)) { - this.error = 'Filetype not allowed'; - } - return !this.error; - }; - FileInfo.prototype.safeName = function () { - // Prevent directory traversal and creating hidden system files: - this.name = path.basename(this.name).replace(/^\.+/, ''); - // Prevent overwriting existing files: - while (_existsSync(options.uploadDir + '/' + this.name)) { - this.name = this.name.replace(nameCountRegexp, nameCountFunc); - } - }; - FileInfo.prototype.initUrls = function (req) { - if (!this.error) { - var that = this, - baseUrl = (options.ssl ? 'https:' : 'http:') + - '//' + req.headers.host + options.uploadUrl; - this.url = this.deleteUrl = baseUrl + encodeURIComponent(this.name); - Object.keys(options.imageVersions).forEach(function (version) { - if (_existsSync( - options.uploadDir + '/' + version + '/' + that.name - )) { - that[version + 'Url'] = baseUrl + version + '/' + - encodeURIComponent(that.name); - } - }); - } - }; - UploadHandler.prototype.get = function () { - var handler = this, - files = []; - fs.readdir(options.uploadDir, function (err, list) { - list.forEach(function (name) { - var stats = fs.statSync(options.uploadDir + '/' + name), - fileInfo; - if (stats.isFile() && name[0] !== '.') { - fileInfo = new FileInfo({ - name: name, - size: stats.size - }); - fileInfo.initUrls(handler.req); - files.push(fileInfo); - } - }); - handler.callback({files: files}); - }); - }; - UploadHandler.prototype.post = function () { - var handler = this, - form = new formidable.IncomingForm(), - tmpFiles = [], - files = [], - map = {}, - counter = 1, - redirect, - finish = function () { - counter -= 1; - if (!counter) { - files.forEach(function (fileInfo) { - fileInfo.initUrls(handler.req); - }); - handler.callback({files: files}, redirect); - } - }; - form.uploadDir = options.tmpDir; - form.on('fileBegin', function (name, file) { - tmpFiles.push(file.path); - var fileInfo = new FileInfo(file, handler.req, true); - fileInfo.safeName(); - map[path.basename(file.path)] = fileInfo; - files.push(fileInfo); - }).on('field', function (name, value) { - if (name === 'redirect') { - redirect = value; - } - }).on('file', function (name, file) { - var fileInfo = map[path.basename(file.path)]; - fileInfo.size = file.size; - if (!fileInfo.validate()) { - fs.unlink(file.path); - return; - } - fs.renameSync(file.path, options.uploadDir + '/' + fileInfo.name); - if (options.imageTypes.test(fileInfo.name)) { - Object.keys(options.imageVersions).forEach(function (version) { - counter += 1; - var opts = options.imageVersions[version]; - imageMagick.resize({ - width: opts.width, - height: opts.height, - srcPath: options.uploadDir + '/' + fileInfo.name, - dstPath: options.uploadDir + '/' + version + '/' + - fileInfo.name - }, finish); - }); - } - }).on('aborted', function () { - tmpFiles.forEach(function (file) { - fs.unlink(file); - }); - }).on('error', function (e) { - console.log(e); - }).on('progress', function (bytesReceived) { - if (bytesReceived > options.maxPostSize) { - handler.req.connection.destroy(); - } - }).on('end', finish).parse(handler.req); - }; - UploadHandler.prototype.destroy = function () { - var handler = this, - fileName; - if (handler.req.url.slice(0, options.uploadUrl.length) === options.uploadUrl) { - fileName = path.basename(decodeURIComponent(handler.req.url)); - if (fileName[0] !== '.') { - fs.unlink(options.uploadDir + '/' + fileName, function (ex) { - Object.keys(options.imageVersions).forEach(function (version) { - fs.unlink(options.uploadDir + '/' + version + '/' + fileName); - }); - handler.callback({success: !ex}); - }); - return; - } - } - handler.callback({success: false}); - }; - if (options.ssl) { - require('https').createServer(options.ssl, serve).listen(port); - } else { - require('http').createServer(serve).listen(port); - } -}(8888)); diff --git a/library/jqupload/server/node/tmp/.gitignore b/library/jqupload/server/node/tmp/.gitignore deleted file mode 100644 index e69de29bb..000000000 diff --git a/library/jqupload/server/php/UploadHandler.php b/library/jqupload/server/php/UploadHandler.php deleted file mode 100644 index 66545b12a..000000000 --- a/library/jqupload/server/php/UploadHandler.php +++ /dev/null @@ -1,1329 +0,0 @@ - 'The uploaded file exceeds the upload_max_filesize directive in php.ini', - 2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form', - 3 => 'The uploaded file was only partially uploaded', - 4 => 'No file was uploaded', - 6 => 'Missing a temporary folder', - 7 => 'Failed to write file to disk', - 8 => 'A PHP extension stopped the file upload', - 'post_max_size' => 'The uploaded file exceeds the post_max_size directive in php.ini', - 'max_file_size' => 'File is too big', - 'min_file_size' => 'File is too small', - 'accept_file_types' => 'Filetype not allowed', - 'max_number_of_files' => 'Maximum number of files exceeded', - 'max_width' => 'Image exceeds maximum width', - 'min_width' => 'Image requires a minimum width', - 'max_height' => 'Image exceeds maximum height', - 'min_height' => 'Image requires a minimum height', - 'abort' => 'File upload aborted', - 'image_resize' => 'Failed to resize image' - ); - - protected $image_objects = array(); - - function __construct($options = null, $initialize = true, $error_messages = null) { - $this->options = array( - 'script_url' => $this->get_full_url().'/', - 'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/files/', - 'upload_url' => $this->get_full_url().'/files/', - 'user_dirs' => false, - 'mkdir_mode' => 0755, - 'param_name' => 'files', - // Set the following option to 'POST', if your server does not support - // DELETE requests. This is a parameter sent to the client: - 'delete_type' => 'DELETE', - 'access_control_allow_origin' => '*', - 'access_control_allow_credentials' => false, - 'access_control_allow_methods' => array( - 'OPTIONS', - 'HEAD', - 'GET', - 'POST', - 'PUT', - 'PATCH', - 'DELETE' - ), - 'access_control_allow_headers' => array( - 'Content-Type', - 'Content-Range', - 'Content-Disposition' - ), - // Enable to provide file downloads via GET requests to the PHP script: - // 1. Set to 1 to download files via readfile method through PHP - // 2. Set to 2 to send a X-Sendfile header for lighttpd/Apache - // 3. Set to 3 to send a X-Accel-Redirect header for nginx - // If set to 2 or 3, adjust the upload_url option to the base path of - // the redirect parameter, e.g. '/files/'. - 'download_via_php' => false, - // Read files in chunks to avoid memory limits when download_via_php - // is enabled, set to 0 to disable chunked reading of files: - 'readfile_chunk_size' => 10 * 1024 * 1024, // 10 MiB - // Defines which files can be displayed inline when downloaded: - 'inline_file_types' => '/\.(gif|jpe?g|png)$/i', - // Defines which files (based on their names) are accepted for upload: - 'accept_file_types' => '/.+$/i', - // The php.ini settings upload_max_filesize and post_max_size - // take precedence over the following max_file_size setting: - 'max_file_size' => null, - 'min_file_size' => 1, - // The maximum number of files for the upload directory: - 'max_number_of_files' => null, - // Defines which files are handled as image files: - 'image_file_types' => '/\.(gif|jpe?g|png)$/i', - // Image resolution restrictions: - 'max_width' => null, - 'max_height' => null, - 'min_width' => 1, - 'min_height' => 1, - // Set the following option to false to enable resumable uploads: - 'discard_aborted_uploads' => true, - // Set to 0 to use the GD library to scale and orient images, - // set to 1 to use imagick (if installed, falls back to GD), - // set to 2 to use the ImageMagick convert binary directly: - 'image_library' => 1, - // Uncomment the following to define an array of resource limits - // for imagick: - /* - 'imagick_resource_limits' => array( - imagick::RESOURCETYPE_MAP => 32, - imagick::RESOURCETYPE_MEMORY => 32 - ), - */ - // Command or path for to the ImageMagick convert binary: - 'convert_bin' => 'convert', - // Uncomment the following to add parameters in front of each - // ImageMagick convert call (the limit constraints seem only - // to have an effect if put in front): - /* - 'convert_params' => '-limit memory 32MiB -limit map 32MiB', - */ - // Command or path for to the ImageMagick identify binary: - 'identify_bin' => 'identify', - 'image_versions' => array( - // The empty image version key defines options for the original image: - '' => array( - // Automatically rotate images based on EXIF meta data: - 'auto_orient' => true - ), - // Uncomment the following to create medium sized images: - /* - 'medium' => array( - 'max_width' => 800, - 'max_height' => 600 - ), - */ - 'thumbnail' => array( - // Uncomment the following to use a defined directory for the thumbnails - // instead of a subdirectory based on the version identifier. - // Make sure that this directory doesn't allow execution of files if you - // don't pose any restrictions on the type of uploaded files, e.g. by - // copying the .htaccess file from the files directory for Apache: - //'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/thumb/', - //'upload_url' => $this->get_full_url().'/thumb/', - // Uncomment the following to force the max - // dimensions and e.g. create square thumbnails: - //'crop' => true, - 'max_width' => 80, - 'max_height' => 80 - ) - ) - ); - if ($options) { - $this->options = $options + $this->options; - } - if ($error_messages) { - $this->error_messages = $error_messages + $this->error_messages; - } - if ($initialize) { - $this->initialize(); - } - } - - protected function initialize() { - switch ($this->get_server_var('REQUEST_METHOD')) { - case 'OPTIONS': - case 'HEAD': - $this->head(); - break; - case 'GET': - $this->get(); - break; - case 'PATCH': - case 'PUT': - case 'POST': - $this->post(); - break; - case 'DELETE': - $this->delete(); - break; - default: - $this->header('HTTP/1.1 405 Method Not Allowed'); - } - } - - protected function get_full_url() { - $https = !empty($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'on') === 0; - return - ($https ? 'https://' : 'http://'). - (!empty($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'].'@' : ''). - (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME']. - ($https && $_SERVER['SERVER_PORT'] === 443 || - $_SERVER['SERVER_PORT'] === 80 ? '' : ':'.$_SERVER['SERVER_PORT']))). - substr($_SERVER['SCRIPT_NAME'],0, strrpos($_SERVER['SCRIPT_NAME'], '/')); - } - - protected function get_user_id() { - @session_start(); - return session_id(); - } - - protected function get_user_path() { - if ($this->options['user_dirs']) { - return $this->get_user_id().'/'; - } - return ''; - } - - protected function get_upload_path($file_name = null, $version = null) { - $file_name = $file_name ? $file_name : ''; - if (empty($version)) { - $version_path = ''; - } else { - $version_dir = @$this->options['image_versions'][$version]['upload_dir']; - if ($version_dir) { - return $version_dir.$this->get_user_path().$file_name; - } - $version_path = $version.'/'; - } - return $this->options['upload_dir'].$this->get_user_path() - .$version_path.$file_name; - } - - protected function get_query_separator($url) { - return strpos($url, '?') === false ? '?' : '&'; - } - - protected function get_download_url($file_name, $version = null, $direct = false) { - if (!$direct && $this->options['download_via_php']) { - $url = $this->options['script_url'] - .$this->get_query_separator($this->options['script_url']) - .$this->get_singular_param_name() - .'='.rawurlencode($file_name); - if ($version) { - $url .= '&version='.rawurlencode($version); - } - return $url.'&download=1'; - } - if (empty($version)) { - $version_path = ''; - } else { - $version_url = @$this->options['image_versions'][$version]['upload_url']; - if ($version_url) { - return $version_url.$this->get_user_path().rawurlencode($file_name); - } - $version_path = rawurlencode($version).'/'; - } - return $this->options['upload_url'].$this->get_user_path() - .$version_path.rawurlencode($file_name); - } - - protected function set_additional_file_properties($file) { - $file->deleteUrl = $this->options['script_url'] - .$this->get_query_separator($this->options['script_url']) - .$this->get_singular_param_name() - .'='.rawurlencode($file->name); - $file->deleteType = $this->options['delete_type']; - if ($file->deleteType !== 'DELETE') { - $file->deleteUrl .= '&_method=DELETE'; - } - if ($this->options['access_control_allow_credentials']) { - $file->deleteWithCredentials = true; - } - } - - // Fix for overflowing signed 32 bit integers, - // works for sizes up to 2^32-1 bytes (4 GiB - 1): - protected function fix_integer_overflow($size) { - if ($size < 0) { - $size += 2.0 * (PHP_INT_MAX + 1); - } - return $size; - } - - protected function get_file_size($file_path, $clear_stat_cache = false) { - if ($clear_stat_cache) { - if (version_compare(PHP_VERSION, '5.3.0') >= 0) { - clearstatcache(true, $file_path); - } else { - clearstatcache(); - } - } - return $this->fix_integer_overflow(filesize($file_path)); - } - - protected function is_valid_file_object($file_name) { - $file_path = $this->get_upload_path($file_name); - if (is_file($file_path) && $file_name[0] !== '.') { - return true; - } - return false; - } - - protected function get_file_object($file_name) { - if ($this->is_valid_file_object($file_name)) { - $file = new stdClass(); - $file->name = $file_name; - $file->size = $this->get_file_size( - $this->get_upload_path($file_name) - ); - $file->url = $this->get_download_url($file->name); - foreach($this->options['image_versions'] as $version => $options) { - if (!empty($version)) { - if (is_file($this->get_upload_path($file_name, $version))) { - $file->{$version.'Url'} = $this->get_download_url( - $file->name, - $version - ); - } - } - } - $this->set_additional_file_properties($file); - return $file; - } - return null; - } - - protected function get_file_objects($iteration_method = 'get_file_object') { - $upload_dir = $this->get_upload_path(); - if (!is_dir($upload_dir)) { - return array(); - } - return array_values(array_filter(array_map( - array($this, $iteration_method), - scandir($upload_dir) - ))); - } - - protected function count_file_objects() { - return count($this->get_file_objects('is_valid_file_object')); - } - - protected function get_error_message($error) { - return array_key_exists($error, $this->error_messages) ? - $this->error_messages[$error] : $error; - } - - function get_config_bytes($val) { - $val = trim($val); - $last = strtolower($val[strlen($val)-1]); - switch($last) { - case 'g': - $val *= 1024; - case 'm': - $val *= 1024; - case 'k': - $val *= 1024; - } - return $this->fix_integer_overflow($val); - } - - protected function validate($uploaded_file, $file, $error, $index) { - if ($error) { - $file->error = $this->get_error_message($error); - return false; - } - $content_length = $this->fix_integer_overflow(intval( - $this->get_server_var('CONTENT_LENGTH') - )); - $post_max_size = $this->get_config_bytes(ini_get('post_max_size')); - if ($post_max_size && ($content_length > $post_max_size)) { - $file->error = $this->get_error_message('post_max_size'); - return false; - } - if (!preg_match($this->options['accept_file_types'], $file->name)) { - $file->error = $this->get_error_message('accept_file_types'); - return false; - } - if ($uploaded_file && is_uploaded_file($uploaded_file)) { - $file_size = $this->get_file_size($uploaded_file); - } else { - $file_size = $content_length; - } - if ($this->options['max_file_size'] && ( - $file_size > $this->options['max_file_size'] || - $file->size > $this->options['max_file_size']) - ) { - $file->error = $this->get_error_message('max_file_size'); - return false; - } - if ($this->options['min_file_size'] && - $file_size < $this->options['min_file_size']) { - $file->error = $this->get_error_message('min_file_size'); - return false; - } - if (is_int($this->options['max_number_of_files']) && ( - $this->count_file_objects() >= $this->options['max_number_of_files']) - ) { - $file->error = $this->get_error_message('max_number_of_files'); - return false; - } - $max_width = @$this->options['max_width']; - $max_height = @$this->options['max_height']; - $min_width = @$this->options['min_width']; - $min_height = @$this->options['min_height']; - if (($max_width || $max_height || $min_width || $min_height)) { - list($img_width, $img_height) = $this->get_image_size($uploaded_file); - } - if (!empty($img_width)) { - if ($max_width && $img_width > $max_width) { - $file->error = $this->get_error_message('max_width'); - return false; - } - if ($max_height && $img_height > $max_height) { - $file->error = $this->get_error_message('max_height'); - return false; - } - if ($min_width && $img_width < $min_width) { - $file->error = $this->get_error_message('min_width'); - return false; - } - if ($min_height && $img_height < $min_height) { - $file->error = $this->get_error_message('min_height'); - return false; - } - } - return true; - } - - protected function upcount_name_callback($matches) { - $index = isset($matches[1]) ? intval($matches[1]) + 1 : 1; - $ext = isset($matches[2]) ? $matches[2] : ''; - return ' ('.$index.')'.$ext; - } - - protected function upcount_name($name) { - return preg_replace_callback( - '/(?:(?: \(([\d]+)\))?(\.[^.]+))?$/', - array($this, 'upcount_name_callback'), - $name, - 1 - ); - } - - protected function get_unique_filename($file_path, $name, $size, $type, $error, - $index, $content_range) { - while(is_dir($this->get_upload_path($name))) { - $name = $this->upcount_name($name); - } - // Keep an existing filename if this is part of a chunked upload: - $uploaded_bytes = $this->fix_integer_overflow(intval($content_range[1])); - while(is_file($this->get_upload_path($name))) { - if ($uploaded_bytes === $this->get_file_size( - $this->get_upload_path($name))) { - break; - } - $name = $this->upcount_name($name); - } - return $name; - } - - protected function trim_file_name($file_path, $name, $size, $type, $error, - $index, $content_range) { - // Remove path information and dots around the filename, to prevent uploading - // into different directories or replacing hidden system files. - // Also remove control characters and spaces (\x00..\x20) around the filename: - $name = trim(basename(stripslashes($name)), ".\x00..\x20"); - // Use a timestamp for empty filenames: - if (!$name) { - $name = str_replace('.', '-', microtime(true)); - } - // Add missing file extension for known image types: - if (strpos($name, '.') === false && - preg_match('/^image\/(gif|jpe?g|png)/', $type, $matches)) { - $name .= '.'.$matches[1]; - } - if (function_exists('exif_imagetype')) { - switch(@exif_imagetype($file_path)){ - case IMAGETYPE_JPEG: - $extensions = array('jpg', 'jpeg'); - break; - case IMAGETYPE_PNG: - $extensions = array('png'); - break; - case IMAGETYPE_GIF: - $extensions = array('gif'); - break; - } - // Adjust incorrect image file extensions: - if (!empty($extensions)) { - $parts = explode('.', $name); - $extIndex = count($parts) - 1; - $ext = strtolower(@$parts[$extIndex]); - if (!in_array($ext, $extensions)) { - $parts[$extIndex] = $extensions[0]; - $name = implode('.', $parts); - } - } - } - return $name; - } - - protected function get_file_name($file_path, $name, $size, $type, $error, - $index, $content_range) { - return $this->get_unique_filename( - $file_path, - $this->trim_file_name($file_path, $name, $size, $type, $error, - $index, $content_range), - $size, - $type, - $error, - $index, - $content_range - ); - } - - protected function handle_form_data($file, $index) { - // Handle form data, e.g. $_REQUEST['description'][$index] - } - - protected function get_scaled_image_file_paths($file_name, $version) { - $file_path = $this->get_upload_path($file_name); - if (!empty($version)) { - $version_dir = $this->get_upload_path(null, $version); - if (!is_dir($version_dir)) { - mkdir($version_dir, $this->options['mkdir_mode'], true); - } - $new_file_path = $version_dir.'/'.$file_name; - } else { - $new_file_path = $file_path; - } - return array($file_path, $new_file_path); - } - - protected function gd_get_image_object($file_path, $func, $no_cache = false) { - if (empty($this->image_objects[$file_path]) || $no_cache) { - $this->gd_destroy_image_object($file_path); - $this->image_objects[$file_path] = $func($file_path); - } - return $this->image_objects[$file_path]; - } - - protected function gd_set_image_object($file_path, $image) { - $this->gd_destroy_image_object($file_path); - $this->image_objects[$file_path] = $image; - } - - protected function gd_destroy_image_object($file_path) { - $image = @$this->image_objects[$file_path]; - return $image && imagedestroy($image); - } - - protected function gd_imageflip($image, $mode) { - if (function_exists('imageflip')) { - return imageflip($image, $mode); - } - $new_width = $src_width = imagesx($image); - $new_height = $src_height = imagesy($image); - $new_img = imagecreatetruecolor($new_width, $new_height); - $src_x = 0; - $src_y = 0; - switch ($mode) { - case '1': // flip on the horizontal axis - $src_y = $new_height - 1; - $src_height = -$new_height; - break; - case '2': // flip on the vertical axis - $src_x = $new_width - 1; - $src_width = -$new_width; - break; - case '3': // flip on both axes - $src_y = $new_height - 1; - $src_height = -$new_height; - $src_x = $new_width - 1; - $src_width = -$new_width; - break; - default: - return $image; - } - imagecopyresampled( - $new_img, - $image, - 0, - 0, - $src_x, - $src_y, - $new_width, - $new_height, - $src_width, - $src_height - ); - return $new_img; - } - - protected function gd_orient_image($file_path, $src_img) { - if (!function_exists('exif_read_data')) { - return false; - } - $exif = @exif_read_data($file_path); - if ($exif === false) { - return false; - } - $orientation = intval(@$exif['Orientation']); - if ($orientation < 2 || $orientation > 8) { - return false; - } - switch ($orientation) { - case 2: - $new_img = $this->gd_imageflip( - $src_img, - defined('IMG_FLIP_VERTICAL') ? IMG_FLIP_VERTICAL : 2 - ); - break; - case 3: - $new_img = imagerotate($src_img, 180, 0); - break; - case 4: - $new_img = $this->gd_imageflip( - $src_img, - defined('IMG_FLIP_HORIZONTAL') ? IMG_FLIP_HORIZONTAL : 1 - ); - break; - case 5: - $tmp_img = $this->gd_imageflip( - $src_img, - defined('IMG_FLIP_HORIZONTAL') ? IMG_FLIP_HORIZONTAL : 1 - ); - $new_img = imagerotate($tmp_img, 270, 0); - imagedestroy($tmp_img); - break; - case 6: - $new_img = imagerotate($src_img, 270, 0); - break; - case 7: - $tmp_img = $this->gd_imageflip( - $src_img, - defined('IMG_FLIP_VERTICAL') ? IMG_FLIP_VERTICAL : 2 - ); - $new_img = imagerotate($tmp_img, 270, 0); - imagedestroy($tmp_img); - break; - case 8: - $new_img = imagerotate($src_img, 90, 0); - break; - default: - return false; - } - $this->gd_set_image_object($file_path, $new_img); - return true; - } - - protected function gd_create_scaled_image($file_name, $version, $options) { - if (!function_exists('imagecreatetruecolor')) { - error_log('Function not found: imagecreatetruecolor'); - return false; - } - list($file_path, $new_file_path) = - $this->get_scaled_image_file_paths($file_name, $version); - $type = strtolower(substr(strrchr($file_name, '.'), 1)); - switch ($type) { - case 'jpg': - case 'jpeg': - $src_func = 'imagecreatefromjpeg'; - $write_func = 'imagejpeg'; - $image_quality = isset($options['jpeg_quality']) ? - $options['jpeg_quality'] : 75; - break; - case 'gif': - $src_func = 'imagecreatefromgif'; - $write_func = 'imagegif'; - $image_quality = null; - break; - case 'png': - $src_func = 'imagecreatefrompng'; - $write_func = 'imagepng'; - $image_quality = isset($options['png_quality']) ? - $options['png_quality'] : 9; - break; - default: - return false; - } - $src_img = $this->gd_get_image_object( - $file_path, - $src_func, - !empty($options['no_cache']) - ); - $image_oriented = false; - if (!empty($options['auto_orient']) && $this->gd_orient_image( - $file_path, - $src_img - )) { - $image_oriented = true; - $src_img = $this->gd_get_image_object( - $file_path, - $src_func - ); - } - $max_width = $img_width = imagesx($src_img); - $max_height = $img_height = imagesy($src_img); - if (!empty($options['max_width'])) { - $max_width = $options['max_width']; - } - if (!empty($options['max_height'])) { - $max_height = $options['max_height']; - } - $scale = min( - $max_width / $img_width, - $max_height / $img_height - ); - if ($scale >= 1) { - if ($image_oriented) { - return $write_func($src_img, $new_file_path, $image_quality); - } - if ($file_path !== $new_file_path) { - return copy($file_path, $new_file_path); - } - return true; - } - if (empty($options['crop'])) { - $new_width = $img_width * $scale; - $new_height = $img_height * $scale; - $dst_x = 0; - $dst_y = 0; - $new_img = imagecreatetruecolor($new_width, $new_height); - } else { - if (($img_width / $img_height) >= ($max_width / $max_height)) { - $new_width = $img_width / ($img_height / $max_height); - $new_height = $max_height; - } else { - $new_width = $max_width; - $new_height = $img_height / ($img_width / $max_width); - } - $dst_x = 0 - ($new_width - $max_width) / 2; - $dst_y = 0 - ($new_height - $max_height) / 2; - $new_img = imagecreatetruecolor($max_width, $max_height); - } - // Handle transparency in GIF and PNG images: - switch ($type) { - case 'gif': - case 'png': - imagecolortransparent($new_img, imagecolorallocate($new_img, 0, 0, 0)); - case 'png': - imagealphablending($new_img, false); - imagesavealpha($new_img, true); - break; - } - $success = imagecopyresampled( - $new_img, - $src_img, - $dst_x, - $dst_y, - 0, - 0, - $new_width, - $new_height, - $img_width, - $img_height - ) && $write_func($new_img, $new_file_path, $image_quality); - $this->gd_set_image_object($file_path, $new_img); - return $success; - } - - protected function imagick_get_image_object($file_path, $no_cache = false) { - if (empty($this->image_objects[$file_path]) || $no_cache) { - $this->imagick_destroy_image_object($file_path); - $image = new Imagick(); - if (!empty($this->options['imagick_resource_limits'])) { - foreach ($this->options['imagick_resource_limits'] as $type => $limit) { - $image->setResourceLimit($type, $limit); - } - } - $image->readImage($file_path); - $this->image_objects[$file_path] = $image; - } - return $this->image_objects[$file_path]; - } - - protected function imagick_set_image_object($file_path, $image) { - $this->imagick_destroy_image_object($file_path); - $this->image_objects[$file_path] = $image; - } - - protected function imagick_destroy_image_object($file_path) { - $image = @$this->image_objects[$file_path]; - return $image && $image->destroy(); - } - - protected function imagick_orient_image($image) { - $orientation = $image->getImageOrientation(); - $background = new ImagickPixel('none'); - switch ($orientation) { - case imagick::ORIENTATION_TOPRIGHT: // 2 - $image->flopImage(); // horizontal flop around y-axis - break; - case imagick::ORIENTATION_BOTTOMRIGHT: // 3 - $image->rotateImage($background, 180); - break; - case imagick::ORIENTATION_BOTTOMLEFT: // 4 - $image->flipImage(); // vertical flip around x-axis - break; - case imagick::ORIENTATION_LEFTTOP: // 5 - $image->flopImage(); // horizontal flop around y-axis - $image->rotateImage($background, 270); - break; - case imagick::ORIENTATION_RIGHTTOP: // 6 - $image->rotateImage($background, 90); - break; - case imagick::ORIENTATION_RIGHTBOTTOM: // 7 - $image->flipImage(); // vertical flip around x-axis - $image->rotateImage($background, 270); - break; - case imagick::ORIENTATION_LEFTBOTTOM: // 8 - $image->rotateImage($background, 270); - break; - default: - return false; - } - $image->setImageOrientation(imagick::ORIENTATION_TOPLEFT); // 1 - return true; - } - - protected function imagick_create_scaled_image($file_name, $version, $options) { - list($file_path, $new_file_path) = - $this->get_scaled_image_file_paths($file_name, $version); - $image = $this->imagick_get_image_object( - $file_path, - !empty($options['no_cache']) - ); - if ($image->getImageFormat() === 'GIF') { - // Handle animated GIFs: - $images = $image->coalesceImages(); - foreach ($images as $frame) { - $image = $frame; - $this->imagick_set_image_object($file_name, $image); - break; - } - } - $image_oriented = false; - if (!empty($options['auto_orient'])) { - $image_oriented = $this->imagick_orient_image($image); - } - $new_width = $max_width = $img_width = $image->getImageWidth(); - $new_height = $max_height = $img_height = $image->getImageHeight(); - if (!empty($options['max_width'])) { - $new_width = $max_width = $options['max_width']; - } - if (!empty($options['max_height'])) { - $new_height = $max_height = $options['max_height']; - } - if (!($image_oriented || $max_width < $img_width || $max_height < $img_height)) { - if ($file_path !== $new_file_path) { - return copy($file_path, $new_file_path); - } - return true; - } - $crop = !empty($options['crop']); - if ($crop) { - $x = 0; - $y = 0; - if (($img_width / $img_height) >= ($max_width / $max_height)) { - $new_width = 0; // Enables proportional scaling based on max_height - $x = ($img_width / ($img_height / $max_height) - $max_width) / 2; - } else { - $new_height = 0; // Enables proportional scaling based on max_width - $y = ($img_height / ($img_width / $max_width) - $max_height) / 2; - } - } - $success = $image->resizeImage( - $new_width, - $new_height, - isset($options['filter']) ? $options['filter'] : imagick::FILTER_LANCZOS, - isset($options['blur']) ? $options['blur'] : 1, - $new_width && $new_height // fit image into constraints if not to be cropped - ); - if ($success && $crop) { - $success = $image->cropImage( - $max_width, - $max_height, - $x, - $y - ); - if ($success) { - $success = $image->setImagePage($max_width, $max_height, 0, 0); - } - } - $type = strtolower(substr(strrchr($file_name, '.'), 1)); - switch ($type) { - case 'jpg': - case 'jpeg': - if (!empty($options['jpeg_quality'])) { - $image->setImageCompression(Imagick::COMPRESSION_JPEG); - $image->setImageCompressionQuality($options['jpeg_quality']); - } - break; - } - if (!empty($options['strip'])) { - $image->stripImage(); - } - return $success && $image->writeImage($new_file_path); - } - - protected function imagemagick_create_scaled_image($file_name, $version, $options) { - list($file_path, $new_file_path) = - $this->get_scaled_image_file_paths($file_name, $version); - $resize = @$options['max_width'] - .(empty($options['max_height']) ? '' : 'x'.$options['max_height']); - if (!$resize && empty($options['auto_orient'])) { - if ($file_path !== $new_file_path) { - return copy($file_path, $new_file_path); - } - return true; - } - $cmd = $this->options['convert_bin']; - if (!empty($this->options['convert_params'])) { - $cmd .= ' '.$this->options['convert_params']; - } - $cmd .= ' '.escapeshellarg($file_path); - if (!empty($options['auto_orient'])) { - $cmd .= ' -auto-orient'; - } - if ($resize) { - // Handle animated GIFs: - $cmd .= ' -coalesce'; - if (empty($options['crop'])) { - $cmd .= ' -resize '.escapeshellarg($resize.'>'); - } else { - $cmd .= ' -resize '.escapeshellarg($resize.'^'); - $cmd .= ' -gravity center'; - $cmd .= ' -crop '.escapeshellarg($resize.'+0+0'); - } - // Make sure the page dimensions are correct (fixes offsets of animated GIFs): - $cmd .= ' +repage'; - } - if (!empty($options['convert_params'])) { - $cmd .= ' '.$options['convert_params']; - } - $cmd .= ' '.escapeshellarg($new_file_path); - exec($cmd, $output, $error); - if ($error) { - error_log(implode('\n', $output)); - return false; - } - return true; - } - - protected function get_image_size($file_path) { - if ($this->options['image_library']) { - if (extension_loaded('imagick')) { - $image = new Imagick(); - try { - if (@$image->pingImage($file_path)) { - $dimensions = array($image->getImageWidth(), $image->getImageHeight()); - $image->destroy(); - return $dimensions; - } - return false; - } catch (Exception $e) { - error_log($e->getMessage()); - } - } - if ($this->options['image_library'] === 2) { - $cmd = $this->options['identify_bin']; - $cmd .= ' -ping '.escapeshellarg($file_path); - exec($cmd, $output, $error); - if (!$error && !empty($output)) { - // image.jpg JPEG 1920x1080 1920x1080+0+0 8-bit sRGB 465KB 0.000u 0:00.000 - $infos = preg_split('/\s+/', $output[0]); - $dimensions = preg_split('/x/', $infos[2]); - return $dimensions; - } - return false; - } - } - if (!function_exists('getimagesize')) { - error_log('Function not found: getimagesize'); - return false; - } - return @getimagesize($file_path); - } - - 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); - } - return $this->gd_create_scaled_image($file_name, $version, $options); - } - - protected function destroy_image_object($file_path) { - if ($this->options['image_library'] && extension_loaded('imagick')) { - return $this->imagick_destroy_image_object($file_path); - } - } - - protected function is_valid_image_file($file_path) { - if (!preg_match($this->options['image_file_types'], $file_path)) { - return false; - } - if (function_exists('exif_imagetype')) { - return @exif_imagetype($file_path); - } - $image_info = $this->get_image_size($file_path); - return $image_info && $image_info[0] && $image_info[1]; - } - - protected function handle_image_file($file_path, $file) { - $failed_versions = array(); - foreach($this->options['image_versions'] as $version => $options) { - if ($this->create_scaled_image($file->name, $version, $options)) { - if (!empty($version)) { - $file->{$version.'Url'} = $this->get_download_url( - $file->name, - $version - ); - } else { - $file->size = $this->get_file_size($file_path, true); - } - } else { - $failed_versions[] = $version ? $version : 'original'; - } - } - if (count($failed_versions)) { - $file->error = $this->get_error_message('image_resize') - .' ('.implode($failed_versions,', ').')'; - } - // Free memory: - $this->destroy_image_object($file_path); - } - - protected function handle_file_upload($uploaded_file, $name, $size, $type, $error, - $index = null, $content_range = null) { - $file = new stdClass(); - $file->name = $this->get_file_name($uploaded_file, $name, $size, $type, $error, - $index, $content_range); - $file->size = $this->fix_integer_overflow(intval($size)); - $file->type = $type; - if ($this->validate($uploaded_file, $file, $error, $index)) { - $this->handle_form_data($file, $index); - $upload_dir = $this->get_upload_path(); - if (!is_dir($upload_dir)) { - mkdir($upload_dir, $this->options['mkdir_mode'], true); - } - $file_path = $this->get_upload_path($file->name); - $append_file = $content_range && is_file($file_path) && - $file->size > $this->get_file_size($file_path); - if ($uploaded_file && is_uploaded_file($uploaded_file)) { - // multipart/formdata uploads (POST method uploads) - if ($append_file) { - file_put_contents( - $file_path, - fopen($uploaded_file, 'r'), - FILE_APPEND - ); - } else { - move_uploaded_file($uploaded_file, $file_path); - } - } else { - // Non-multipart uploads (PUT method support) - file_put_contents( - $file_path, - fopen('php://input', 'r'), - $append_file ? FILE_APPEND : 0 - ); - } - $file_size = $this->get_file_size($file_path, $append_file); - if ($file_size === $file->size) { - $file->url = $this->get_download_url($file->name); - if ($this->is_valid_image_file($file_path)) { - $this->handle_image_file($file_path, $file); - } - } else { - $file->size = $file_size; - if (!$content_range && $this->options['discard_aborted_uploads']) { - unlink($file_path); - $file->error = $this->get_error_message('abort'); - } - } - $this->set_additional_file_properties($file); - } - return $file; - } - - protected function readfile($file_path) { - $file_size = $this->get_file_size($file_path); - $chunk_size = $this->options['readfile_chunk_size']; - if ($chunk_size && $file_size > $chunk_size) { - $handle = fopen($file_path, 'rb'); - while (!feof($handle)) { - echo fread($handle, $chunk_size); - ob_flush(); - flush(); - } - fclose($handle); - return $file_size; - } - return readfile($file_path); - } - - protected function body($str) { - echo $str; - } - - protected function header($str) { - header($str); - } - - protected function get_server_var($id) { - return isset($_SERVER[$id]) ? $_SERVER[$id] : ''; - } - - protected function generate_response($content, $print_response = true) { - if ($print_response) { - $json = json_encode($content); - $redirect = isset($_REQUEST['redirect']) ? - stripslashes($_REQUEST['redirect']) : null; - if ($redirect) { - $this->header('Location: '.sprintf($redirect, rawurlencode($json))); - return; - } - $this->head(); - if ($this->get_server_var('HTTP_CONTENT_RANGE')) { - $files = isset($content[$this->options['param_name']]) ? - $content[$this->options['param_name']] : null; - if ($files && is_array($files) && is_object($files[0]) && $files[0]->size) { - $this->header('Range: 0-'.( - $this->fix_integer_overflow(intval($files[0]->size)) - 1 - )); - } - } - $this->body($json); - } - return $content; - } - - protected function get_version_param() { - return isset($_GET['version']) ? basename(stripslashes($_GET['version'])) : null; - } - - protected function get_singular_param_name() { - return substr($this->options['param_name'], 0, -1); - } - - protected function get_file_name_param() { - $name = $this->get_singular_param_name(); - return isset($_GET[$name]) ? basename(stripslashes($_GET[$name])) : null; - } - - protected function get_file_names_params() { - $params = isset($_GET[$this->options['param_name']]) ? - $_GET[$this->options['param_name']] : array(); - foreach ($params as $key => $value) { - $params[$key] = basename(stripslashes($value)); - } - return $params; - } - - protected function get_file_type($file_path) { - switch (strtolower(pathinfo($file_path, PATHINFO_EXTENSION))) { - case 'jpeg': - case 'jpg': - return 'image/jpeg'; - case 'png': - return 'image/png'; - case 'gif': - return 'image/gif'; - default: - return ''; - } - } - - protected function download() { - switch ($this->options['download_via_php']) { - case 1: - $redirect_header = null; - break; - case 2: - $redirect_header = 'X-Sendfile'; - break; - case 3: - $redirect_header = 'X-Accel-Redirect'; - break; - default: - return $this->header('HTTP/1.1 403 Forbidden'); - } - $file_name = $this->get_file_name_param(); - if (!$this->is_valid_file_object($file_name)) { - return $this->header('HTTP/1.1 404 Not Found'); - } - if ($redirect_header) { - return $this->header( - $redirect_header.': '.$this->get_download_url( - $file_name, - $this->get_version_param(), - true - ) - ); - } - $file_path = $this->get_upload_path($file_name, $this->get_version_param()); - // Prevent browsers from MIME-sniffing the content-type: - $this->header('X-Content-Type-Options: nosniff'); - if (!preg_match($this->options['inline_file_types'], $file_name)) { - $this->header('Content-Type: application/octet-stream'); - $this->header('Content-Disposition: attachment; filename="'.$file_name.'"'); - } else { - $this->header('Content-Type: '.$this->get_file_type($file_path)); - $this->header('Content-Disposition: inline; filename="'.$file_name.'"'); - } - $this->header('Content-Length: '.$this->get_file_size($file_path)); - $this->header('Last-Modified: '.gmdate('D, d M Y H:i:s T', filemtime($file_path))); - $this->readfile($file_path); - } - - protected function send_content_type_header() { - $this->header('Vary: Accept'); - if (strpos($this->get_server_var('HTTP_ACCEPT'), 'application/json') !== false) { - $this->header('Content-type: application/json'); - } else { - $this->header('Content-type: text/plain'); - } - } - - protected function send_access_control_headers() { - $this->header('Access-Control-Allow-Origin: '.$this->options['access_control_allow_origin']); - $this->header('Access-Control-Allow-Credentials: ' - .($this->options['access_control_allow_credentials'] ? 'true' : 'false')); - $this->header('Access-Control-Allow-Methods: ' - .implode(', ', $this->options['access_control_allow_methods'])); - $this->header('Access-Control-Allow-Headers: ' - .implode(', ', $this->options['access_control_allow_headers'])); - } - - public function head() { - $this->header('Pragma: no-cache'); - $this->header('Cache-Control: no-store, no-cache, must-revalidate'); - $this->header('Content-Disposition: inline; filename="files.json"'); - // Prevent Internet Explorer from MIME-sniffing the content-type: - $this->header('X-Content-Type-Options: nosniff'); - if ($this->options['access_control_allow_origin']) { - $this->send_access_control_headers(); - } - $this->send_content_type_header(); - } - - public function get($print_response = true) { - if ($print_response && isset($_GET['download'])) { - return $this->download(); - } - $file_name = $this->get_file_name_param(); - if ($file_name) { - $response = array( - $this->get_singular_param_name() => $this->get_file_object($file_name) - ); - } else { - $response = array( - $this->options['param_name'] => $this->get_file_objects() - ); - } - return $this->generate_response($response, $print_response); - } - - public function post($print_response = true) { - if (isset($_REQUEST['_method']) && $_REQUEST['_method'] === 'DELETE') { - return $this->delete($print_response); - } - $upload = isset($_FILES[$this->options['param_name']]) ? - $_FILES[$this->options['param_name']] : null; - // Parse the Content-Disposition header, if available: - $file_name = $this->get_server_var('HTTP_CONTENT_DISPOSITION') ? - rawurldecode(preg_replace( - '/(^[^"]+")|("$)/', - '', - $this->get_server_var('HTTP_CONTENT_DISPOSITION') - )) : null; - // Parse the Content-Range header, which has the following form: - // Content-Range: bytes 0-524287/2000000 - $content_range = $this->get_server_var('HTTP_CONTENT_RANGE') ? - preg_split('/[^0-9]+/', $this->get_server_var('HTTP_CONTENT_RANGE')) : null; - $size = $content_range ? $content_range[3] : null; - $files = array(); - if ($upload && is_array($upload['tmp_name'])) { - // param_name is an array identifier like "files[]", - // $_FILES is a multi-dimensional array: - foreach ($upload['tmp_name'] as $index => $value) { - $files[] = $this->handle_file_upload( - $upload['tmp_name'][$index], - $file_name ? $file_name : $upload['name'][$index], - $size ? $size : $upload['size'][$index], - $upload['type'][$index], - $upload['error'][$index], - $index, - $content_range - ); - } - } else { - // param_name is a single object identifier like "file", - // $_FILES is a one-dimensional array: - $files[] = $this->handle_file_upload( - isset($upload['tmp_name']) ? $upload['tmp_name'] : null, - $file_name ? $file_name : (isset($upload['name']) ? - $upload['name'] : null), - $size ? $size : (isset($upload['size']) ? - $upload['size'] : $this->get_server_var('CONTENT_LENGTH')), - isset($upload['type']) ? - $upload['type'] : $this->get_server_var('CONTENT_TYPE'), - isset($upload['error']) ? $upload['error'] : null, - null, - $content_range - ); - } - return $this->generate_response( - array($this->options['param_name'] => $files), - $print_response - ); - } - - public function delete($print_response = true) { - $file_names = $this->get_file_names_params(); - if (empty($file_names)) { - $file_names = array($this->get_file_name_param()); - } - $response = array(); - foreach($file_names as $file_name) { - $file_path = $this->get_upload_path($file_name); - $success = is_file($file_path) && $file_name[0] !== '.' && unlink($file_path); - if ($success) { - foreach($this->options['image_versions'] as $version => $options) { - if (!empty($version)) { - $file = $this->get_upload_path($file_name, $version); - if (is_file($file)) { - unlink($file); - } - } - } - } - $response[$file_name] = $success; - } - return $this->generate_response($response, $print_response); - } - -} diff --git a/library/jqupload/server/php/files/.gitignore b/library/jqupload/server/php/files/.gitignore deleted file mode 100644 index e24a60fae..000000000 --- a/library/jqupload/server/php/files/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -* -!.gitignore -!.htaccess diff --git a/library/jqupload/server/php/files/.htaccess b/library/jqupload/server/php/files/.htaccess deleted file mode 100644 index 56689f0bb..000000000 --- a/library/jqupload/server/php/files/.htaccess +++ /dev/null @@ -1,18 +0,0 @@ -# The following directives force the content-type application/octet-stream -# and force browsers to display a download dialog for non-image files. -# This prevents the execution of script files in the context of the website: -ForceType application/octet-stream -Header set Content-Disposition attachment - - ForceType none - Header unset Content-Disposition - - -# The following directive prevents browsers from MIME-sniffing the content-type. -# This is an important complement to the ForceType directive above: -Header set X-Content-Type-Options nosniff - -# Uncomment the following lines to prevent unauthorized download of files: -#AuthName "Authorization required" -#AuthType Basic -#require valid-user diff --git a/library/jqupload/server/php/index.php b/library/jqupload/server/php/index.php deleted file mode 100644 index be29bf479..000000000 --- a/library/jqupload/server/php/index.php +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - -jQuery File Upload Plugin Test - - - - -

    jQuery File Upload Plugin Test

    -

    -
    -

    -
      -
      - -
      - -
      -
      - - - - Add files... - - - - - - - - -
      - -
      - -
      -
      -
      - -
       
      -
      -
      - - -
      -
      - - - - - - - - - - - - - - - - - - - - - - - diff --git a/library/jqupload/test/test.js b/library/jqupload/test/test.js deleted file mode 100644 index 72d08d99e..000000000 --- a/library/jqupload/test/test.js +++ /dev/null @@ -1,1288 +0,0 @@ -/* - * jQuery File Upload Plugin Test 9.4.0 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2010, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -/* global $, QUnit, window, document, expect, module, test, asyncTest, start, ok, strictEqual, notStrictEqual */ - -$(function () { - // jshint nomen:false - 'use strict'; - - QUnit.done = function () { - // Delete all uploaded files: - var url = $('#fileupload').prop('action'); - $.getJSON(url, function (result) { - $.each(result.files, function (index, file) { - $.ajax({ - url: url + '?file=' + encodeURIComponent(file.name), - type: 'DELETE' - }); - }); - }); - }; - - var lifecycle = { - setup: function () { - // Set the .fileupload method to the basic widget method: - $.widget('blueimp.fileupload', window.testBasicWidget, {}); - }, - teardown: function () { - // Remove all remaining event listeners: - $(document).unbind(); - } - }, - lifecycleUI = { - setup: function () { - // Set the .fileupload method to the UI widget method: - $.widget('blueimp.fileupload', window.testUIWidget, {}); - }, - teardown: function () { - // Remove all remaining event listeners: - $(document).unbind(); - } - }; - - module('Initialization', lifecycle); - - test('Widget initialization', function () { - var fu = $('#fileupload').fileupload(); - ok(fu.data('blueimp-fileupload') || fu.data('fileupload')); - }); - - test('Data attribute options', function () { - $('#fileupload').attr('data-url', 'http://example.org'); - $('#fileupload').fileupload(); - strictEqual( - $('#fileupload').fileupload('option', 'url'), - 'http://example.org' - ); - }); - - test('File input initialization', function () { - var fu = $('#fileupload').fileupload(); - ok( - fu.fileupload('option', 'fileInput').length, - 'File input field inside of the widget' - ); - ok( - fu.fileupload('option', 'fileInput').length, - 'Widget element as file input field' - ); - }); - - test('Drop zone initialization', function () { - ok($('#fileupload').fileupload() - .fileupload('option', 'dropZone').length); - }); - - test('Paste zone initialization', function () { - ok($('#fileupload').fileupload() - .fileupload('option', 'pasteZone').length); - }); - - test('Event listeners initialization', function () { - expect( - $.support.xhrFormDataFileUpload ? 4 : 1 - ); - var eo = { - originalEvent: { - dataTransfer: {files: [{}], types: ['Files']}, - clipboardData: {items: [{}]} - } - }, - fu = $('#fileupload').fileupload({ - dragover: function () { - ok(true, 'Triggers dragover callback'); - return false; - }, - drop: function () { - ok(true, 'Triggers drop callback'); - return false; - }, - paste: function () { - ok(true, 'Triggers paste callback'); - return false; - }, - change: function () { - ok(true, 'Triggers change callback'); - return false; - } - }), - fileInput = fu.fileupload('option', 'fileInput'), - dropZone = fu.fileupload('option', 'dropZone'), - pasteZone = fu.fileupload('option', 'pasteZone'); - fileInput.trigger($.Event('change', eo)); - dropZone.trigger($.Event('dragover', eo)); - dropZone.trigger($.Event('drop', eo)); - pasteZone.trigger($.Event('paste', eo)); - }); - - module('API', lifecycle); - - test('destroy', function () { - expect(4); - var eo = { - originalEvent: { - dataTransfer: {files: [{}], types: ['Files']}, - clipboardData: {items: [{}]} - } - }, - options = { - dragover: function () { - ok(true, 'Triggers dragover callback'); - return false; - }, - drop: function () { - ok(true, 'Triggers drop callback'); - return false; - }, - paste: function () { - ok(true, 'Triggers paste callback'); - return false; - }, - change: function () { - ok(true, 'Triggers change callback'); - return false; - } - }, - fu = $('#fileupload').fileupload(options), - fileInput = fu.fileupload('option', 'fileInput'), - dropZone = fu.fileupload('option', 'dropZone'), - pasteZone = fu.fileupload('option', 'pasteZone'); - dropZone.bind('dragover', options.dragover); - dropZone.bind('drop', options.drop); - pasteZone.bind('paste', options.paste); - fileInput.bind('change', options.change); - fu.fileupload('destroy'); - fileInput.trigger($.Event('change', eo)); - dropZone.trigger($.Event('dragover', eo)); - dropZone.trigger($.Event('drop', eo)); - pasteZone.trigger($.Event('paste', eo)); - }); - - test('disable/enable', function () { - expect( - $.support.xhrFormDataFileUpload ? 4 : 1 - ); - var eo = { - originalEvent: { - dataTransfer: {files: [{}], types: ['Files']}, - clipboardData: {items: [{}]} - } - }, - fu = $('#fileupload').fileupload({ - dragover: function () { - ok(true, 'Triggers dragover callback'); - return false; - }, - drop: function () { - ok(true, 'Triggers drop callback'); - return false; - }, - paste: function () { - ok(true, 'Triggers paste callback'); - return false; - }, - change: function () { - ok(true, 'Triggers change callback'); - return false; - } - }), - fileInput = fu.fileupload('option', 'fileInput'), - dropZone = fu.fileupload('option', 'dropZone'), - pasteZone = fu.fileupload('option', 'pasteZone'); - fu.fileupload('disable'); - fileInput.trigger($.Event('change', eo)); - dropZone.trigger($.Event('dragover', eo)); - dropZone.trigger($.Event('drop', eo)); - pasteZone.trigger($.Event('paste', eo)); - fu.fileupload('enable'); - fileInput.trigger($.Event('change', eo)); - dropZone.trigger($.Event('dragover', eo)); - dropZone.trigger($.Event('drop', eo)); - pasteZone.trigger($.Event('paste', eo)); - }); - - test('option', function () { - expect( - $.support.xhrFormDataFileUpload ? 10 : 7 - ); - var eo = { - originalEvent: { - dataTransfer: {files: [{}], types: ['Files']}, - clipboardData: {items: [{}]} - } - }, - fu = $('#fileupload').fileupload({ - dragover: function () { - ok(true, 'Triggers dragover callback'); - return false; - }, - drop: function () { - ok(true, 'Triggers drop callback'); - return false; - }, - paste: function () { - ok(true, 'Triggers paste callback'); - return false; - }, - change: function () { - ok(true, 'Triggers change callback'); - return false; - } - }), - fileInput = fu.fileupload('option', 'fileInput'), - dropZone = fu.fileupload('option', 'dropZone'), - pasteZone = fu.fileupload('option', 'pasteZone'); - fu.fileupload('option', 'fileInput', null); - fu.fileupload('option', 'dropZone', null); - fu.fileupload('option', 'pasteZone', null); - fileInput.trigger($.Event('change', eo)); - dropZone.trigger($.Event('dragover', eo)); - dropZone.trigger($.Event('drop', eo)); - pasteZone.trigger($.Event('paste', eo)); - fu.fileupload('option', 'dropZone', 'body'); - strictEqual( - fu.fileupload('option', 'dropZone')[0], - document.body, - 'Allow a query string as parameter for the dropZone option' - ); - fu.fileupload('option', 'dropZone', document); - strictEqual( - fu.fileupload('option', 'dropZone')[0], - document, - 'Allow a document element as parameter for the dropZone option' - ); - fu.fileupload('option', 'pasteZone', 'body'); - strictEqual( - fu.fileupload('option', 'pasteZone')[0], - document.body, - 'Allow a query string as parameter for the pasteZone option' - ); - fu.fileupload('option', 'pasteZone', document); - strictEqual( - fu.fileupload('option', 'pasteZone')[0], - document, - 'Allow a document element as parameter for the pasteZone option' - ); - fu.fileupload('option', 'fileInput', ':file'); - strictEqual( - fu.fileupload('option', 'fileInput')[0], - $(':file')[0], - 'Allow a query string as parameter for the fileInput option' - ); - fu.fileupload('option', 'fileInput', $(':file')[0]); - strictEqual( - fu.fileupload('option', 'fileInput')[0], - $(':file')[0], - 'Allow a document element as parameter for the fileInput option' - ); - fu.fileupload('option', 'fileInput', fileInput); - fu.fileupload('option', 'dropZone', dropZone); - fu.fileupload('option', 'pasteZone', pasteZone); - fileInput.trigger($.Event('change', eo)); - dropZone.trigger($.Event('dragover', eo)); - dropZone.trigger($.Event('drop', eo)); - pasteZone.trigger($.Event('paste', eo)); - }); - - asyncTest('add', function () { - expect(2); - var param = {files: [{name: 'test'}]}; - $('#fileupload').fileupload({ - add: function (e, data) { - strictEqual( - data.files[0].name, - param.files[0].name, - 'Triggers add callback' - ); - } - }).fileupload('add', param).fileupload( - 'option', - 'add', - function (e, data) { - data.submit().complete(function () { - ok(true, 'data.submit() Returns a jqXHR object'); - start(); - }); - } - ).fileupload('add', param); - }); - - asyncTest('send', function () { - expect(3); - var param = {files: [{name: 'test'}]}; - $('#fileupload').fileupload({ - send: function (e, data) { - strictEqual( - data.files[0].name, - 'test', - 'Triggers send callback' - ); - } - }).fileupload('send', param).fail(function () { - ok(true, 'Allows to abort the request'); - }).complete(function () { - ok(true, 'Returns a jqXHR object'); - start(); - }).abort(); - }); - - module('Callbacks', lifecycle); - - asyncTest('add', function () { - expect(1); - var param = {files: [{name: 'test'}]}; - $('#fileupload').fileupload({ - add: function () { - ok(true, 'Triggers add callback'); - start(); - } - }).fileupload('add', param); - }); - - asyncTest('submit', function () { - expect(1); - var param = {files: [{name: 'test'}]}; - $('#fileupload').fileupload({ - submit: function () { - ok(true, 'Triggers submit callback'); - start(); - return false; - } - }).fileupload('add', param); - }); - - asyncTest('send', function () { - expect(1); - var param = {files: [{name: 'test'}]}; - $('#fileupload').fileupload({ - send: function () { - ok(true, 'Triggers send callback'); - start(); - return false; - } - }).fileupload('send', param); - }); - - asyncTest('done', function () { - expect(1); - var param = {files: [{name: 'test'}]}; - $('#fileupload').fileupload({ - done: function () { - ok(true, 'Triggers done callback'); - start(); - } - }).fileupload('send', param); - }); - - asyncTest('fail', function () { - expect(1); - var param = {files: [{name: 'test'}]}, - fu = $('#fileupload').fileupload({ - url: '404', - fail: function () { - ok(true, 'Triggers fail callback'); - start(); - } - }); - (fu.data('blueimp-fileupload') || fu.data('fileupload')) - ._isXHRUpload = function () { - return true; - }; - fu.fileupload('send', param); - }); - - asyncTest('always', function () { - expect(2); - var param = {files: [{name: 'test'}]}, - counter = 0, - fu = $('#fileupload').fileupload({ - always: function () { - ok(true, 'Triggers always callback'); - if (counter === 1) { - start(); - } else { - counter += 1; - } - } - }); - (fu.data('blueimp-fileupload') || fu.data('fileupload')) - ._isXHRUpload = function () { - return true; - }; - fu.fileupload('add', param).fileupload( - 'option', - 'url', - '404' - ).fileupload('add', param); - }); - - asyncTest('progress', function () { - expect(1); - var param = {files: [{name: 'test'}]}, - counter = 0; - $('#fileupload').fileupload({ - forceIframeTransport: true, - progress: function () { - ok(true, 'Triggers progress callback'); - if (counter === 0) { - start(); - } else { - counter += 1; - } - } - }).fileupload('send', param); - }); - - asyncTest('progressall', function () { - expect(1); - var param = {files: [{name: 'test'}]}, - counter = 0; - $('#fileupload').fileupload({ - forceIframeTransport: true, - progressall: function () { - ok(true, 'Triggers progressall callback'); - if (counter === 0) { - start(); - } else { - counter += 1; - } - } - }).fileupload('send', param); - }); - - asyncTest('start', function () { - expect(1); - var param = {files: [{name: '1'}, {name: '2'}]}, - active = 0; - $('#fileupload').fileupload({ - send: function () { - active += 1; - }, - start: function () { - ok(!active, 'Triggers start callback before uploads'); - start(); - } - }).fileupload('send', param); - }); - - asyncTest('stop', function () { - expect(1); - var param = {files: [{name: '1'}, {name: '2'}]}, - active = 0; - $('#fileupload').fileupload({ - send: function () { - active += 1; - }, - always: function () { - active -= 1; - }, - stop: function () { - ok(!active, 'Triggers stop callback after uploads'); - start(); - } - }).fileupload('send', param); - }); - - test('change', function () { - var fu = $('#fileupload').fileupload(), - fuo = fu.data('blueimp-fileupload') || fu.data('fileupload'), - fileInput = fu.fileupload('option', 'fileInput'); - expect(2); - fu.fileupload({ - change: function (e, data) { - ok(true, 'Triggers change callback'); - strictEqual( - data.files.length, - 0, - 'Returns empty files list' - ); - }, - add: $.noop - }); - fuo._onChange({ - data: {fileupload: fuo}, - target: fileInput[0] - }); - }); - - test('paste', function () { - var fu = $('#fileupload').fileupload(), - fuo = fu.data('blueimp-fileupload') || fu.data('fileupload'); - expect(1); - fu.fileupload({ - paste: function () { - ok(true, 'Triggers paste callback'); - }, - add: $.noop - }); - fuo._onPaste({ - data: {fileupload: fuo}, - originalEvent: { - dataTransfer: {files: [{}]}, - clipboardData: {items: [{}]} - }, - preventDefault: $.noop - }); - }); - - test('drop', function () { - var fu = $('#fileupload').fileupload(), - fuo = fu.data('blueimp-fileupload') || fu.data('fileupload'); - expect(1); - fu.fileupload({ - drop: function () { - ok(true, 'Triggers drop callback'); - }, - add: $.noop - }); - fuo._onDrop({ - data: {fileupload: fuo}, - originalEvent: { - dataTransfer: {files: [{}]}, - clipboardData: {items: [{}]} - }, - preventDefault: $.noop - }); - }); - - test('dragover', function () { - var fu = $('#fileupload').fileupload(), - fuo = fu.data('blueimp-fileupload') || fu.data('fileupload'); - expect(1); - fu.fileupload({ - dragover: function () { - ok(true, 'Triggers dragover callback'); - }, - add: $.noop - }); - fuo._onDragOver({ - data: {fileupload: fuo}, - originalEvent: {dataTransfer: {types: ['Files']}}, - preventDefault: $.noop - }); - }); - - module('Options', lifecycle); - - test('paramName', function () { - expect(1); - var param = {files: [{name: 'test'}]}; - $('#fileupload').fileupload({ - paramName: null, - send: function (e, data) { - strictEqual( - data.paramName[0], - data.fileInput.prop('name'), - 'Takes paramName from file input field if not set' - ); - return false; - } - }).fileupload('send', param); - }); - - test('url', function () { - expect(1); - var param = {files: [{name: 'test'}]}; - $('#fileupload').fileupload({ - url: null, - send: function (e, data) { - strictEqual( - data.url, - $(data.fileInput.prop('form')).prop('action'), - 'Takes url from form action if not set' - ); - return false; - } - }).fileupload('send', param); - }); - - test('type', function () { - expect(2); - var param = {files: [{name: 'test'}]}; - $('#fileupload').fileupload({ - type: null, - send: function (e, data) { - strictEqual( - data.type, - 'POST', - 'Request type is "POST" if not set to "PUT"' - ); - return false; - } - }).fileupload('send', param); - $('#fileupload').fileupload({ - type: 'PUT', - send: function (e, data) { - strictEqual( - data.type, - 'PUT', - 'Request type is "PUT" if set to "PUT"' - ); - return false; - } - }).fileupload('send', param); - }); - - test('replaceFileInput', function () { - var fu = $('#fileupload').fileupload(), - fuo = fu.data('blueimp-fileupload') || fu.data('fileupload'), - fileInput = fu.fileupload('option', 'fileInput'), - fileInputElement = fileInput[0]; - expect(2); - fu.fileupload({ - replaceFileInput: false, - change: function () { - strictEqual( - fu.fileupload('option', 'fileInput')[0], - fileInputElement, - 'Keeps file input with replaceFileInput: false' - ); - }, - add: $.noop - }); - fuo._onChange({ - data: {fileupload: fuo}, - target: fileInput[0] - }); - fu.fileupload({ - replaceFileInput: true, - change: function () { - notStrictEqual( - fu.fileupload('option', 'fileInput')[0], - fileInputElement, - 'Replaces file input with replaceFileInput: true' - ); - }, - add: $.noop - }); - fuo._onChange({ - data: {fileupload: fuo}, - target: fileInput[0] - }); - }); - - asyncTest('forceIframeTransport', function () { - expect(1); - var param = {files: [{name: 'test'}]}; - $('#fileupload').fileupload({ - forceIframeTransport: true, - done: function (e, data) { - strictEqual( - data.dataType.substr(0, 6), - 'iframe', - 'Iframe Transport is used' - ); - start(); - } - }).fileupload('send', param); - }); - - test('singleFileUploads', function () { - expect(3); - var fu = $('#fileupload').fileupload(), - param = {files: [{name: '1'}, {name: '2'}]}, - index = 1; - (fu.data('blueimp-fileupload') || fu.data('fileupload')) - ._isXHRUpload = function () { - return true; - }; - $('#fileupload').fileupload({ - singleFileUploads: true, - add: function () { - ok(true, 'Triggers callback number ' + index.toString()); - index += 1; - } - }).fileupload('add', param).fileupload( - 'option', - 'singleFileUploads', - false - ).fileupload('add', param); - }); - - test('limitMultiFileUploads', function () { - expect(3); - var fu = $('#fileupload').fileupload(), - param = {files: [ - {name: '1'}, - {name: '2'}, - {name: '3'}, - {name: '4'}, - {name: '5'} - ]}, - index = 1; - (fu.data('blueimp-fileupload') || fu.data('fileupload')) - ._isXHRUpload = function () { - return true; - }; - $('#fileupload').fileupload({ - singleFileUploads: false, - limitMultiFileUploads: 2, - add: function () { - ok(true, 'Triggers callback number ' + index.toString()); - index += 1; - } - }).fileupload('add', param); - }); - - test('limitMultiFileUploadSize', function () { - expect(7); - var fu = $('#fileupload').fileupload(), - param = {files: [ - {name: '1-1', size: 100000}, - {name: '1-2', size: 40000}, - {name: '2-1', size: 100000}, - {name: '3-1', size: 50000}, - {name: '3-2', size: 40000}, - {name: '4-1', size: 45000} // New request due to limitMultiFileUploads - ]}, - param2 = {files: [ - {name: '5-1'}, - {name: '5-2'}, - {name: '6-1'}, - {name: '6-2'}, - {name: '7-1'} - ]}, - index = 1; - (fu.data('blueimp-fileupload') || fu.data('fileupload')) - ._isXHRUpload = function () { - return true; - }; - $('#fileupload').fileupload({ - singleFileUploads: false, - limitMultiFileUploads: 2, - limitMultiFileUploadSize: 150000, - limitMultiFileUploadSizeOverhead: 5000, - add: function () { - ok(true, 'Triggers callback number ' + index.toString()); - index += 1; - } - }).fileupload('add', param).fileupload('add', param2); - }); - - asyncTest('sequentialUploads', function () { - expect(6); - var param = {files: [ - {name: '1'}, - {name: '2'}, - {name: '3'}, - {name: '4'}, - {name: '5'}, - {name: '6'} - ]}, - addIndex = 0, - sendIndex = 0, - loadIndex = 0, - fu = $('#fileupload').fileupload({ - sequentialUploads: true, - add: function (e, data) { - addIndex += 1; - if (addIndex === 4) { - data.submit().abort(); - } else { - data.submit(); - } - }, - send: function () { - sendIndex += 1; - }, - done: function () { - loadIndex += 1; - strictEqual(sendIndex, loadIndex, 'upload in order'); - }, - fail: function (e, data) { - strictEqual(data.errorThrown, 'abort', 'upload aborted'); - }, - stop: function () { - start(); - } - }); - (fu.data('blueimp-fileupload') || fu.data('fileupload')) - ._isXHRUpload = function () { - return true; - }; - fu.fileupload('add', param); - }); - - asyncTest('limitConcurrentUploads', function () { - expect(12); - var param = {files: [ - {name: '1'}, - {name: '2'}, - {name: '3'}, - {name: '4'}, - {name: '5'}, - {name: '6'}, - {name: '7'}, - {name: '8'}, - {name: '9'}, - {name: '10'}, - {name: '11'}, - {name: '12'} - ]}, - addIndex = 0, - sendIndex = 0, - loadIndex = 0, - fu = $('#fileupload').fileupload({ - limitConcurrentUploads: 3, - add: function (e, data) { - addIndex += 1; - if (addIndex === 4) { - data.submit().abort(); - } else { - data.submit(); - } - }, - send: function () { - sendIndex += 1; - }, - done: function () { - loadIndex += 1; - ok(sendIndex - loadIndex < 3); - }, - fail: function (e, data) { - strictEqual(data.errorThrown, 'abort', 'upload aborted'); - }, - stop: function () { - start(); - } - }); - (fu.data('blueimp-fileupload') || fu.data('fileupload')) - ._isXHRUpload = function () { - return true; - }; - fu.fileupload('add', param); - }); - - if ($.support.xhrFileUpload) { - asyncTest('multipart', function () { - expect(2); - var param = {files: [{ - name: 'test.png', - size: 123, - type: 'image/png' - }]}, - fu = $('#fileupload').fileupload({ - multipart: false, - always: function (e, data) { - strictEqual( - data.contentType, - param.files[0].type, - 'non-multipart upload sets file type as contentType' - ); - strictEqual( - data.headers['Content-Disposition'], - 'attachment; filename="' + param.files[0].name + '"', - 'non-multipart upload sets Content-Disposition header' - ); - start(); - } - }); - fu.fileupload('send', param); - }); - } - - module('UI Initialization', lifecycleUI); - - test('Widget initialization', function () { - var fu = $('#fileupload').fileupload(); - ok(fu.data('blueimp-fileupload') || fu.data('fileupload')); - ok( - $('#fileupload').fileupload('option', 'uploadTemplate').length, - 'Initialized upload template' - ); - ok( - $('#fileupload').fileupload('option', 'downloadTemplate').length, - 'Initialized download template' - ); - }); - - test('Buttonbar event listeners', function () { - var buttonbar = $('#fileupload .fileupload-buttonbar'), - files = [{name: 'test'}]; - expect(4); - $('#fileupload').fileupload({ - send: function () { - ok(true, 'Started file upload via global start button'); - }, - fail: function (e, data) { - ok(true, 'Canceled file upload via global cancel button'); - data.context.remove(); - }, - destroy: function () { - ok(true, 'Delete action called via global delete button'); - } - }); - $('#fileupload').fileupload('add', {files: files}); - buttonbar.find('.cancel').click(); - $('#fileupload').fileupload('add', {files: files}); - buttonbar.find('.start').click(); - buttonbar.find('.cancel').click(); - files[0].deleteUrl = 'http://example.org/banana.jpg'; - ($('#fileupload').data('blueimp-fileupload') || - $('#fileupload').data('fileupload')) - ._renderDownload(files) - .appendTo($('#fileupload .files')).show() - .find('.toggle').click(); - buttonbar.find('.delete').click(); - }); - - module('UI API', lifecycleUI); - - test('destroy', function () { - var buttonbar = $('#fileupload .fileupload-buttonbar'), - files = [{name: 'test'}]; - expect(1); - $('#fileupload').fileupload({ - send: function () { - ok(true, 'This test should not run'); - return false; - } - }) - .fileupload('add', {files: files}) - .fileupload('destroy'); - buttonbar.find('.start').click(function () { - ok(true, 'Clicked global start button'); - return false; - }).click(); - }); - - test('disable/enable', function () { - var buttonbar = $('#fileupload .fileupload-buttonbar'); - $('#fileupload').fileupload(); - $('#fileupload').fileupload('disable'); - strictEqual( - buttonbar.find('input[type=file], button').not(':disabled').length, - 0, - 'Disables the buttonbar buttons' - ); - $('#fileupload').fileupload('enable'); - strictEqual( - buttonbar.find('input[type=file], button').not(':disabled').length, - 4, - 'Enables the buttonbar buttons' - ); - }); - - module('UI Callbacks', lifecycleUI); - - test('destroy', function () { - expect(3); - $('#fileupload').fileupload({ - destroy: function (e, data) { - ok(true, 'Triggers destroy callback'); - strictEqual( - data.url, - 'test', - 'Passes over deletion url parameter' - ); - strictEqual( - data.type, - 'DELETE', - 'Passes over deletion request type parameter' - ); - } - }); - ($('#fileupload').data('blueimp-fileupload') || - $('#fileupload').data('fileupload')) - ._renderDownload([{ - name: 'test', - deleteUrl: 'test', - deleteType: 'DELETE' - }]) - .appendTo($('#fileupload .files')) - .show() - .find('.toggle').click(); - $('#fileupload .fileupload-buttonbar .delete').click(); - }); - - asyncTest('added', function () { - expect(1); - var param = {files: [{name: 'test'}]}; - $('#fileupload').fileupload({ - added: function (e, data) { - start(); - strictEqual( - data.files[0].name, - param.files[0].name, - 'Triggers added callback' - ); - }, - send: function () { - return false; - } - }).fileupload('add', param); - }); - - asyncTest('started', function () { - expect(1); - var param = {files: [{name: 'test'}]}; - $('#fileupload').fileupload({ - started: function () { - start(); - ok('Triggers started callback'); - return false; - }, - sent: function () { - return false; - } - }).fileupload('send', param); - }); - - asyncTest('sent', function () { - expect(1); - var param = {files: [{name: 'test'}]}; - $('#fileupload').fileupload({ - sent: function (e, data) { - start(); - strictEqual( - data.files[0].name, - param.files[0].name, - 'Triggers sent callback' - ); - return false; - } - }).fileupload('send', param); - }); - - asyncTest('completed', function () { - expect(1); - var param = {files: [{name: 'test'}]}; - $('#fileupload').fileupload({ - completed: function () { - start(); - ok('Triggers completed callback'); - return false; - } - }).fileupload('send', param); - }); - - asyncTest('failed', function () { - expect(1); - var param = {files: [{name: 'test'}]}; - $('#fileupload').fileupload({ - failed: function () { - start(); - ok('Triggers failed callback'); - return false; - } - }).fileupload('send', param).abort(); - }); - - asyncTest('stopped', function () { - expect(1); - var param = {files: [{name: 'test'}]}; - $('#fileupload').fileupload({ - stopped: function () { - start(); - ok('Triggers stopped callback'); - return false; - } - }).fileupload('send', param); - }); - - asyncTest('destroyed', function () { - expect(1); - $('#fileupload').fileupload({ - dataType: 'html', - destroyed: function () { - start(); - ok(true, 'Triggers destroyed callback'); - } - }); - ($('#fileupload').data('blueimp-fileupload') || - $('#fileupload').data('fileupload')) - ._renderDownload([{ - name: 'test', - deleteUrl: '.', - deleteType: 'GET' - }]) - .appendTo($('#fileupload .files')) - .show() - .find('.toggle').click(); - $('#fileupload .fileupload-buttonbar .delete').click(); - }); - - module('UI Options', lifecycleUI); - - test('autoUpload', function () { - expect(1); - $('#fileupload') - .fileupload({ - autoUpload: true, - send: function () { - ok(true, 'Started file upload automatically'); - return false; - } - }) - .fileupload('add', {files: [{name: 'test'}]}) - .fileupload('option', 'autoUpload', false) - .fileupload('add', {files: [{name: 'test'}]}); - }); - - test('maxNumberOfFiles', function () { - expect(3); - var addIndex = 0, - sendIndex = 0; - $('#fileupload') - .fileupload({ - autoUpload: true, - maxNumberOfFiles: 3, - singleFileUploads: false, - send: function () { - strictEqual( - sendIndex += 1, - addIndex - ); - }, - progress: $.noop, - progressall: $.noop, - done: $.noop, - stop: $.noop - }) - .fileupload('add', {files: [{name: (addIndex += 1)}]}) - .fileupload('add', {files: [{name: (addIndex += 1)}]}) - .fileupload('add', {files: [{name: (addIndex += 1)}]}) - .fileupload('add', {files: [{name: 'test'}]}); - }); - - test('maxFileSize', function () { - expect(2); - var addIndex = 0, - sendIndex = 0; - $('#fileupload') - .fileupload({ - autoUpload: true, - maxFileSize: 1000, - send: function () { - strictEqual( - sendIndex += 1, - addIndex - ); - return false; - } - }) - .fileupload('add', {files: [{ - name: (addIndex += 1) - }]}) - .fileupload('add', {files: [{ - name: (addIndex += 1), - size: 999 - }]}) - .fileupload('add', {files: [{ - name: 'test', - size: 1001 - }]}) - .fileupload({ - send: function (e, data) { - ok( - !$.blueimp.fileupload.prototype.options - .send.call(this, e, data) - ); - return false; - } - }); - }); - - test('minFileSize', function () { - expect(2); - var addIndex = 0, - sendIndex = 0; - $('#fileupload') - .fileupload({ - autoUpload: true, - minFileSize: 1000, - send: function () { - strictEqual( - sendIndex += 1, - addIndex - ); - return false; - } - }) - .fileupload('add', {files: [{ - name: (addIndex += 1) - }]}) - .fileupload('add', {files: [{ - name: (addIndex += 1), - size: 1001 - }]}) - .fileupload('add', {files: [{ - name: 'test', - size: 999 - }]}) - .fileupload({ - send: function (e, data) { - ok( - !$.blueimp.fileupload.prototype.options - .send.call(this, e, data) - ); - return false; - } - }); - }); - - test('acceptFileTypes', function () { - expect(2); - var addIndex = 0, - sendIndex = 0; - $('#fileupload') - .fileupload({ - autoUpload: true, - acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i, - disableImageMetaDataLoad: true, - send: function () { - strictEqual( - sendIndex += 1, - addIndex - ); - return false; - } - }) - .fileupload('add', {files: [{ - name: (addIndex += 1) + '.jpg' - }]}) - .fileupload('add', {files: [{ - name: (addIndex += 1), - type: 'image/jpeg' - }]}) - .fileupload('add', {files: [{ - name: 'test.txt', - type: 'text/plain' - }]}) - .fileupload({ - send: function (e, data) { - ok( - !$.blueimp.fileupload.prototype.options - .send.call(this, e, data) - ); - return false; - } - }); - }); - - test('acceptFileTypes as HTML5 data attribute', function () { - expect(2); - var regExp = /(\.|\/)(gif|jpe?g|png)$/i; - $('#fileupload') - .attr('data-accept-file-types', regExp.toString()) - .fileupload(); - strictEqual( - $.type($('#fileupload').fileupload('option', 'acceptFileTypes')), - $.type(regExp) - ); - strictEqual( - $('#fileupload').fileupload('option', 'acceptFileTypes').toString(), - regExp.toString() - ); - }); - -}); diff --git a/mail.png b/mail.png new file mode 100755 index 000000000..b981becf0 Binary files /dev/null and b/mail.png differ diff --git a/noti.png b/noti.png new file mode 100755 index 000000000..45c7ee00d Binary files /dev/null and b/noti.png differ diff --git a/people.png b/people.png new file mode 100755 index 000000000..b00625c8e Binary files /dev/null and b/people.png differ diff --git a/picture/Activitypub.png b/picture/Activitypub.png new file mode 100755 index 000000000..a62824bb3 Binary files /dev/null and b/picture/Activitypub.png differ diff --git a/picture/P&C.png b/picture/P&C.png new file mode 100755 index 000000000..42ee57ff4 Binary files /dev/null and b/picture/P&C.png differ diff --git a/picture/background.png b/picture/background.png new file mode 100755 index 000000000..967ed7979 Binary files /dev/null and b/picture/background.png differ diff --git a/picture/category.png b/picture/category.png new file mode 100755 index 000000000..f8acf87b9 Binary files /dev/null and b/picture/category.png differ diff --git a/picture/harukin+.png b/picture/harukin+.png new file mode 100755 index 000000000..284bb2c0a Binary files /dev/null and b/picture/harukin+.png differ diff --git a/picture/harukin+Black.png b/picture/harukin+Black.png new file mode 100755 index 000000000..855d30868 Binary files /dev/null and b/picture/harukin+Black.png differ diff --git a/picture/harukin+Black2.png b/picture/harukin+Black2.png new file mode 100755 index 000000000..cbd756c04 Binary files /dev/null and b/picture/harukin+Black2.png differ diff --git a/picture/icon.png b/picture/icon.png new file mode 100755 index 000000000..5e16408b5 Binary files /dev/null and b/picture/icon.png differ diff --git a/topsite.css b/topsite.css new file mode 100755 index 000000000..7fcc4857c --- /dev/null +++ b/topsite.css @@ -0,0 +1,82 @@ +main h1,main h2{ + text-align: center; +} +.signup,.login{ + width:30vw; + margin-top: 10px; + margin-bottom: 10px; + /*font-size: 40px;*/ + +} +.pubstream{ + width:60vw; + margin-top: 10px; + margin-bottom: 10px; + /*font-size: 40px;*/ + +} +.button{ + display: inline-table; + margin: 5px; + background-color: rgb(85, 85, 85); + border-style: ridge; + border-color: rgb(93, 94, 95); +} +.position{ + text-align: center; +} +html{ + background: url("./picture/background.png")center center / cover no-repeat fixed; +} +body{ + /*background: rgba(236, 106, 241, 0.747);*/ + color: azure; + margin: 0px; + width:100%; + height: 100%; + +} +a:link{ + color: azure; + text-decoration: none; +} +.br10{ + height: 10px; + clear: left; +} + +/*box*/ +.mainbox{ + transform:skewY(-5deg); + width:100%; +} +.mainbox div{ + position: relative; +} +.mainbox .picturearea{ + transform:skewY(5deg); + height:50vw; + width:100%; +} +.mainbox .textarea{ + transform:skewY(5deg); +} +@media screen and (min-width: 700px) { + .mainbox{ + transform:skewY(-5deg); + width:100%; + overflow: hidden; + } + .mainbox div{ + display: table-cell; + } + .mainbox .picturearea{ + width: 50vw; + transform:skewY(5deg); + height: unset; + } + .mainbox .textarea{ + transform:skewY(5deg); + width: 50vw; + } +} \ No newline at end of file diff --git a/topsite.html b/topsite.html new file mode 100755 index 000000000..22d4068a3 --- /dev/null +++ b/topsite.html @@ -0,0 +1,102 @@ + + + + + Harukin+! + + + + + + + + +
      + +
      +
      +

      +
      + +
      +

      +

      +

      +

      +

      +

      +
      +

      +

      +
      +

      hello.Harukin+! from hubzilla

      + +
      +
      +

      +

      お待たせしました。分散型という選択肢。

      + +
      +

      +
      +

      +
      +
      +
      +

      +

      ポスト/コメントのバランスのよい配置

      +

      +

      hubzillaはFacebookやGoogle+と同じポスト+コメントのスタイルを継承しています。

      +

      投稿の主従関係を明確にし、話題の脱線を防ぎ有意義な会話を実現します。

      +

      +
      +
      +

      +
      +
      +
      +

      +

      豊富な、豊富すぎる機能たち

      +

      +

      Google+で人気なサークル概念やコレクション機能を独自名にて内包しており、投稿andフォロワーの整理ができます。

      +

      もちろん特定人物(複数)に送信することやサークルの仲間全員に送信などをすることもできます。

      +

      ファイルフォーマットに限度は無し、BBcodeで自分の投稿内容に装飾を加えることができます。

      +

      +
      +
      +

      +
      +
      +
      +

      +

      繋がりを求めて

      +

      +

      hubzillaでは独自開発の協力な分散プロトコルZotをはじめ、MastodonやMisskey,Pleromaでお馴染みのActivityPub、Diaspora、OStatusのクアッドチャンネルを持ちます。

      +

      この協力な連合ネットワークによってここに居るだけで他の大量のサーバーと通信ができます。(Zot以外は任意なので意図せず公開されることはありません)

      +

      対象サービス(リストはマストドンwikiより転載) : GNU Social Friendica diaspora Misskey Hubzilla Mastodon postActiv + Sosialhome + Aardwolf Pleroma GangGo PixelFed

      +

      + +

      +
      +
      + +
      +
      + +
      + + + \ No newline at end of file diff --git a/util/hmessages.po b/util/hmessages.po index d1baafded..9561cab2b 100644 --- a/util/hmessages.po +++ b/util/hmessages.po @@ -10851,66 +10851,6 @@ msgstr "" msgid "Until modified date yyyy-mm-dd" msgstr "" -#: ../../addon/gravatar/gravatar.php:123 -msgid "generic profile image" -msgstr "" - -#: ../../addon/gravatar/gravatar.php:124 -msgid "random geometric pattern" -msgstr "" - -#: ../../addon/gravatar/gravatar.php:125 -msgid "monster face" -msgstr "" - -#: ../../addon/gravatar/gravatar.php:126 -msgid "computer generated face" -msgstr "" - -#: ../../addon/gravatar/gravatar.php:127 -msgid "retro arcade style face" -msgstr "" - -#: ../../addon/gravatar/gravatar.php:128 -msgid "Hub default profile photo" -msgstr "" - -#: ../../addon/gravatar/gravatar.php:143 -msgid "Information" -msgstr "" - -#: ../../addon/gravatar/gravatar.php:143 -msgid "" -"Libravatar addon is installed, too. Please disable Libravatar addon or this " -"Gravatar addon.
      The Libravatar addon will fall back to Gravatar if " -"nothing was found at Libravatar." -msgstr "" - -#: ../../addon/gravatar/gravatar.php:150 ../../addon/msgfooter/msgfooter.php:46 -#: ../../addon/xmpp/xmpp.php:91 -msgid "Save Settings" -msgstr "" - -#: ../../addon/gravatar/gravatar.php:151 -msgid "Default avatar image" -msgstr "" - -#: ../../addon/gravatar/gravatar.php:151 -msgid "Select default avatar image if none was found at Gravatar. See README" -msgstr "" - -#: ../../addon/gravatar/gravatar.php:152 -msgid "Rating of images" -msgstr "" - -#: ../../addon/gravatar/gravatar.php:152 -msgid "Select the appropriate avatar rating for your site. See README" -msgstr "" - -#: ../../addon/gravatar/gravatar.php:165 -msgid "Gravatar settings updated." -msgstr "" - #: ../../addon/visage/visage.php:93 msgid "Recent Channel/Profile Viewers" msgstr "" @@ -11866,13 +11806,17 @@ msgstr "" #: ../../addon/twitter/twitter.php:187 msgid "" -"Or become a project sponsor (Hubzilla Project only)" +"No consumer key pair for Twitter found. Please contact your site " +"administrator." msgstr "" #: ../../addon/twitter/twitter.php:209 msgid "" -"Please indicate if you would like your first name or full name (or nothing) " -"to appear in our sponsor listing" +"At this Hubzilla instance the Twitter plugin was enabled but you have not " +"yet connected your account to your Twitter account. To do so click the " +"button below to get a PIN from Twitter which you have to copy into the input " +"box below and submit the form. Only your public posts will " +"be posted to Twitter." msgstr "" #: ../../addon/twitter/twitter.php:211 @@ -11885,11 +11829,10 @@ msgstr "" #: ../../addon/twitter/twitter.php:241 msgid "" -"This is a fairly comprehensive and complete guitar chord dictionary which " -"will list most of the available ways to play a certain chord, starting from " -"the base of the fingerboard up to a few frets beyond the twelfth fret " -"(beyond which everything repeats). A couple of non-standard tunings are " -"provided for the benefit of slide players, etc." +"Note: Due your privacy settings (Hide your profile " +"details from unknown viewers?) the link potentially included in public " +"postings relayed to Twitter will lead the visitor to a blank page informing " +"the visitor that the access to your profile has been restricted." msgstr "" #: ../../addon/twitter/twitter.php:246 @@ -14352,11 +14295,9 @@ msgstr "" #: ../../include/bbcode.php:259 #, php-format -msgid "You have reached your limit of %1$.0f Mbytes attachment storage." -msgstr "" - -#: ../../include/bbcode.php:331 -msgid "card" +msgid "" +"This post contains an installable %s element, however you lack permissions " +"to install it on this site." msgstr "" #: ../../include/bbcode.php:350 diff --git a/util/update_autoloader b/util/update_autoloader deleted file mode 100755 index 1e65bed5c..000000000 --- a/util/update_autoloader +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash -f - -composer install --optimize-autoloader --no-dev diff --git a/util/update_theme_repo b/util/update_theme_repo index 3d3cafe84..b4de55568 100755 --- a/util/update_theme_repo +++ b/util/update_theme_repo @@ -2,7 +2,6 @@ set -f -set -f if [ $# -ne 1 ]; then echo usage: $0 repository diff --git a/util/zotsh/zotsh.py b/util/zotsh/zotsh.py index d5e1aa527..36506b39d 100755 --- a/util/zotsh/zotsh.py +++ b/util/zotsh/zotsh.py @@ -55,7 +55,7 @@ class ZotSH(object): @session.setter def session(self, session): self._session = session - self.davclient = easywebdav.connect( self.hostname, protocol='https', session=session, path="dav", verify_ssl=VERIFY_SSL) + self.davclient = easywebdav.connect( self.hostname, protocol='https', session=session, path="cloud", verify_ssl=VERIFY_SSL) @property def PS1(self): @@ -205,7 +205,7 @@ class ZotSH(object): print _fmt('d', 0, "../") for f in r: - name = f.name.replace("/dav"+self.davclient.cwd,"") + name = f.name.replace("/cloud"+self.davclient.cwd,"") type = "-" if name.endswith("/"): type = "d" diff --git a/view/es-es/hmessages.po b/view/es-es/hmessages.po index a57d634bc..f2c1ccf79 100644 --- a/view/es-es/hmessages.po +++ b/view/es-es/hmessages.po @@ -3,7 +3,7 @@ # This file is distributed under the same license as the hubzilla package. # # Translators: -# alfonsomthd , 2015 +# Alfonso Martínez , 2015 # inboxwall , 2015 # jeroenpraat , 2015 # Manuel Jiménez Friaza , 2017-2018 @@ -14,8 +14,8 @@ msgid "" msgstr "" "Project-Id-Version: hubzilla\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-06 17:07+0200\n" -"PO-Revision-Date: 2018-10-11 10:13+0000\n" +"POT-Creation-Date: 2018-10-19 11:04+0200\n" +"PO-Revision-Date: 2018-10-24 11:35+0000\n" "Last-Translator: Manuel Jiménez Friaza \n" "Language-Team: Spanish (Spain) (http://www.transifex.com/Friendica/hubzilla/language/es_ES/)\n" "MIME-Version: 1.0\n" @@ -158,9 +158,9 @@ msgstr "Especial - Repositorio de grupo" #: ../../Zotlabs/Access/PermissionRoles.php:306 #: ../../Zotlabs/Module/Cdav.php:1227 ../../Zotlabs/Module/Connedit.php:919 -#: ../../Zotlabs/Module/Profiles.php:795 ../../include/selectors.php:49 -#: ../../include/selectors.php:66 ../../include/selectors.php:104 -#: ../../include/selectors.php:140 ../../include/event.php:1315 +#: ../../Zotlabs/Module/Profiles.php:795 ../../include/selectors.php:60 +#: ../../include/selectors.php:77 ../../include/selectors.php:115 +#: ../../include/selectors.php:151 ../../include/event.php:1315 #: ../../include/event.php:1322 ../../include/connections.php:703 #: ../../include/connections.php:710 msgid "Other" @@ -202,7 +202,7 @@ msgstr "El perfil solicitado no está disponible." #: ../../Zotlabs/Module/Mood.php:124 ../../Zotlabs/Module/Connections.php:32 #: ../../Zotlabs/Module/Viewsrc.php:19 ../../Zotlabs/Module/Bookmarks.php:70 #: ../../Zotlabs/Module/Photos.php:69 ../../Zotlabs/Module/Wiki.php:59 -#: ../../Zotlabs/Module/Wiki.php:282 ../../Zotlabs/Module/Wiki.php:415 +#: ../../Zotlabs/Module/Wiki.php:285 ../../Zotlabs/Module/Wiki.php:428 #: ../../Zotlabs/Module/Pdledit.php:34 ../../Zotlabs/Module/Poke.php:157 #: ../../Zotlabs/Module/Profile_photo.php:302 #: ../../Zotlabs/Module/Profile_photo.php:315 @@ -229,7 +229,7 @@ msgstr "El perfil solicitado no está disponible." #: ../../Zotlabs/Module/Register.php:77 #: ../../Zotlabs/Module/Cover_photo.php:313 #: ../../Zotlabs/Module/Cover_photo.php:326 -#: ../../Zotlabs/Module/Display.php:449 ../../Zotlabs/Module/Network.php:17 +#: ../../Zotlabs/Module/Display.php:448 ../../Zotlabs/Module/Network.php:17 #: ../../Zotlabs/Module/Filestorage.php:15 #: ../../Zotlabs/Module/Filestorage.php:70 #: ../../Zotlabs/Module/Filestorage.php:96 @@ -291,7 +291,7 @@ msgstr "Crear" #: ../../Zotlabs/Module/Connections.php:284 #: ../../Zotlabs/Module/Connections.php:322 #: ../../Zotlabs/Module/Connections.php:342 ../../Zotlabs/Module/Wiki.php:211 -#: ../../Zotlabs/Module/Wiki.php:371 ../../Zotlabs/Module/Menu.php:175 +#: ../../Zotlabs/Module/Wiki.php:384 ../../Zotlabs/Module/Menu.php:175 #: ../../Zotlabs/Module/Layouts.php:193 ../../Zotlabs/Module/Group.php:235 #: ../../Zotlabs/Module/Editwebpage.php:142 #: ../../Zotlabs/Module/Webpages.php:255 ../../Zotlabs/Module/Card_edit.php:99 @@ -304,7 +304,7 @@ msgid "Edit" msgstr "Editar" #: ../../Zotlabs/Module/Blocks.php:161 ../../Zotlabs/Module/Photos.php:1104 -#: ../../Zotlabs/Module/Wiki.php:296 ../../Zotlabs/Module/Layouts.php:194 +#: ../../Zotlabs/Module/Wiki.php:301 ../../Zotlabs/Module/Layouts.php:194 #: ../../Zotlabs/Module/Webpages.php:256 ../../Zotlabs/Widget/Cdav.php:124 #: ../../addon/hsse/hsse.php:186 ../../include/conversation.php:1389 msgid "Share" @@ -330,7 +330,7 @@ msgid "Delete" msgstr "Eliminar" #: ../../Zotlabs/Module/Blocks.php:166 ../../Zotlabs/Module/Events.php:695 -#: ../../Zotlabs/Module/Wiki.php:213 ../../Zotlabs/Module/Wiki.php:396 +#: ../../Zotlabs/Module/Wiki.php:213 ../../Zotlabs/Module/Wiki.php:409 #: ../../Zotlabs/Module/Layouts.php:198 ../../Zotlabs/Module/Webpages.php:261 #: ../../Zotlabs/Module/Pubsites.php:60 msgid "View" @@ -448,7 +448,7 @@ msgstr "3. Pulse [conectar]" #: ../../Zotlabs/Module/Admin/Profs.php:178 #: ../../Zotlabs/Module/Admin/Account_edit.php:73 #: ../../Zotlabs/Module/Admin/Security.php:112 -#: ../../Zotlabs/Module/Settings/Channel.php:511 +#: ../../Zotlabs/Module/Settings/Channel.php:493 #: ../../Zotlabs/Module/Settings/Features.php:46 #: ../../Zotlabs/Module/Settings/Events.php:41 #: ../../Zotlabs/Module/Settings/Calendar.php:41 @@ -456,10 +456,10 @@ msgstr "3. Pulse [conectar]" #: ../../Zotlabs/Module/Settings/Connections.php:41 #: ../../Zotlabs/Module/Settings/Photos.php:41 #: ../../Zotlabs/Module/Settings/Account.php:103 -#: ../../Zotlabs/Module/Settings/Profiles.php:41 +#: ../../Zotlabs/Module/Settings/Profiles.php:50 #: ../../Zotlabs/Module/Settings/Manage.php:41 #: ../../Zotlabs/Module/Settings/Featured.php:54 -#: ../../Zotlabs/Module/Settings/Channel_home.php:61 +#: ../../Zotlabs/Module/Settings/Channel_home.php:89 #: ../../Zotlabs/Module/Settings/Directory.php:41 #: ../../Zotlabs/Module/Settings/Editor.php:41 #: ../../Zotlabs/Module/Settings/Display.php:189 @@ -473,7 +473,7 @@ msgstr "3. Pulse [conectar]" #: ../../Zotlabs/Module/Poke.php:217 ../../Zotlabs/Module/Connedit.php:888 #: ../../Zotlabs/Module/Chat.php:211 ../../Zotlabs/Module/Chat.php:250 #: ../../Zotlabs/Module/Email_validation.php:40 -#: ../../Zotlabs/Module/Pconfig.php:107 ../../Zotlabs/Module/Defperms.php:265 +#: ../../Zotlabs/Module/Pconfig.php:111 ../../Zotlabs/Module/Defperms.php:265 #: ../../Zotlabs/Module/Group.php:140 ../../Zotlabs/Module/Group.php:156 #: ../../Zotlabs/Module/Profiles.php:723 ../../Zotlabs/Module/Editpost.php:85 #: ../../Zotlabs/Module/Sources.php:125 ../../Zotlabs/Module/Sources.php:162 @@ -481,8 +481,8 @@ msgstr "3. Pulse [conectar]" #: ../../Zotlabs/Module/Filestorage.php:183 ../../Zotlabs/Module/Rate.php:166 #: ../../Zotlabs/Module/Oauth.php:111 ../../Zotlabs/Lib/ThreadItem.php:767 #: ../../Zotlabs/Widget/Eventstools.php:16 -#: ../../Zotlabs/Widget/Wiki_pages.php:40 -#: ../../Zotlabs/Widget/Wiki_pages.php:97 +#: ../../Zotlabs/Widget/Wiki_pages.php:42 +#: ../../Zotlabs/Widget/Wiki_pages.php:99 #: ../../view/theme/redbasic_c/php/config.php:95 #: ../../view/theme/redbasic/php/config.php:94 #: ../../addon/skeleton/skeleton.php:65 ../../addon/planets/planets.php:153 @@ -513,7 +513,7 @@ msgstr "3. Pulse [conectar]" #: ../../addon/cart/Settings/Cart.php:114 ../../addon/cart/cart.php:1263 #: ../../addon/cart/submodules/manualcat.php:248 #: ../../addon/cart/submodules/hzservices.php:640 -#: ../../addon/cart/submodules/subscriptions.php:401 +#: ../../addon/cart/submodules/subscriptions.php:410 #: ../../addon/piwik/piwik.php:95 ../../addon/pageheader/pageheader.php:48 #: ../../addon/xmpp/xmpp.php:69 ../../addon/pumpio/pumpio.php:237 #: ../../addon/redfiles/redfiles.php:124 ../../addon/hubwall/hubwall.php:95 @@ -534,7 +534,7 @@ msgid "Add Article" msgstr "Añadir un artículo" #: ../../Zotlabs/Module/Articles.php:214 ../../Zotlabs/Lib/Apps.php:302 -#: ../../include/nav.php:477 +#: ../../include/nav.php:482 msgid "Articles" msgstr "Artículos" @@ -567,8 +567,8 @@ msgstr "Modificar la plantilla" #: ../../Zotlabs/Module/Article_edit.php:131 #: ../../Zotlabs/Module/Admin/Addons.php:423 #: ../../Zotlabs/Module/Oauth2.php:117 ../../Zotlabs/Module/Oauth2.php:145 -#: ../../Zotlabs/Module/Editblock.php:141 ../../Zotlabs/Module/Wiki.php:356 -#: ../../Zotlabs/Module/Wiki.php:388 +#: ../../Zotlabs/Module/Editblock.php:141 ../../Zotlabs/Module/Wiki.php:368 +#: ../../Zotlabs/Module/Wiki.php:401 #: ../../Zotlabs/Module/Profile_photo.php:465 #: ../../Zotlabs/Module/Connedit.php:925 ../../Zotlabs/Module/Fbrowser.php:66 #: ../../Zotlabs/Module/Fbrowser.php:88 ../../Zotlabs/Module/Profiles.php:801 @@ -633,7 +633,7 @@ msgstr "Resumen: " #: ../../Zotlabs/Lib/Activity.php:858 ../../Zotlabs/Lib/Apps.php:994 #: ../../Zotlabs/Lib/Apps.php:1078 ../../Zotlabs/Storage/Browser.php:164 #: ../../Zotlabs/Widget/Portfolio.php:95 ../../Zotlabs/Widget/Album.php:84 -#: ../../addon/pubcrawl/as.php:964 ../../include/conversation.php:1166 +#: ../../addon/pubcrawl/as.php:963 ../../include/conversation.php:1166 msgid "Unknown" msgstr "Desconocido" @@ -769,7 +769,7 @@ msgstr "¡Disculpas! La edición de eventos recurrentes aún no se ha implementa #: ../../Zotlabs/Module/Wiki.php:218 ../../Zotlabs/Module/Connedit.php:907 #: ../../Zotlabs/Module/Chat.php:259 ../../Zotlabs/Module/Group.php:144 #: ../../Zotlabs/Module/Oauth.php:113 ../../Zotlabs/Module/Oauth.php:139 -#: ../../Zotlabs/Lib/NativeWikiPage.php:558 +#: ../../Zotlabs/Lib/NativeWikiPage.php:561 #: ../../Zotlabs/Storage/Browser.php:285 #: ../../Zotlabs/Widget/Wiki_page_history.php:22 #: ../../addon/rendezvous/rendezvous.php:172 @@ -795,7 +795,7 @@ msgstr "Teléfono" #: ../../Zotlabs/Module/Connedit.php:911 ../../Zotlabs/Module/Profiles.php:787 #: ../../addon/openid/MysqlProvider.php:56 #: ../../addon/openid/MysqlProvider.php:57 ../../addon/rtof/rtof.php:93 -#: ../../addon/redred/redred.php:107 ../../include/network.php:1769 +#: ../../addon/redred/redred.php:107 ../../include/network.php:1779 msgid "Email" msgstr "Correo electrónico" @@ -983,7 +983,7 @@ msgstr "Buscar resultados para:" msgid "Reset form" msgstr "Reiniciar el formulario" -#: ../../Zotlabs/Module/Channel.php:424 ../../Zotlabs/Module/Display.php:375 +#: ../../Zotlabs/Module/Channel.php:424 ../../Zotlabs/Module/Display.php:374 msgid "" "You must enable javascript for your browser to be able to view this content." msgstr "Debe habilitar javascript para poder ver este contenido en su navegador." @@ -1204,7 +1204,7 @@ msgid "Menu Item Permissions" msgstr "Permisos del elemento del menú" #: ../../Zotlabs/Module/Mitem.php:168 ../../Zotlabs/Module/Mitem.php:247 -#: ../../Zotlabs/Module/Settings/Channel.php:544 +#: ../../Zotlabs/Module/Settings/Channel.php:526 msgid "(click to open/close)" msgstr "(pulsar para abrir o cerrar)" @@ -1229,7 +1229,7 @@ msgstr "Usar la autenticación mágica si está disponible" #: ../../Zotlabs/Module/Events.php:472 ../../Zotlabs/Module/Events.php:473 #: ../../Zotlabs/Module/Removeme.php:63 #: ../../Zotlabs/Module/Admin/Site.php:255 -#: ../../Zotlabs/Module/Settings/Channel.php:315 +#: ../../Zotlabs/Module/Settings/Channel.php:309 #: ../../Zotlabs/Module/Settings/Display.php:89 #: ../../Zotlabs/Module/Import.php:554 ../../Zotlabs/Module/Import.php:558 #: ../../Zotlabs/Module/Import.php:559 ../../Zotlabs/Module/Api.php:99 @@ -1284,7 +1284,7 @@ msgstr "Usar la autenticación mágica si está disponible" #: ../../addon/cart/submodules/hzservices.php:646 #: ../../addon/cart/submodules/hzservices.php:650 #: ../../addon/cart/submodules/subscriptions.php:153 -#: ../../addon/cart/submodules/subscriptions.php:416 +#: ../../addon/cart/submodules/subscriptions.php:425 #: ../../addon/xmpp/xmpp.php:53 ../../addon/pumpio/pumpio.php:219 #: ../../addon/pumpio/pumpio.php:223 ../../addon/pumpio/pumpio.php:227 #: ../../addon/pumpio/pumpio.php:231 ../../include/dir_fns.php:143 @@ -1297,7 +1297,7 @@ msgstr "No" #: ../../Zotlabs/Module/Events.php:472 ../../Zotlabs/Module/Events.php:473 #: ../../Zotlabs/Module/Removeme.php:63 #: ../../Zotlabs/Module/Admin/Site.php:257 -#: ../../Zotlabs/Module/Settings/Channel.php:315 +#: ../../Zotlabs/Module/Settings/Channel.php:309 #: ../../Zotlabs/Module/Settings/Display.php:89 #: ../../Zotlabs/Module/Import.php:554 ../../Zotlabs/Module/Import.php:558 #: ../../Zotlabs/Module/Import.php:559 ../../Zotlabs/Module/Api.php:98 @@ -1351,7 +1351,7 @@ msgstr "No" #: ../../addon/cart/submodules/hzservices.php:646 #: ../../addon/cart/submodules/hzservices.php:650 #: ../../addon/cart/submodules/subscriptions.php:153 -#: ../../addon/cart/submodules/subscriptions.php:416 +#: ../../addon/cart/submodules/subscriptions.php:425 #: ../../addon/xmpp/xmpp.php:53 ../../addon/pumpio/pumpio.php:219 #: ../../addon/pumpio/pumpio.php:223 ../../addon/pumpio/pumpio.php:227 #: ../../addon/pumpio/pumpio.php:231 ../../include/dir_fns.php:143 @@ -1651,14 +1651,14 @@ msgstr "Servidor no encontrado" #: ../../Zotlabs/Module/Subthread.php:111 ../../Zotlabs/Module/Tagger.php:69 #: ../../Zotlabs/Module/Like.php:384 ../../Zotlabs/Lib/Activity.php:1570 #: ../../addon/redphotos/redphotohelper.php:71 -#: ../../addon/diaspora/Receiver.php:1539 ../../addon/pubcrawl/as.php:1512 +#: ../../addon/diaspora/Receiver.php:1539 ../../addon/pubcrawl/as.php:1511 #: ../../include/conversation.php:116 ../../include/text.php:2028 msgid "photo" msgstr "foto" #: ../../Zotlabs/Module/Subthread.php:111 ../../Zotlabs/Module/Like.php:384 #: ../../Zotlabs/Lib/Activity.php:1570 ../../addon/diaspora/Receiver.php:1539 -#: ../../addon/pubcrawl/as.php:1512 ../../include/conversation.php:144 +#: ../../addon/pubcrawl/as.php:1511 ../../include/conversation.php:144 #: ../../include/text.php:2034 msgid "status" msgstr "el mensaje de estado " @@ -1745,7 +1745,7 @@ msgstr "Ha creado %1$.0f de %2$.0f canales permitidos." #: ../../Zotlabs/Module/New_channel.php:157 #: ../../Zotlabs/Module/New_channel.php:164 #: ../../Zotlabs/Module/Connedit.php:853 ../../Zotlabs/Module/Defperms.php:256 -#: ../../Zotlabs/Widget/Notifications.php:162 ../../include/nav.php:288 +#: ../../Zotlabs/Widget/Notifications.php:162 ../../include/nav.php:293 msgid "Loading" msgstr "Cargando" @@ -1777,7 +1777,7 @@ msgid "Choose a short nickname" msgstr "Elija un alias corto" #: ../../Zotlabs/Module/New_channel.php:178 -#: ../../Zotlabs/Module/Settings/Channel.php:555 +#: ../../Zotlabs/Module/Settings/Channel.php:535 #: ../../Zotlabs/Module/Register.php:261 msgid "Channel role and privacy" msgstr "Clase de canal y privacidad" @@ -1855,7 +1855,7 @@ msgid "" msgstr "Por defecto, solo la instancia del canal alojado en este servidor será eliminado de la red" #: ../../Zotlabs/Module/Removeme.php:64 -#: ../../Zotlabs/Module/Settings/Channel.php:617 +#: ../../Zotlabs/Module/Settings/Channel.php:594 msgid "Remove Channel" msgstr "Eliminar el canal" @@ -2694,7 +2694,7 @@ msgstr "Permitir código" msgid "Disallow Code" msgstr "No permitir código" -#: ../../Zotlabs/Module/Admin/Channels.php:154 ../../include/nav.php:386 +#: ../../Zotlabs/Module/Admin/Channels.php:154 ../../include/nav.php:391 msgid "Channel" msgstr "Canal" @@ -2725,7 +2725,7 @@ msgstr "No se han encontrado temas." #: ../../Zotlabs/Module/Admin/Themes.php:72 #: ../../Zotlabs/Module/Admin/Addons.php:259 ../../Zotlabs/Module/Thing.php:94 #: ../../Zotlabs/Module/Viewsrc.php:25 ../../Zotlabs/Module/Display.php:45 -#: ../../Zotlabs/Module/Display.php:453 +#: ../../Zotlabs/Module/Display.php:452 #: ../../Zotlabs/Module/Filestorage.php:24 ../../Zotlabs/Module/Admin.php:62 #: ../../include/items.php:3587 msgid "Item not found." @@ -2786,7 +2786,7 @@ msgstr "Ajustes del sitio actualizados." #: ../../Zotlabs/Module/Admin/Site.php:187 #: ../../view/theme/redbasic_c/php/config.php:15 -#: ../../view/theme/redbasic/php/config.php:15 ../../include/text.php:3085 +#: ../../view/theme/redbasic/php/config.php:15 ../../include/text.php:3087 msgid "Default" msgstr "Predeterminado" @@ -2969,9 +2969,9 @@ msgstr "Página personal que se mostrará a los visitantes (por defecto: la pág #: ../../Zotlabs/Module/Admin/Site.php:314 msgid "" -"example: 'public' to show public stream, 'page/sys/home' to show a system " -"webpage called 'home' or 'include:home.html' to include a file." -msgstr "ejemplo: 'public' para mostrar contenido público, 'page/sys/home' para mostrar la página web definida como \"home\" o 'include:home.html' para mostrar el contenido de un fichero." +"example: 'pubstream' to show public stream, 'page/sys/home' to show a system" +" webpage called 'home' or 'include:home.html' to include a file." +msgstr "ejemplo: 'pubstream' para mostrar el stream público, 'page/sys/home' para mostrar una página web del sistema llamada 'home' o 'include:home.html' para incluir un archivo." #: ../../Zotlabs/Module/Admin/Site.php:315 msgid "Preserve site homepage URL" @@ -3564,15 +3564,13 @@ msgstr "Un sitio por línea. El contenido incorporado se filtra de forma predete msgid "Block embedded HTML from these domains" msgstr "Bloquear contenido con HTML incorporado desde estos dominios" -#: ../../Zotlabs/Module/Events.php:475 -msgid "Edit Location" -msgstr "Modificar la dirección" +#: ../../Zotlabs/Module/Lockview.php:75 +msgid "Remote privacy information not available." +msgstr "La información privada remota no está disponible." -#: ../../Zotlabs/Module/Events.php:478 ../../Zotlabs/Module/Photos.php:1094 -#: ../../Zotlabs/Module/Webpages.php:251 ../../Zotlabs/Lib/ThreadItem.php:740 -#: ../../include/page_widgets.php:43 ../../include/conversation.php:1347 -msgid "Preview" -msgstr "Previsualizar" +#: ../../Zotlabs/Module/Lockview.php:96 +msgid "Visible to:" +msgstr "Visible para:" #: ../../Zotlabs/Module/Lockview.php:117 ../../Zotlabs/Module/Lockview.php:153 #: ../../Zotlabs/Module/Acl.php:120 ../../include/acl_selectors.php:88 @@ -3594,12 +3592,12 @@ msgstr "Se ha eliminado el comentario" #: ../../Zotlabs/Module/Settings/Channel.php:78 #: ../../Zotlabs/Module/Settings/Channel.php:89 #: ../../Zotlabs/Module/Connedit.php:712 ../../Zotlabs/Widget/Affinity.php:24 -#: ../../include/selectors.php:123 ../../include/channel.php:444 +#: ../../include/selectors.php:134 ../../include/channel.php:444 #: ../../include/channel.php:445 ../../include/channel.php:452 msgid "Friends" msgstr "Amigos/as" -#: ../../Zotlabs/Module/Settings/Channel.php:272 +#: ../../Zotlabs/Module/Settings/Channel.php:266 #: ../../Zotlabs/Module/Defperms.php:111 #: ../../addon/rendezvous/rendezvous.php:82 #: ../../addon/openstreetmap/openstreetmap.php:184 @@ -3609,414 +3607,402 @@ msgstr "Amigos/as" msgid "Settings updated." msgstr "Ajustes actualizados." -#: ../../Zotlabs/Module/Settings/Channel.php:333 +#: ../../Zotlabs/Module/Settings/Channel.php:327 msgid "Nobody except yourself" msgstr "Nadie excepto usted" -#: ../../Zotlabs/Module/Settings/Channel.php:334 +#: ../../Zotlabs/Module/Settings/Channel.php:328 msgid "Only those you specifically allow" msgstr "Solo aquellos a los que usted permita explícitamente" -#: ../../Zotlabs/Module/Settings/Channel.php:335 +#: ../../Zotlabs/Module/Settings/Channel.php:329 msgid "Approved connections" msgstr "Conexiones aprobadas" -#: ../../Zotlabs/Module/Settings/Channel.php:336 +#: ../../Zotlabs/Module/Settings/Channel.php:330 msgid "Any connections" msgstr "Cualquier conexión" -#: ../../Zotlabs/Module/Settings/Channel.php:337 +#: ../../Zotlabs/Module/Settings/Channel.php:331 msgid "Anybody on this website" msgstr "Cualquiera en este sitio web" -#: ../../Zotlabs/Module/Settings/Channel.php:338 +#: ../../Zotlabs/Module/Settings/Channel.php:332 msgid "Anybody in this network" msgstr "Cualquiera en esta red" -#: ../../Zotlabs/Module/Settings/Channel.php:339 +#: ../../Zotlabs/Module/Settings/Channel.php:333 msgid "Anybody authenticated" msgstr "Cualquiera que esté autenticado" -#: ../../Zotlabs/Module/Settings/Channel.php:340 +#: ../../Zotlabs/Module/Settings/Channel.php:334 msgid "Anybody on the internet" msgstr "Cualquiera en internet" -#: ../../Zotlabs/Module/Settings/Channel.php:415 +#: ../../Zotlabs/Module/Settings/Channel.php:409 msgid "Publish your default profile in the network directory" msgstr "Publicar su perfil principal en el directorio de la red" -#: ../../Zotlabs/Module/Settings/Channel.php:420 +#: ../../Zotlabs/Module/Settings/Channel.php:414 msgid "Allow us to suggest you as a potential friend to new members?" msgstr "¿Nos permite sugerirle como amigo potencial a los nuevos miembros?" -#: ../../Zotlabs/Module/Settings/Channel.php:424 +#: ../../Zotlabs/Module/Settings/Channel.php:418 msgid "or" msgstr "o" -#: ../../Zotlabs/Module/Settings/Channel.php:433 +#: ../../Zotlabs/Module/Settings/Channel.php:427 msgid "Your channel address is" msgstr "Su dirección de canal es" -#: ../../Zotlabs/Module/Settings/Channel.php:436 +#: ../../Zotlabs/Module/Settings/Channel.php:430 msgid "Your files/photos are accessible via WebDAV at" msgstr "Sus archivos y fotos son accesibles a través de WebDAV en " -#: ../../Zotlabs/Module/Settings/Channel.php:488 +#: ../../Zotlabs/Module/Settings/Channel.php:470 msgid "Automatic membership approval" msgstr "Aprobación automática de nuevos miembros" -#: ../../Zotlabs/Module/Settings/Channel.php:488 +#: ../../Zotlabs/Module/Settings/Channel.php:470 #: ../../Zotlabs/Module/Defperms.php:255 msgid "" "If enabled, connection requests will be approved without your interaction" msgstr "Si está habilitado, las solicitudes de conexión serán aprobadas sin su intervención." -#: ../../Zotlabs/Module/Settings/Channel.php:509 +#: ../../Zotlabs/Module/Settings/Channel.php:491 msgid "Channel Settings" msgstr "Ajustes del canal" -#: ../../Zotlabs/Module/Settings/Channel.php:516 +#: ../../Zotlabs/Module/Settings/Channel.php:498 msgid "Basic Settings" msgstr "Configuración básica" -#: ../../Zotlabs/Module/Settings/Channel.php:517 +#: ../../Zotlabs/Module/Settings/Channel.php:499 #: ../../include/channel.php:1528 msgid "Full Name:" msgstr "Nombre completo:" -#: ../../Zotlabs/Module/Settings/Channel.php:518 +#: ../../Zotlabs/Module/Settings/Channel.php:500 #: ../../Zotlabs/Module/Settings/Account.php:104 msgid "Email Address:" msgstr "Dirección de correo electrónico:" -#: ../../Zotlabs/Module/Settings/Channel.php:519 +#: ../../Zotlabs/Module/Settings/Channel.php:501 msgid "Your Timezone:" msgstr "Su huso horario:" -#: ../../Zotlabs/Module/Settings/Channel.php:520 +#: ../../Zotlabs/Module/Settings/Channel.php:502 msgid "Default Post Location:" msgstr "Localización geográfica predeterminada para sus publicaciones:" -#: ../../Zotlabs/Module/Settings/Channel.php:520 +#: ../../Zotlabs/Module/Settings/Channel.php:502 msgid "Geographical location to display on your posts" msgstr "Localización geográfica que debe mostrarse en sus publicaciones" -#: ../../Zotlabs/Module/Settings/Channel.php:521 +#: ../../Zotlabs/Module/Settings/Channel.php:503 msgid "Use Browser Location:" msgstr "Usar la localización geográfica del navegador:" -#: ../../Zotlabs/Module/Settings/Channel.php:523 +#: ../../Zotlabs/Module/Settings/Channel.php:505 msgid "Adult Content" msgstr "Contenido solo para adultos" -#: ../../Zotlabs/Module/Settings/Channel.php:523 +#: ../../Zotlabs/Module/Settings/Channel.php:505 msgid "" "This channel frequently or regularly publishes adult content. (Please tag " "any adult material and/or nudity with #NSFW)" msgstr "Este canal publica contenido solo para adultos con frecuencia o regularmente. (Por favor etiquete cualquier material para adultos con la etiqueta #NSFW)" -#: ../../Zotlabs/Module/Settings/Channel.php:525 +#: ../../Zotlabs/Module/Settings/Channel.php:507 msgid "Security and Privacy Settings" msgstr "Configuración de seguridad y privacidad" -#: ../../Zotlabs/Module/Settings/Channel.php:527 +#: ../../Zotlabs/Module/Settings/Channel.php:509 msgid "Your permissions are already configured. Click to view/adjust" msgstr "Sus permisos ya están configurados. Pulse para ver/ajustar" -#: ../../Zotlabs/Module/Settings/Channel.php:529 +#: ../../Zotlabs/Module/Settings/Channel.php:511 msgid "Hide my online presence" msgstr "Ocultar mi presencia en línea" -#: ../../Zotlabs/Module/Settings/Channel.php:529 +#: ../../Zotlabs/Module/Settings/Channel.php:511 msgid "Prevents displaying in your profile that you are online" msgstr "Evitar mostrar en su perfil que está en línea" -#: ../../Zotlabs/Module/Settings/Channel.php:531 +#: ../../Zotlabs/Module/Settings/Channel.php:513 msgid "Simple Privacy Settings:" msgstr "Configuración de privacidad sencilla:" -#: ../../Zotlabs/Module/Settings/Channel.php:532 +#: ../../Zotlabs/Module/Settings/Channel.php:514 msgid "" "Very Public - extremely permissive (should be used with caution)" msgstr "Muy Público - extremadamente permisivo (debería ser usado con precaución)" -#: ../../Zotlabs/Module/Settings/Channel.php:533 +#: ../../Zotlabs/Module/Settings/Channel.php:515 msgid "" "Typical - default public, privacy when desired (similar to social " "network permissions but with improved privacy)" msgstr "Típico - por defecto público, privado cuando se desee (similar a los permisos de una red social pero con privacidad mejorada)" -#: ../../Zotlabs/Module/Settings/Channel.php:534 +#: ../../Zotlabs/Module/Settings/Channel.php:516 msgid "Private - default private, never open or public" msgstr "Privado - por defecto, privado, nunca abierto o público" -#: ../../Zotlabs/Module/Settings/Channel.php:535 +#: ../../Zotlabs/Module/Settings/Channel.php:517 msgid "Blocked - default blocked to/from everybody" msgstr "Bloqueado - por defecto, bloqueado/a para cualquiera" -#: ../../Zotlabs/Module/Settings/Channel.php:537 +#: ../../Zotlabs/Module/Settings/Channel.php:519 msgid "Allow others to tag your posts" msgstr "Permitir a otros etiquetar sus publicaciones" -#: ../../Zotlabs/Module/Settings/Channel.php:537 +#: ../../Zotlabs/Module/Settings/Channel.php:519 msgid "" "Often used by the community to retro-actively flag inappropriate content" msgstr "A menudo usado por la comunidad para marcar contenido inapropiado de forma retroactiva." -#: ../../Zotlabs/Module/Settings/Channel.php:539 +#: ../../Zotlabs/Module/Settings/Channel.php:521 msgid "Channel Permission Limits" msgstr "Límites de los permisos del canal" -#: ../../Zotlabs/Module/Settings/Channel.php:541 +#: ../../Zotlabs/Module/Settings/Channel.php:523 msgid "Expire other channel content after this many days" msgstr "Caducar contenido de otros canales después de este número de días" -#: ../../Zotlabs/Module/Settings/Channel.php:541 +#: ../../Zotlabs/Module/Settings/Channel.php:523 msgid "0 or blank to use the website limit." msgstr "0 o en blanco para usar el límite del sitio web." -#: ../../Zotlabs/Module/Settings/Channel.php:541 +#: ../../Zotlabs/Module/Settings/Channel.php:523 #, php-format msgid "This website expires after %d days." msgstr "Este sitio web caduca después de %d días." -#: ../../Zotlabs/Module/Settings/Channel.php:541 +#: ../../Zotlabs/Module/Settings/Channel.php:523 msgid "This website does not expire imported content." msgstr "Este sitio web no caduca el contenido importado." -#: ../../Zotlabs/Module/Settings/Channel.php:541 +#: ../../Zotlabs/Module/Settings/Channel.php:523 msgid "The website limit takes precedence if lower than your limit." msgstr "El límite del sitio web tiene prioridad si es inferior a su propio límite." -#: ../../Zotlabs/Module/Settings/Channel.php:542 +#: ../../Zotlabs/Module/Settings/Channel.php:524 msgid "Maximum Friend Requests/Day:" msgstr "Máximo de solicitudes de amistad por día:" -#: ../../Zotlabs/Module/Settings/Channel.php:542 +#: ../../Zotlabs/Module/Settings/Channel.php:524 msgid "May reduce spam activity" msgstr "Podría reducir la actividad de spam" -#: ../../Zotlabs/Module/Settings/Channel.php:543 +#: ../../Zotlabs/Module/Settings/Channel.php:525 msgid "Default Privacy Group" msgstr "Grupo de canales predeterminado" -#: ../../Zotlabs/Module/Settings/Channel.php:545 +#: ../../Zotlabs/Module/Settings/Channel.php:527 msgid "Use my default audience setting for the type of object published" msgstr "Usar los ajustes de mi audiencia predeterminada para el tipo de publicación" -#: ../../Zotlabs/Module/Settings/Channel.php:546 -msgid "Profile to assign new connections" -msgstr "Perfil para asignar a las nuevas conexiones" - -#: ../../Zotlabs/Module/Settings/Channel.php:556 +#: ../../Zotlabs/Module/Settings/Channel.php:536 msgid "Default permissions category" msgstr "Categoría de permisos por defecto" -#: ../../Zotlabs/Module/Settings/Channel.php:562 +#: ../../Zotlabs/Module/Settings/Channel.php:542 msgid "Maximum private messages per day from unknown people:" msgstr "Máximo de mensajes privados por día de gente desconocida:" -#: ../../Zotlabs/Module/Settings/Channel.php:562 +#: ../../Zotlabs/Module/Settings/Channel.php:542 msgid "Useful to reduce spamming" msgstr "Útil para reducir el envío de correo no deseado" -#: ../../Zotlabs/Module/Settings/Channel.php:565 +#: ../../Zotlabs/Module/Settings/Channel.php:545 #: ../../Zotlabs/Lib/Enotify.php:68 msgid "Notification Settings" msgstr "Configuración de las notificaciones" -#: ../../Zotlabs/Module/Settings/Channel.php:566 +#: ../../Zotlabs/Module/Settings/Channel.php:546 msgid "By default post a status message when:" msgstr "Por defecto, enviar un mensaje de estado cuando:" -#: ../../Zotlabs/Module/Settings/Channel.php:567 +#: ../../Zotlabs/Module/Settings/Channel.php:547 msgid "accepting a friend request" msgstr "Acepte una solicitud de amistad" -#: ../../Zotlabs/Module/Settings/Channel.php:568 +#: ../../Zotlabs/Module/Settings/Channel.php:548 msgid "joining a forum/community" msgstr "al unirse a un foro o comunidad" -#: ../../Zotlabs/Module/Settings/Channel.php:569 +#: ../../Zotlabs/Module/Settings/Channel.php:549 msgid "making an interesting profile change" msgstr "Realice un cambio interesante en su perfil" -#: ../../Zotlabs/Module/Settings/Channel.php:570 +#: ../../Zotlabs/Module/Settings/Channel.php:550 msgid "Send a notification email when:" msgstr "Enviar una notificación por correo electrónico cuando:" -#: ../../Zotlabs/Module/Settings/Channel.php:571 +#: ../../Zotlabs/Module/Settings/Channel.php:551 msgid "You receive a connection request" msgstr "Reciba una solicitud de conexión" -#: ../../Zotlabs/Module/Settings/Channel.php:572 +#: ../../Zotlabs/Module/Settings/Channel.php:552 msgid "Your connections are confirmed" msgstr "Sus conexiones hayan sido confirmadas" -#: ../../Zotlabs/Module/Settings/Channel.php:573 +#: ../../Zotlabs/Module/Settings/Channel.php:553 msgid "Someone writes on your profile wall" msgstr "Alguien escriba en la página de su perfil (\"muro\")" -#: ../../Zotlabs/Module/Settings/Channel.php:574 +#: ../../Zotlabs/Module/Settings/Channel.php:554 msgid "Someone writes a followup comment" msgstr "Alguien escriba un comentario sobre sus publicaciones" -#: ../../Zotlabs/Module/Settings/Channel.php:575 +#: ../../Zotlabs/Module/Settings/Channel.php:555 msgid "You receive a private message" msgstr "Reciba un mensaje privado" -#: ../../Zotlabs/Module/Settings/Channel.php:576 +#: ../../Zotlabs/Module/Settings/Channel.php:556 msgid "You receive a friend suggestion" msgstr "Reciba una sugerencia de amistad" -#: ../../Zotlabs/Module/Settings/Channel.php:577 +#: ../../Zotlabs/Module/Settings/Channel.php:557 msgid "You are tagged in a post" msgstr "Usted sea etiquetado en una publicación" -#: ../../Zotlabs/Module/Settings/Channel.php:578 +#: ../../Zotlabs/Module/Settings/Channel.php:558 msgid "You are poked/prodded/etc. in a post" msgstr "Reciba un toque o incitación en una publicación" -#: ../../Zotlabs/Module/Settings/Channel.php:580 +#: ../../Zotlabs/Module/Settings/Channel.php:560 msgid "Someone likes your post/comment" msgstr "Alguien muestre agrado por su entrada o comentario" -#: ../../Zotlabs/Module/Settings/Channel.php:583 +#: ../../Zotlabs/Module/Settings/Channel.php:563 msgid "Show visual notifications including:" msgstr "Mostrar notificaciones visuales que incluyan:" -#: ../../Zotlabs/Module/Settings/Channel.php:585 +#: ../../Zotlabs/Module/Settings/Channel.php:565 msgid "Unseen stream activity" msgstr "Actividad del stream no vista" -#: ../../Zotlabs/Module/Settings/Channel.php:586 +#: ../../Zotlabs/Module/Settings/Channel.php:566 msgid "Unseen channel activity" msgstr "Actividad no vista en el canal" -#: ../../Zotlabs/Module/Settings/Channel.php:587 +#: ../../Zotlabs/Module/Settings/Channel.php:567 msgid "Unseen private messages" msgstr "Mensajes privados no leídos" -#: ../../Zotlabs/Module/Settings/Channel.php:587 -#: ../../Zotlabs/Module/Settings/Channel.php:592 -#: ../../Zotlabs/Module/Settings/Channel.php:593 -#: ../../Zotlabs/Module/Settings/Channel.php:594 +#: ../../Zotlabs/Module/Settings/Channel.php:567 +#: ../../Zotlabs/Module/Settings/Channel.php:572 +#: ../../Zotlabs/Module/Settings/Channel.php:573 +#: ../../Zotlabs/Module/Settings/Channel.php:574 #: ../../addon/jappixmini/jappixmini.php:343 msgid "Recommended" msgstr "Recomendado" -#: ../../Zotlabs/Module/Settings/Channel.php:588 +#: ../../Zotlabs/Module/Settings/Channel.php:568 msgid "Upcoming events" msgstr "Próximos eventos" -#: ../../Zotlabs/Module/Settings/Channel.php:589 +#: ../../Zotlabs/Module/Settings/Channel.php:569 msgid "Events today" msgstr "Eventos de hoy" -#: ../../Zotlabs/Module/Settings/Channel.php:590 +#: ../../Zotlabs/Module/Settings/Channel.php:570 msgid "Upcoming birthdays" msgstr "Próximos cumpleaños" -#: ../../Zotlabs/Module/Settings/Channel.php:590 +#: ../../Zotlabs/Module/Settings/Channel.php:570 msgid "Not available in all themes" msgstr "No disponible en todos los temas" -#: ../../Zotlabs/Module/Settings/Channel.php:591 +#: ../../Zotlabs/Module/Settings/Channel.php:571 msgid "System (personal) notifications" msgstr "Notificaciones del sistema (personales)" -#: ../../Zotlabs/Module/Settings/Channel.php:592 +#: ../../Zotlabs/Module/Settings/Channel.php:572 msgid "System info messages" msgstr "Mensajes de información del sistema" -#: ../../Zotlabs/Module/Settings/Channel.php:593 +#: ../../Zotlabs/Module/Settings/Channel.php:573 msgid "System critical alerts" msgstr "Alertas críticas del sistema" -#: ../../Zotlabs/Module/Settings/Channel.php:594 +#: ../../Zotlabs/Module/Settings/Channel.php:574 msgid "New connections" msgstr "Nuevas conexiones" -#: ../../Zotlabs/Module/Settings/Channel.php:595 +#: ../../Zotlabs/Module/Settings/Channel.php:575 msgid "System Registrations" msgstr "Registros del sistema" -#: ../../Zotlabs/Module/Settings/Channel.php:596 +#: ../../Zotlabs/Module/Settings/Channel.php:576 msgid "Unseen shared files" msgstr "Ficheros compartidos no vistos" -#: ../../Zotlabs/Module/Settings/Channel.php:597 +#: ../../Zotlabs/Module/Settings/Channel.php:577 msgid "Unseen public stream activity" msgstr "Actividad del stream público no vista" -#: ../../Zotlabs/Module/Settings/Channel.php:598 +#: ../../Zotlabs/Module/Settings/Channel.php:578 msgid "Unseen likes and dislikes" msgstr "Los \"me gusta\" y \"no me gusta\" no vistos" -#: ../../Zotlabs/Module/Settings/Channel.php:599 +#: ../../Zotlabs/Module/Settings/Channel.php:579 msgid "Unseen forum posts" msgstr "Entradas no vistas en el foro" -#: ../../Zotlabs/Module/Settings/Channel.php:600 +#: ../../Zotlabs/Module/Settings/Channel.php:580 msgid "Email notification hub (hostname)" msgstr "Email de notificación del hub (nombre del host)" -#: ../../Zotlabs/Module/Settings/Channel.php:600 +#: ../../Zotlabs/Module/Settings/Channel.php:580 #, php-format msgid "" "If your channel is mirrored to multiple hubs, set this to your preferred " "location. This will prevent duplicate email notifications. Example: %s" msgstr "Si su canal está replicado en múltiples hubs, colóquelo en su ubicación preferida. Esto evitará la duplicación de notificaciones por correo electrónico. Ejemplo: %s" -#: ../../Zotlabs/Module/Settings/Channel.php:601 +#: ../../Zotlabs/Module/Settings/Channel.php:581 msgid "Show new wall posts, private messages and connections under Notices" msgstr "Mostrar nuevos mensajes en el muro, mensajes privados y conexiones en Avisos" -#: ../../Zotlabs/Module/Settings/Channel.php:603 +#: ../../Zotlabs/Module/Settings/Channel.php:583 msgid "Notify me of events this many days in advance" msgstr "Avisarme de los eventos con algunos días de antelación" -#: ../../Zotlabs/Module/Settings/Channel.php:603 +#: ../../Zotlabs/Module/Settings/Channel.php:583 msgid "Must be greater than 0" msgstr "Debe ser mayor que 0" -#: ../../Zotlabs/Module/Settings/Channel.php:609 +#: ../../Zotlabs/Module/Settings/Channel.php:588 msgid "Advanced Account/Page Type Settings" msgstr "Ajustes avanzados de la cuenta y de los tipos de página" -#: ../../Zotlabs/Module/Settings/Channel.php:610 +#: ../../Zotlabs/Module/Settings/Channel.php:589 msgid "Change the behaviour of this account for special situations" msgstr "Cambiar el comportamiento de esta cuenta en situaciones especiales" -#: ../../Zotlabs/Module/Settings/Channel.php:612 +#: ../../Zotlabs/Module/Settings/Channel.php:591 msgid "Miscellaneous Settings" msgstr "Ajustes diversos" -#: ../../Zotlabs/Module/Settings/Channel.php:613 +#: ../../Zotlabs/Module/Settings/Channel.php:592 msgid "Default photo upload folder" msgstr "Carpeta por defecto de las fotos subidas" -#: ../../Zotlabs/Module/Settings/Channel.php:613 -#: ../../Zotlabs/Module/Settings/Channel.php:614 +#: ../../Zotlabs/Module/Settings/Channel.php:592 +#: ../../Zotlabs/Module/Settings/Channel.php:593 msgid "%Y - current year, %m - current month" msgstr "%Y - año en curso, %m - mes actual" -#: ../../Zotlabs/Module/Settings/Channel.php:614 +#: ../../Zotlabs/Module/Settings/Channel.php:593 msgid "Default file upload folder" msgstr "Carpeta por defecto de los ficheros subidos" -#: ../../Zotlabs/Module/Settings/Channel.php:616 -msgid "Personal menu to display in your channel pages" -msgstr "Menú personal que debe mostrarse en las páginas de su canal" - -#: ../../Zotlabs/Module/Settings/Channel.php:618 +#: ../../Zotlabs/Module/Settings/Channel.php:595 msgid "Remove this channel." msgstr "Eliminar este canal." -#: ../../Zotlabs/Module/Settings/Channel.php:619 -msgid "Firefox Share $Projectname provider" -msgstr "Servicio de compartición de Firefox: proveedor $Projectname" - #: ../../Zotlabs/Module/Settings/Features.php:43 msgid "Additional Features" msgstr "Funcionalidades" @@ -4110,7 +4096,7 @@ msgstr "Eliminar cuenta" msgid "Remove this account including all its channels" msgstr "Eliminar esta cuenta incluyendo todos sus canales" -#: ../../Zotlabs/Module/Settings/Profiles.php:39 +#: ../../Zotlabs/Module/Settings/Profiles.php:47 msgid "Profiles Settings" msgstr "Gestión de los perfiles" @@ -4154,17 +4140,21 @@ msgstr "Ajustes de los complementos" msgid "Please save/submit changes to any panel before opening another." msgstr "Guarde o envíe los cambios a cualquier panel antes de abrir otro." -#: ../../Zotlabs/Module/Settings/Channel_home.php:41 +#: ../../Zotlabs/Module/Settings/Channel_home.php:44 #: ../../Zotlabs/Module/Settings/Network.php:41 msgid "Max height of content (in pixels)" msgstr "Altura máxima del contenido (en píxeles)" -#: ../../Zotlabs/Module/Settings/Channel_home.php:43 +#: ../../Zotlabs/Module/Settings/Channel_home.php:46 #: ../../Zotlabs/Module/Settings/Network.php:43 msgid "Click to expand content exceeding this height" msgstr "Haga clic para expandir el contenido que exceda esta altura" -#: ../../Zotlabs/Module/Settings/Channel_home.php:58 +#: ../../Zotlabs/Module/Settings/Channel_home.php:59 +msgid "Personal menu to display in your channel pages" +msgstr "Menú personal que debe mostrarse en las páginas de su canal" + +#: ../../Zotlabs/Module/Settings/Channel_home.php:86 msgid "Channel Home Settings" msgstr "Ajustes del canal" @@ -4260,7 +4250,7 @@ msgid "Link post titles to source" msgstr "Enlazar título de la publicación a la fuente original" #: ../../Zotlabs/Module/Settings/Display.php:205 -#: ../../Zotlabs/Widget/Newmember.php:69 +#: ../../Zotlabs/Widget/Newmember.php:75 msgid "New Member Links" msgstr "Enlaces para nuevos miembros" @@ -5166,7 +5156,7 @@ msgstr "Proporcionar un wiki para su canal" #: ../../Zotlabs/Module/Wiki.php:77 ../../addon/cart/myshop.php:37 #: ../../addon/cart/cart.php:1440 #: ../../addon/cart/submodules/paypalbutton.php:456 -#: ../../addon/cart/manual_payments.php:63 +#: ../../addon/cart/manual_payments.php:93 msgid "Invalid channel" msgstr "Canal no válido" @@ -5183,7 +5173,7 @@ msgid "Error downloading wiki: " msgstr "Error al descargar el wiki: " #: ../../Zotlabs/Module/Wiki.php:206 ../../Zotlabs/Widget/Wiki_list.php:19 -#: ../../include/nav.php:501 +#: ../../include/nav.php:506 msgid "Wikis" msgstr "Wikis" @@ -5204,21 +5194,21 @@ msgstr "Nombre del wiki" msgid "Content type" msgstr "Tipo de contenido" -#: ../../Zotlabs/Module/Wiki.php:217 ../../Zotlabs/Module/Wiki.php:359 -#: ../../Zotlabs/Widget/Wiki_pages.php:36 -#: ../../Zotlabs/Widget/Wiki_pages.php:93 ../../addon/mdpost/mdpost.php:41 +#: ../../Zotlabs/Module/Wiki.php:217 ../../Zotlabs/Module/Wiki.php:371 +#: ../../Zotlabs/Widget/Wiki_pages.php:38 +#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../addon/mdpost/mdpost.php:41 #: ../../include/text.php:1892 msgid "Markdown" msgstr "Markdown" -#: ../../Zotlabs/Module/Wiki.php:217 ../../Zotlabs/Module/Wiki.php:359 -#: ../../Zotlabs/Widget/Wiki_pages.php:36 -#: ../../Zotlabs/Widget/Wiki_pages.php:93 ../../include/text.php:1890 +#: ../../Zotlabs/Module/Wiki.php:217 ../../Zotlabs/Module/Wiki.php:371 +#: ../../Zotlabs/Widget/Wiki_pages.php:38 +#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../include/text.php:1890 msgid "BBcode" msgstr "BBcode" -#: ../../Zotlabs/Module/Wiki.php:217 ../../Zotlabs/Widget/Wiki_pages.php:36 -#: ../../Zotlabs/Widget/Wiki_pages.php:93 ../../include/text.php:1893 +#: ../../Zotlabs/Module/Wiki.php:217 ../../Zotlabs/Widget/Wiki_pages.php:38 +#: ../../Zotlabs/Widget/Wiki_pages.php:95 ../../include/text.php:1893 msgid "Text" msgstr "Texto" @@ -5242,53 +5232,53 @@ msgstr "Crear un mensaje de estado para este wiki" msgid "Edit Wiki Name" msgstr "Editar el nombre del wiki" -#: ../../Zotlabs/Module/Wiki.php:271 +#: ../../Zotlabs/Module/Wiki.php:274 msgid "Wiki not found" msgstr "Wiki no encontrado" -#: ../../Zotlabs/Module/Wiki.php:295 +#: ../../Zotlabs/Module/Wiki.php:300 msgid "Rename page" msgstr "Renombrar la página" -#: ../../Zotlabs/Module/Wiki.php:316 +#: ../../Zotlabs/Module/Wiki.php:321 msgid "Error retrieving page content" msgstr "Error al recuperar el contenido de la página" -#: ../../Zotlabs/Module/Wiki.php:324 ../../Zotlabs/Module/Wiki.php:326 +#: ../../Zotlabs/Module/Wiki.php:329 ../../Zotlabs/Module/Wiki.php:331 msgid "New page" msgstr "Nueva página" -#: ../../Zotlabs/Module/Wiki.php:354 +#: ../../Zotlabs/Module/Wiki.php:366 msgid "Revision Comparison" msgstr "Comparación de revisiones" -#: ../../Zotlabs/Module/Wiki.php:355 ../../Zotlabs/Lib/NativeWikiPage.php:561 +#: ../../Zotlabs/Module/Wiki.php:367 ../../Zotlabs/Lib/NativeWikiPage.php:564 #: ../../Zotlabs/Widget/Wiki_page_history.php:25 msgid "Revert" msgstr "Revertir" -#: ../../Zotlabs/Module/Wiki.php:362 +#: ../../Zotlabs/Module/Wiki.php:374 msgid "Short description of your changes (optional)" msgstr "Breve descripción de sus cambios (opcional)" -#: ../../Zotlabs/Module/Wiki.php:371 +#: ../../Zotlabs/Module/Wiki.php:384 msgid "Source" msgstr "Fuente" -#: ../../Zotlabs/Module/Wiki.php:381 +#: ../../Zotlabs/Module/Wiki.php:394 msgid "New page name" msgstr "Nombre de la nueva página" -#: ../../Zotlabs/Module/Wiki.php:386 +#: ../../Zotlabs/Module/Wiki.php:399 msgid "Embed image from photo albums" msgstr "Incluir una imagen de los álbumes de fotos" -#: ../../Zotlabs/Module/Wiki.php:387 ../../addon/hsse/hsse.php:208 +#: ../../Zotlabs/Module/Wiki.php:400 ../../addon/hsse/hsse.php:208 #: ../../include/conversation.php:1411 msgid "Embed an image from your albums" msgstr "Incluir una imagen de sus álbumes" -#: ../../Zotlabs/Module/Wiki.php:389 +#: ../../Zotlabs/Module/Wiki.php:402 #: ../../Zotlabs/Module/Profile_photo.php:466 #: ../../Zotlabs/Module/Cover_photo.php:400 ../../addon/hsse/hsse.php:210 #: ../../addon/hsse/hsse.php:257 ../../include/conversation.php:1413 @@ -5296,100 +5286,100 @@ msgstr "Incluir una imagen de sus álbumes" msgid "OK" msgstr "OK" -#: ../../Zotlabs/Module/Wiki.php:390 +#: ../../Zotlabs/Module/Wiki.php:403 #: ../../Zotlabs/Module/Profile_photo.php:467 #: ../../Zotlabs/Module/Cover_photo.php:401 ../../addon/hsse/hsse.php:139 #: ../../include/conversation.php:1342 msgid "Choose images to embed" msgstr "Elegir imágenes para incluir" -#: ../../Zotlabs/Module/Wiki.php:391 +#: ../../Zotlabs/Module/Wiki.php:404 #: ../../Zotlabs/Module/Profile_photo.php:468 #: ../../Zotlabs/Module/Cover_photo.php:402 ../../addon/hsse/hsse.php:140 #: ../../include/conversation.php:1343 msgid "Choose an album" msgstr "Elegir un álbum" -#: ../../Zotlabs/Module/Wiki.php:392 +#: ../../Zotlabs/Module/Wiki.php:405 #: ../../Zotlabs/Module/Profile_photo.php:469 #: ../../Zotlabs/Module/Cover_photo.php:403 msgid "Choose a different album" msgstr "Elegir un álbum diferente..." -#: ../../Zotlabs/Module/Wiki.php:393 +#: ../../Zotlabs/Module/Wiki.php:406 #: ../../Zotlabs/Module/Profile_photo.php:470 #: ../../Zotlabs/Module/Cover_photo.php:404 ../../addon/hsse/hsse.php:142 #: ../../include/conversation.php:1345 msgid "Error getting album list" msgstr "Error al obtener la lista de álbumes" -#: ../../Zotlabs/Module/Wiki.php:394 +#: ../../Zotlabs/Module/Wiki.php:407 #: ../../Zotlabs/Module/Profile_photo.php:471 #: ../../Zotlabs/Module/Cover_photo.php:405 ../../addon/hsse/hsse.php:143 #: ../../include/conversation.php:1346 msgid "Error getting photo link" msgstr "Error al obtener el enlace de la foto" -#: ../../Zotlabs/Module/Wiki.php:395 +#: ../../Zotlabs/Module/Wiki.php:408 #: ../../Zotlabs/Module/Profile_photo.php:472 #: ../../Zotlabs/Module/Cover_photo.php:406 ../../addon/hsse/hsse.php:144 #: ../../include/conversation.php:1347 msgid "Error getting album" msgstr "Error al obtener el álbum" -#: ../../Zotlabs/Module/Wiki.php:397 +#: ../../Zotlabs/Module/Wiki.php:410 msgid "History" msgstr "Historial" -#: ../../Zotlabs/Module/Wiki.php:473 +#: ../../Zotlabs/Module/Wiki.php:488 msgid "Error creating wiki. Invalid name." msgstr "Error al crear el wiki: el nombre no es válido." -#: ../../Zotlabs/Module/Wiki.php:480 +#: ../../Zotlabs/Module/Wiki.php:495 msgid "A wiki with this name already exists." msgstr "Ya hay un wiki con este nombre." -#: ../../Zotlabs/Module/Wiki.php:493 +#: ../../Zotlabs/Module/Wiki.php:508 msgid "Wiki created, but error creating Home page." msgstr "Se ha creado el wiki, pero se ha producido un error al crear la página de inicio." -#: ../../Zotlabs/Module/Wiki.php:500 +#: ../../Zotlabs/Module/Wiki.php:515 msgid "Error creating wiki" msgstr "Error al crear el wiki" -#: ../../Zotlabs/Module/Wiki.php:523 +#: ../../Zotlabs/Module/Wiki.php:539 msgid "Error updating wiki. Invalid name." msgstr "Error al actualizar el wiki. Nombre no válido." -#: ../../Zotlabs/Module/Wiki.php:543 +#: ../../Zotlabs/Module/Wiki.php:559 msgid "Error updating wiki" msgstr "Error al actualizar el wiki" -#: ../../Zotlabs/Module/Wiki.php:558 +#: ../../Zotlabs/Module/Wiki.php:574 msgid "Wiki delete permission denied." msgstr "Se ha denegado el permiso para eliminar el wiki." -#: ../../Zotlabs/Module/Wiki.php:568 +#: ../../Zotlabs/Module/Wiki.php:584 msgid "Error deleting wiki" msgstr "Se ha producido un error al eliminar el wiki" -#: ../../Zotlabs/Module/Wiki.php:601 +#: ../../Zotlabs/Module/Wiki.php:617 msgid "New page created" msgstr "Se ha creado la nueva página" -#: ../../Zotlabs/Module/Wiki.php:722 +#: ../../Zotlabs/Module/Wiki.php:739 msgid "Cannot delete Home" msgstr "No se puede eliminar la página principal" -#: ../../Zotlabs/Module/Wiki.php:786 +#: ../../Zotlabs/Module/Wiki.php:803 msgid "Current Revision" msgstr "Revisión actual" -#: ../../Zotlabs/Module/Wiki.php:786 +#: ../../Zotlabs/Module/Wiki.php:803 msgid "Selected Revision" msgstr "Revisión seleccionada" -#: ../../Zotlabs/Module/Wiki.php:836 +#: ../../Zotlabs/Module/Wiki.php:853 msgid "You must be authenticated." msgstr "Debe estar autenticado." @@ -5584,21 +5574,13 @@ msgstr "Por favor ajuste el recorte de la imagen para una visión óptima." msgid "Done Editing" msgstr "Edición completada" -#: ../../Zotlabs/Module/Profile.php:91 -msgid "vcard" -msgstr "vcard" +#: ../../Zotlabs/Module/Chatsvc.php:131 +msgid "Away" +msgstr "Ausente" -#: ../../Zotlabs/Module/Oexchange.php:27 -msgid "Unable to find your hub." -msgstr "No se puede encontrar su servidor." - -#: ../../Zotlabs/Module/Oexchange.php:41 -msgid "Post successful." -msgstr "Enviado con éxito." - -#: ../../Zotlabs/Module/Viewsrc.php:46 -msgid "Source of Item" -msgstr "Origen del elemento" +#: ../../Zotlabs/Module/Chatsvc.php:136 +msgid "Online" +msgstr "Conectado/a" #: ../../Zotlabs/Module/Item.php:194 msgid "Unable to locate original post." @@ -5677,7 +5659,7 @@ msgstr "Elemento no válido." #: ../../Zotlabs/Module/Page.php:136 ../../Zotlabs/Module/Block.php:77 #: ../../Zotlabs/Module/Display.php:140 ../../Zotlabs/Module/Display.php:157 #: ../../Zotlabs/Module/Display.php:174 -#: ../../Zotlabs/Lib/NativeWikiPage.php:519 ../../Zotlabs/Web/Router.php:185 +#: ../../Zotlabs/Lib/NativeWikiPage.php:521 ../../Zotlabs/Web/Router.php:185 #: ../../include/help.php:132 msgid "Page not found." msgstr "Página no encontrada." @@ -6077,12 +6059,12 @@ msgid "min" msgstr "min" #: ../../Zotlabs/Module/Fbrowser.php:29 ../../Zotlabs/Lib/Apps.php:320 -#: ../../include/features.php:391 ../../include/nav.php:409 +#: ../../include/features.php:391 ../../include/nav.php:414 msgid "Photos" msgstr "Fotos" #: ../../Zotlabs/Module/Fbrowser.php:85 ../../Zotlabs/Lib/Apps.php:315 -#: ../../Zotlabs/Storage/Browser.php:272 ../../include/nav.php:417 +#: ../../Zotlabs/Storage/Browser.php:272 ../../include/nav.php:422 msgid "Files" msgstr "Ficheros" @@ -6179,7 +6161,7 @@ msgid "Layouts" msgstr "Plantillas" #: ../../Zotlabs/Module/Layouts.php:186 ../../Zotlabs/Lib/Apps.php:323 -#: ../../include/nav.php:168 ../../include/nav.php:284 +#: ../../include/nav.php:168 ../../include/nav.php:289 #: ../../include/help.php:117 ../../include/help.php:125 msgid "Help" msgstr "Ayuda" @@ -6260,15 +6242,15 @@ msgstr "el comentario" msgid "%1$s tagged %2$s's %3$s with %4$s" msgstr "%1$s ha etiquetado %3$s de %2$s con %4$s" -#: ../../Zotlabs/Module/Pconfig.php:26 ../../Zotlabs/Module/Pconfig.php:59 +#: ../../Zotlabs/Module/Pconfig.php:27 ../../Zotlabs/Module/Pconfig.php:63 msgid "This setting requires special processing and editing has been blocked." msgstr "Este ajuste necesita de un proceso especial y la edición ha sido bloqueada." -#: ../../Zotlabs/Module/Pconfig.php:48 +#: ../../Zotlabs/Module/Pconfig.php:52 msgid "Configuration Editor" msgstr "Editor de configuración" -#: ../../Zotlabs/Module/Pconfig.php:49 +#: ../../Zotlabs/Module/Pconfig.php:53 msgid "" "Warning: Changing some settings could render your channel inoperable. Please" " leave this page unless you are comfortable with and knowledgeable about how" @@ -6792,7 +6774,7 @@ msgid "Add Card" msgstr "Añadir una ficha" #: ../../Zotlabs/Module/Cards.php:203 ../../Zotlabs/Lib/Apps.php:303 -#: ../../include/nav.php:466 +#: ../../include/nav.php:471 msgid "Cards" msgstr "Fichas" @@ -6892,7 +6874,7 @@ msgid "Export selected" msgstr "Exportar los elementos seleccionados" #: ../../Zotlabs/Module/Webpages.php:252 ../../Zotlabs/Lib/Apps.php:316 -#: ../../include/nav.php:489 +#: ../../include/nav.php:494 msgid "Webpages" msgstr "Páginas web" @@ -7026,8 +7008,8 @@ msgstr "correo enviado" msgid "Delivery report for %1$s" msgstr "Informe de entrega para %1$s" -#: ../../Zotlabs/Module/Dreport.php:151 ../../Zotlabs/Widget/Wiki_pages.php:39 -#: ../../Zotlabs/Widget/Wiki_pages.php:96 +#: ../../Zotlabs/Module/Dreport.php:151 ../../Zotlabs/Widget/Wiki_pages.php:41 +#: ../../Zotlabs/Widget/Wiki_pages.php:98 msgid "Options" msgstr "Opciones" @@ -7164,14 +7146,14 @@ msgid "Previous action reversed." msgstr "Acción anterior revocada." #: ../../Zotlabs/Module/Like.php:438 ../../Zotlabs/Lib/Activity.php:1605 -#: ../../addon/diaspora/Receiver.php:1568 ../../addon/pubcrawl/as.php:1547 +#: ../../addon/diaspora/Receiver.php:1568 ../../addon/pubcrawl/as.php:1546 #: ../../include/conversation.php:160 #, php-format msgid "%1$s likes %2$s's %3$s" msgstr "A %1$s le gusta %3$s de %2$s" #: ../../Zotlabs/Module/Like.php:440 ../../Zotlabs/Lib/Activity.php:1607 -#: ../../addon/pubcrawl/as.php:1549 ../../include/conversation.php:163 +#: ../../addon/pubcrawl/as.php:1548 ../../include/conversation.php:163 #, php-format msgid "%1$s doesn't like %2$s's %3$s" msgstr "A %1$s no le gusta %3$s de %2$s" @@ -7728,7 +7710,7 @@ msgstr "Cambiar la foto de portada del perfil" msgid "Documentation Search" msgstr "Búsqueda de Documentación" -#: ../../Zotlabs/Module/Help.php:80 ../../include/nav.php:399 +#: ../../Zotlabs/Module/Help.php:80 ../../include/nav.php:404 msgid "About" msgstr "Mi perfil" @@ -7752,11 +7734,11 @@ msgstr "Documentación de $Projectname" msgid "Contents" msgstr "Contenidos" -#: ../../Zotlabs/Module/Display.php:394 +#: ../../Zotlabs/Module/Display.php:393 msgid "Article" msgstr "Artículo" -#: ../../Zotlabs/Module/Display.php:446 +#: ../../Zotlabs/Module/Display.php:445 msgid "Item has been removed." msgstr "Se ha eliminado el elemento." @@ -8073,9 +8055,9 @@ msgid "Mark all seen" msgstr "Marcar todo como visto" #: ../../Zotlabs/Lib/Activity.php:1417 ../../Zotlabs/Lib/Activity.php:1614 -#: ../../widget/Netselect/Netselect.php:42 ../../addon/pubcrawl/as.php:1222 -#: ../../addon/pubcrawl/as.php:1377 ../../addon/pubcrawl/as.php:1556 -#: ../../include/network.php:1768 +#: ../../widget/Netselect/Netselect.php:42 ../../addon/pubcrawl/as.php:1221 +#: ../../addon/pubcrawl/as.php:1376 ../../addon/pubcrawl/as.php:1555 +#: ../../include/network.php:1778 msgid "ActivityPub" msgstr "ActivityPub" @@ -8119,12 +8101,12 @@ msgstr "Administrador del sitio" msgid "Report Bug" msgstr "Informe de errores" -#: ../../Zotlabs/Lib/Apps.php:306 ../../include/nav.php:455 +#: ../../Zotlabs/Lib/Apps.php:306 ../../include/nav.php:460 msgid "Bookmarks" msgstr "Marcadores" #: ../../Zotlabs/Lib/Apps.php:307 ../../Zotlabs/Widget/Chatroom_list.php:16 -#: ../../include/nav.php:442 ../../include/nav.php:445 +#: ../../include/nav.php:447 ../../include/nav.php:450 msgid "Chatrooms" msgstr "Salas de chat" @@ -8145,7 +8127,7 @@ msgstr "Iniciar sesión" msgid "Stream" msgstr "Stream" -#: ../../Zotlabs/Lib/Apps.php:317 ../../include/nav.php:504 +#: ../../Zotlabs/Lib/Apps.php:317 ../../include/nav.php:509 msgid "Wiki" msgstr "Wiki" @@ -8300,79 +8282,79 @@ msgid "publisher" msgstr "editor" #: ../../Zotlabs/Lib/NativeWikiPage.php:42 -#: ../../Zotlabs/Lib/NativeWikiPage.php:93 +#: ../../Zotlabs/Lib/NativeWikiPage.php:94 msgid "(No Title)" msgstr "(Sin título)" -#: ../../Zotlabs/Lib/NativeWikiPage.php:107 +#: ../../Zotlabs/Lib/NativeWikiPage.php:109 msgid "Wiki page create failed." msgstr "Se ha producido un error en la creación de la página wiki." -#: ../../Zotlabs/Lib/NativeWikiPage.php:120 +#: ../../Zotlabs/Lib/NativeWikiPage.php:122 msgid "Wiki not found." msgstr "No se ha encontrado el wiki." -#: ../../Zotlabs/Lib/NativeWikiPage.php:131 +#: ../../Zotlabs/Lib/NativeWikiPage.php:133 msgid "Destination name already exists" msgstr "El nombre de destino ya existe" -#: ../../Zotlabs/Lib/NativeWikiPage.php:163 -#: ../../Zotlabs/Lib/NativeWikiPage.php:359 +#: ../../Zotlabs/Lib/NativeWikiPage.php:166 +#: ../../Zotlabs/Lib/NativeWikiPage.php:362 msgid "Page not found" msgstr "No se ha encontrado la página" -#: ../../Zotlabs/Lib/NativeWikiPage.php:194 +#: ../../Zotlabs/Lib/NativeWikiPage.php:197 msgid "Error reading page content" msgstr "Se ha producido un error al leer el contenido de la página" -#: ../../Zotlabs/Lib/NativeWikiPage.php:350 -#: ../../Zotlabs/Lib/NativeWikiPage.php:400 -#: ../../Zotlabs/Lib/NativeWikiPage.php:467 -#: ../../Zotlabs/Lib/NativeWikiPage.php:508 +#: ../../Zotlabs/Lib/NativeWikiPage.php:353 +#: ../../Zotlabs/Lib/NativeWikiPage.php:402 +#: ../../Zotlabs/Lib/NativeWikiPage.php:469 +#: ../../Zotlabs/Lib/NativeWikiPage.php:510 msgid "Error reading wiki" msgstr "Se ha producido un error al leer el wiki" -#: ../../Zotlabs/Lib/NativeWikiPage.php:388 +#: ../../Zotlabs/Lib/NativeWikiPage.php:390 msgid "Page update failed." msgstr "Se ha producido un error al actualizar la página." -#: ../../Zotlabs/Lib/NativeWikiPage.php:422 +#: ../../Zotlabs/Lib/NativeWikiPage.php:424 msgid "Nothing deleted" msgstr "No se ha eliminado nada" -#: ../../Zotlabs/Lib/NativeWikiPage.php:488 +#: ../../Zotlabs/Lib/NativeWikiPage.php:490 msgid "Compare: object not found." msgstr "No se ha encontrado un objeto para comparar." -#: ../../Zotlabs/Lib/NativeWikiPage.php:494 +#: ../../Zotlabs/Lib/NativeWikiPage.php:496 msgid "Page updated" msgstr "Se ha actualizado la página" -#: ../../Zotlabs/Lib/NativeWikiPage.php:497 +#: ../../Zotlabs/Lib/NativeWikiPage.php:499 msgid "Untitled" msgstr "Sin título" -#: ../../Zotlabs/Lib/NativeWikiPage.php:503 +#: ../../Zotlabs/Lib/NativeWikiPage.php:505 msgid "Wiki resource_id required for git commit" msgstr "Se necesita Wiki resource_id para el git commit" -#: ../../Zotlabs/Lib/NativeWikiPage.php:559 +#: ../../Zotlabs/Lib/NativeWikiPage.php:562 #: ../../Zotlabs/Widget/Wiki_page_history.php:23 msgctxt "wiki_history" msgid "Message" msgstr "Mensaje" -#: ../../Zotlabs/Lib/NativeWikiPage.php:560 +#: ../../Zotlabs/Lib/NativeWikiPage.php:563 #: ../../Zotlabs/Widget/Wiki_page_history.php:24 msgid "Date" msgstr "Fecha" -#: ../../Zotlabs/Lib/NativeWikiPage.php:562 +#: ../../Zotlabs/Lib/NativeWikiPage.php:565 #: ../../Zotlabs/Widget/Wiki_page_history.php:26 msgid "Compare" msgstr "Comparar" -#: ../../Zotlabs/Lib/NativeWikiPage.php:600 ../../include/bbcode.php:746 +#: ../../Zotlabs/Lib/NativeWikiPage.php:603 ../../include/bbcode.php:746 #: ../../include/bbcode.php:916 msgid "Different viewers will see this text differently" msgstr "Visitantes diferentes verán este texto de forma distinta" @@ -8781,11 +8763,11 @@ msgstr "ha editado una entrada fechada el %s" msgid "edited a comment dated %s" msgstr "ha editado un comentario fechado el %s" -#: ../../Zotlabs/Lib/NativeWiki.php:151 +#: ../../Zotlabs/Lib/NativeWiki.php:152 msgid "Wiki updated successfully" msgstr "El wiki se ha actualizado con éxito" -#: ../../Zotlabs/Lib/NativeWiki.php:205 +#: ../../Zotlabs/Lib/NativeWiki.php:206 msgid "Wiki files deleted successfully" msgstr "Se han borrado con éxito los ficheros del wiki" @@ -9034,8 +9016,8 @@ msgstr "Principal" msgid "Addressbook" msgstr "Libreta de direcciones" -#: ../../Zotlabs/Storage/Browser.php:140 ../../include/nav.php:428 -#: ../../include/nav.php:431 +#: ../../Zotlabs/Storage/Browser.php:140 ../../include/nav.php:433 +#: ../../include/nav.php:436 msgid "Calendar" msgstr "Calendario" @@ -9373,16 +9355,16 @@ msgstr "Eliminar término" msgid "Saved Searches" msgstr "Búsquedas guardadas" -#: ../../Zotlabs/Widget/Wiki_pages.php:32 -#: ../../Zotlabs/Widget/Wiki_pages.php:89 +#: ../../Zotlabs/Widget/Wiki_pages.php:34 +#: ../../Zotlabs/Widget/Wiki_pages.php:91 msgid "Add new page" msgstr "Añadir una nueva página" -#: ../../Zotlabs/Widget/Wiki_pages.php:83 +#: ../../Zotlabs/Widget/Wiki_pages.php:85 msgid "Wiki Pages" msgstr "Páginas del wiki" -#: ../../Zotlabs/Widget/Wiki_pages.php:94 +#: ../../Zotlabs/Widget/Wiki_pages.php:96 msgid "Page name" msgstr "Nombre de la página" @@ -9491,7 +9473,19 @@ msgstr "Ver el \"stream\" de su red" msgid "Documentation" msgstr "Documentación" -#: ../../Zotlabs/Widget/Newmember.php:65 +#: ../../Zotlabs/Widget/Newmember.php:57 +msgid "Missing Features?" +msgstr "¿Faltan Características?" + +#: ../../Zotlabs/Widget/Newmember.php:59 +msgid "Pin apps to navigation bar" +msgstr "Fijar apps a la barra de navegación" + +#: ../../Zotlabs/Widget/Newmember.php:60 +msgid "Install more apps" +msgstr "Instalar más apps" + +#: ../../Zotlabs/Widget/Newmember.php:71 msgid "View public stream" msgstr "Ver el \"stream\" público" @@ -9667,20 +9661,20 @@ msgstr "No se ha encontrado el canal de origen." msgid "Network/Protocol" msgstr "Red / Protocolo" -#: ../../widget/Netselect/Netselect.php:28 ../../include/network.php:1772 +#: ../../widget/Netselect/Netselect.php:28 ../../include/network.php:1782 msgid "Zot" msgstr "Zot" -#: ../../widget/Netselect/Netselect.php:31 ../../include/network.php:1770 +#: ../../widget/Netselect/Netselect.php:31 ../../include/network.php:1780 msgid "Diaspora" msgstr "Diaspora" -#: ../../widget/Netselect/Netselect.php:33 ../../include/network.php:1763 -#: ../../include/network.php:1764 +#: ../../widget/Netselect/Netselect.php:33 ../../include/network.php:1773 +#: ../../include/network.php:1774 msgid "Friendica" msgstr "Friendica" -#: ../../widget/Netselect/Netselect.php:38 ../../include/network.php:1765 +#: ../../widget/Netselect/Netselect.php:38 ../../include/network.php:1775 msgid "OStatus" msgstr "OStatus" @@ -10559,13 +10553,13 @@ msgstr "Error de protocolo OpenID. No se recuperó ninguna ID." msgid "Login failed." msgstr "El acceso ha fallado." -#: ../../addon/openid/Mod_Id.php:85 ../../include/selectors.php:49 -#: ../../include/selectors.php:66 ../../include/channel.php:1487 +#: ../../addon/openid/Mod_Id.php:85 ../../include/selectors.php:60 +#: ../../include/selectors.php:77 ../../include/channel.php:1487 msgid "Male" msgstr "Hombre" -#: ../../addon/openid/Mod_Id.php:87 ../../include/selectors.php:49 -#: ../../include/selectors.php:66 ../../include/channel.php:1485 +#: ../../addon/openid/Mod_Id.php:87 ../../include/selectors.php:60 +#: ../../include/selectors.php:77 ../../include/channel.php:1485 msgid "Female" msgstr "Mujer" @@ -11139,6 +11133,36 @@ msgstr "Ayuda para los ajustes" msgid "Jappix Mini Settings" msgstr "Ajustes de Jappix Mini" +#: ../../addon/upgrade_info/upgrade_info.php:43 +msgid "Your channel has been upgraded to the latest $Projectname version." +msgstr "Su canal ha sido actualizado a la última versión de $Projectname." + +#: ../../addon/upgrade_info/upgrade_info.php:44 +msgid "" +"To improve usability, we have converted some features into installable " +"stand-alone apps." +msgstr "Para mejorar la usabilidad, hemos convertido algunas características en aplicaciones independientes instalables." + +#: ../../addon/upgrade_info/upgrade_info.php:45 +msgid "Please visit the $Projectname" +msgstr "Por favor visite el sitio web de $Projectname" + +#: ../../addon/upgrade_info/upgrade_info.php:46 +msgid "app store" +msgstr "depósito de apps" + +#: ../../addon/upgrade_info/upgrade_info.php:47 +msgid "and install possibly missing apps." +msgstr "e instalar aplicaciones que posiblemente falten." + +#: ../../addon/upgrade_info/upgrade_info.php:52 +msgid "Upgrade Info" +msgstr "Información de actualización" + +#: ../../addon/upgrade_info/upgrade_info.php:56 +msgid "Do not show this again" +msgstr "No mostrar esto de nuevo" + #: ../../addon/channelreputation/channelreputation.php:101 #: ../../addon/channelreputation/channelreputation.php:102 #: ../../addon/cart/myshop.php:141 ../../addon/cart/myshop.php:177 @@ -11967,7 +11991,7 @@ msgstr "Debe iniciar sesión en la red para comprar." #: ../../addon/cart/cart.php:1462 #: ../../addon/cart/submodules/paypalbutton.php:392 -#: ../../addon/cart/manual_payments.php:38 +#: ../../addon/cart/manual_payments.php:68 msgid "Order not found." msgstr "El pedido no se ha encontrado." @@ -12107,39 +12131,39 @@ msgid "" "Cannot include subscription items with different terms in the same order." msgstr "No se pueden incluir artículos de suscripción con términos diferentes en el mismo orden." -#: ../../addon/cart/submodules/subscriptions.php:365 +#: ../../addon/cart/submodules/subscriptions.php:372 msgid "Select Subscription to Edit" msgstr "Seleccione suscripción a editar" -#: ../../addon/cart/submodules/subscriptions.php:371 +#: ../../addon/cart/submodules/subscriptions.php:380 msgid "Edit Subscriptions" msgstr "Editar suscripciones" -#: ../../addon/cart/submodules/subscriptions.php:405 +#: ../../addon/cart/submodules/subscriptions.php:414 msgid "Subscription SKU" msgstr "SKU de la suscripción" -#: ../../addon/cart/submodules/subscriptions.php:410 +#: ../../addon/cart/submodules/subscriptions.php:419 msgid "Catalog Description" msgstr "Descripción del catálogo" -#: ../../addon/cart/submodules/subscriptions.php:414 +#: ../../addon/cart/submodules/subscriptions.php:423 msgid "Subscription available for purchase." msgstr "Suscripción disponible para la compra." -#: ../../addon/cart/submodules/subscriptions.php:419 +#: ../../addon/cart/submodules/subscriptions.php:428 msgid "Maximum active subscriptions to this item per account." msgstr "Máximo de suscripciones activas a este artículo por cuenta." -#: ../../addon/cart/submodules/subscriptions.php:422 +#: ../../addon/cart/submodules/subscriptions.php:431 msgid "Subscription price." msgstr "Precio de la suscripción." -#: ../../addon/cart/submodules/subscriptions.php:426 +#: ../../addon/cart/submodules/subscriptions.php:435 msgid "Quantity" msgstr "Cuantía" -#: ../../addon/cart/submodules/subscriptions.php:430 +#: ../../addon/cart/submodules/subscriptions.php:439 msgid "Term" msgstr "Condición" @@ -12147,11 +12171,11 @@ msgstr "Condición" msgid "Error: order mismatch. Please try again." msgstr "Error: desajuste de pedidos. Por favor, inténtelo de nuevo." -#: ../../addon/cart/manual_payments.php:31 +#: ../../addon/cart/manual_payments.php:61 msgid "Manual payments are not enabled." msgstr "Los pagos manuales no están habilitados." -#: ../../addon/cart/manual_payments.php:47 +#: ../../addon/cart/manual_payments.php:77 msgid "Finished" msgstr "Terminado" @@ -12682,243 +12706,247 @@ msgstr "Dirección de correo electrónico del remitente" msgid "Test mode (only send to hub administrator)" msgstr "Modo de prueba (enviar sólo al administrador del hub)" -#: ../../include/selectors.php:30 +#: ../../include/selectors.php:18 +msgid "Profile to assign new connections" +msgstr "Perfil para asignar a las nuevas conexiones" + +#: ../../include/selectors.php:41 msgid "Frequently" msgstr "Frecuentemente" -#: ../../include/selectors.php:31 +#: ../../include/selectors.php:42 msgid "Hourly" msgstr "Cada hora" -#: ../../include/selectors.php:32 +#: ../../include/selectors.php:43 msgid "Twice daily" msgstr "Dos veces al día" -#: ../../include/selectors.php:33 +#: ../../include/selectors.php:44 msgid "Daily" msgstr "Diariamente" -#: ../../include/selectors.php:34 +#: ../../include/selectors.php:45 msgid "Weekly" msgstr "Semanalmente" -#: ../../include/selectors.php:35 +#: ../../include/selectors.php:46 msgid "Monthly" msgstr "Mensualmente" -#: ../../include/selectors.php:49 +#: ../../include/selectors.php:60 msgid "Currently Male" msgstr "Actualmente hombre" -#: ../../include/selectors.php:49 +#: ../../include/selectors.php:60 msgid "Currently Female" msgstr "Actualmente mujer" -#: ../../include/selectors.php:49 +#: ../../include/selectors.php:60 msgid "Mostly Male" msgstr "Generalmente hombre" -#: ../../include/selectors.php:49 +#: ../../include/selectors.php:60 msgid "Mostly Female" msgstr "Generalmente mujer" -#: ../../include/selectors.php:49 +#: ../../include/selectors.php:60 msgid "Transgender" msgstr "Transgénero" -#: ../../include/selectors.php:49 +#: ../../include/selectors.php:60 msgid "Intersex" msgstr "Intersexual" -#: ../../include/selectors.php:49 +#: ../../include/selectors.php:60 msgid "Transsexual" msgstr "Transexual" -#: ../../include/selectors.php:49 +#: ../../include/selectors.php:60 msgid "Hermaphrodite" msgstr "Hermafrodita" -#: ../../include/selectors.php:49 ../../include/channel.php:1491 +#: ../../include/selectors.php:60 ../../include/channel.php:1491 msgid "Neuter" msgstr "Neutral" -#: ../../include/selectors.php:49 ../../include/channel.php:1493 +#: ../../include/selectors.php:60 ../../include/channel.php:1493 msgid "Non-specific" msgstr "No especificado" -#: ../../include/selectors.php:49 +#: ../../include/selectors.php:60 msgid "Undecided" msgstr "Indeciso/a" -#: ../../include/selectors.php:85 ../../include/selectors.php:104 +#: ../../include/selectors.php:96 ../../include/selectors.php:115 msgid "Males" msgstr "Hombres" -#: ../../include/selectors.php:85 ../../include/selectors.php:104 +#: ../../include/selectors.php:96 ../../include/selectors.php:115 msgid "Females" msgstr "Mujeres" -#: ../../include/selectors.php:85 +#: ../../include/selectors.php:96 msgid "Gay" msgstr "Homosexual" -#: ../../include/selectors.php:85 +#: ../../include/selectors.php:96 msgid "Lesbian" msgstr "Lesbiana" -#: ../../include/selectors.php:85 +#: ../../include/selectors.php:96 msgid "No Preference" msgstr "Sin preferencias" -#: ../../include/selectors.php:85 +#: ../../include/selectors.php:96 msgid "Bisexual" msgstr "Bisexual" -#: ../../include/selectors.php:85 +#: ../../include/selectors.php:96 msgid "Autosexual" msgstr "Autosexual" -#: ../../include/selectors.php:85 +#: ../../include/selectors.php:96 msgid "Abstinent" msgstr "Casto/a" -#: ../../include/selectors.php:85 +#: ../../include/selectors.php:96 msgid "Virgin" msgstr "Virgen" -#: ../../include/selectors.php:85 +#: ../../include/selectors.php:96 msgid "Deviant" msgstr "Fuera de lo común" -#: ../../include/selectors.php:85 +#: ../../include/selectors.php:96 msgid "Fetish" msgstr "Fetichista" -#: ../../include/selectors.php:85 +#: ../../include/selectors.php:96 msgid "Oodles" msgstr "Orgías" -#: ../../include/selectors.php:85 +#: ../../include/selectors.php:96 msgid "Nonsexual" msgstr "Asexual" -#: ../../include/selectors.php:123 ../../include/selectors.php:140 +#: ../../include/selectors.php:134 ../../include/selectors.php:151 msgid "Single" msgstr "Soltero/a" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Lonely" msgstr "Solo/a" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Available" msgstr "Disponible" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Unavailable" msgstr "No disponible" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Has crush" msgstr "Enamorado/a" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Infatuated" msgstr "Apasionado/a" -#: ../../include/selectors.php:123 ../../include/selectors.php:140 +#: ../../include/selectors.php:134 ../../include/selectors.php:151 msgid "Dating" msgstr "Saliendo con alguien" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Unfaithful" msgstr "Infiel" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Sex Addict" msgstr "Con adicción al sexo" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Friends/Benefits" msgstr "Amigos con algo extra" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Casual" msgstr "Casual" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Engaged" msgstr "Prometido/a" -#: ../../include/selectors.php:123 ../../include/selectors.php:140 +#: ../../include/selectors.php:134 ../../include/selectors.php:151 msgid "Married" msgstr "Casado/a" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Imaginarily married" msgstr "Casado/a en sueños" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Partners" msgstr "Pareja" -#: ../../include/selectors.php:123 ../../include/selectors.php:140 +#: ../../include/selectors.php:134 ../../include/selectors.php:151 msgid "Cohabiting" msgstr "Cohabitando" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Common law" msgstr "Matrimonio tradicional" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Happy" msgstr "Felíz" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Not looking" msgstr "No estoy buscando" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Swinger" msgstr "Libertino" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Betrayed" msgstr "Engañado/a" -#: ../../include/selectors.php:123 ../../include/selectors.php:140 +#: ../../include/selectors.php:134 ../../include/selectors.php:151 msgid "Separated" msgstr "Separado/a" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Unstable" msgstr "Inestable" -#: ../../include/selectors.php:123 ../../include/selectors.php:140 +#: ../../include/selectors.php:134 ../../include/selectors.php:151 msgid "Divorced" msgstr "Divorciado/a" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Imaginarily divorced" msgstr "Divorciado/a en sueños" -#: ../../include/selectors.php:123 ../../include/selectors.php:140 +#: ../../include/selectors.php:134 ../../include/selectors.php:151 msgid "Widowed" msgstr "Viudo/a" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Uncertain" msgstr "Indeterminado" -#: ../../include/selectors.php:123 ../../include/selectors.php:140 +#: ../../include/selectors.php:134 ../../include/selectors.php:151 msgid "It's complicated" msgstr "Es complicado" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Don't care" msgstr "No me importa" -#: ../../include/selectors.php:123 +#: ../../include/selectors.php:134 msgid "Ask me" msgstr "Pregúnteme" @@ -13267,47 +13295,47 @@ msgstr "relajado/a" msgid "surprised" msgstr "sorprendido/a" -#: ../../include/text.php:1377 ../../include/js_strings.php:86 +#: ../../include/text.php:1377 ../../include/js_strings.php:95 msgid "Monday" msgstr "lunes" -#: ../../include/text.php:1377 ../../include/js_strings.php:87 +#: ../../include/text.php:1377 ../../include/js_strings.php:96 msgid "Tuesday" msgstr "martes" -#: ../../include/text.php:1377 ../../include/js_strings.php:88 +#: ../../include/text.php:1377 ../../include/js_strings.php:97 msgid "Wednesday" msgstr "miércoles" -#: ../../include/text.php:1377 ../../include/js_strings.php:89 +#: ../../include/text.php:1377 ../../include/js_strings.php:98 msgid "Thursday" msgstr "jueves" -#: ../../include/text.php:1377 ../../include/js_strings.php:90 +#: ../../include/text.php:1377 ../../include/js_strings.php:99 msgid "Friday" msgstr "viernes" -#: ../../include/text.php:1377 ../../include/js_strings.php:91 +#: ../../include/text.php:1377 ../../include/js_strings.php:100 msgid "Saturday" msgstr "sábado" -#: ../../include/text.php:1377 ../../include/js_strings.php:85 +#: ../../include/text.php:1377 ../../include/js_strings.php:94 msgid "Sunday" msgstr "domingo" -#: ../../include/text.php:1381 ../../include/js_strings.php:61 +#: ../../include/text.php:1381 ../../include/js_strings.php:70 msgid "January" msgstr "enero" -#: ../../include/text.php:1381 ../../include/js_strings.php:62 +#: ../../include/text.php:1381 ../../include/js_strings.php:71 msgid "February" msgstr "febrero" -#: ../../include/text.php:1381 ../../include/js_strings.php:63 +#: ../../include/text.php:1381 ../../include/js_strings.php:72 msgid "March" msgstr "marzo" -#: ../../include/text.php:1381 ../../include/js_strings.php:64 +#: ../../include/text.php:1381 ../../include/js_strings.php:73 msgid "April" msgstr "abril" @@ -13315,31 +13343,31 @@ msgstr "abril" msgid "May" msgstr "mayo" -#: ../../include/text.php:1381 ../../include/js_strings.php:66 +#: ../../include/text.php:1381 ../../include/js_strings.php:75 msgid "June" msgstr "junio" -#: ../../include/text.php:1381 ../../include/js_strings.php:67 +#: ../../include/text.php:1381 ../../include/js_strings.php:76 msgid "July" msgstr "julio" -#: ../../include/text.php:1381 ../../include/js_strings.php:68 +#: ../../include/text.php:1381 ../../include/js_strings.php:77 msgid "August" msgstr "agosto" -#: ../../include/text.php:1381 ../../include/js_strings.php:69 +#: ../../include/text.php:1381 ../../include/js_strings.php:78 msgid "September" msgstr "septiembre" -#: ../../include/text.php:1381 ../../include/js_strings.php:70 +#: ../../include/text.php:1381 ../../include/js_strings.php:79 msgid "October" msgstr "octubre" -#: ../../include/text.php:1381 ../../include/js_strings.php:71 +#: ../../include/text.php:1381 ../../include/js_strings.php:80 msgid "November" msgstr "noviembre" -#: ../../include/text.php:1381 ../../include/js_strings.php:72 +#: ../../include/text.php:1381 ../../include/js_strings.php:81 msgid "December" msgstr "diciembre" @@ -13363,7 +13391,7 @@ msgstr "eliminar del fichero" msgid "Download binary/encrypted content" msgstr "Descargar contenido binario o cifrado" -#: ../../include/text.php:1872 ../../include/language.php:397 +#: ../../include/text.php:1872 ../../include/language.php:423 msgid "default" msgstr "por defecto" @@ -13662,181 +13690,191 @@ msgid " channel name" msgstr "nombre de canal" #: ../../include/js_strings.php:41 +#, php-format +msgid "%d minutes" +msgid_plural "%d minutes" +msgstr[0] "%d minutos" +msgstr[1] "%d minutos" + +#: ../../include/js_strings.php:42 +#, php-format +msgid "about %d hours" +msgid_plural "about %d hours" +msgstr[0] "alrededor de %d horas" +msgstr[1] "alrededor de %d horas" + +#: ../../include/js_strings.php:43 +#, php-format +msgid "%d days" +msgid_plural "%d days" +msgstr[0] "%d días" +msgstr[1] "%d días" + +#: ../../include/js_strings.php:44 +#, php-format +msgid "%d months" +msgid_plural "%d months" +msgstr[0] "%d meses" +msgstr[1] "%d meses" + +#: ../../include/js_strings.php:45 +#, php-format +msgid "%d years" +msgid_plural "%d years" +msgstr[0] "%d años" +msgstr[1] "%d años" + +#: ../../include/js_strings.php:50 msgid "timeago.prefixAgo" msgstr "hace " -#: ../../include/js_strings.php:42 +#: ../../include/js_strings.php:51 msgid "timeago.prefixFromNow" msgstr "en " -#: ../../include/js_strings.php:43 +#: ../../include/js_strings.php:52 msgid "timeago.suffixAgo" msgstr "NONE" -#: ../../include/js_strings.php:44 +#: ../../include/js_strings.php:53 msgid "timeago.suffixFromNow" msgstr "NONE" -#: ../../include/js_strings.php:47 +#: ../../include/js_strings.php:56 msgid "less than a minute" msgstr "menos de un minuto" -#: ../../include/js_strings.php:48 +#: ../../include/js_strings.php:57 msgid "about a minute" msgstr "alrededor de un minuto" -#: ../../include/js_strings.php:49 -#, php-format -msgid "%d minutes" -msgstr "%d minutos" - -#: ../../include/js_strings.php:50 +#: ../../include/js_strings.php:59 msgid "about an hour" msgstr "alrededor de una hora" -#: ../../include/js_strings.php:51 -#, php-format -msgid "about %d hours" -msgstr "alrededor de %d horas" - -#: ../../include/js_strings.php:52 +#: ../../include/js_strings.php:61 msgid "a day" msgstr "un día" -#: ../../include/js_strings.php:53 -#, php-format -msgid "%d days" -msgstr "%d días" - -#: ../../include/js_strings.php:54 +#: ../../include/js_strings.php:63 msgid "about a month" msgstr "alrededor de un mes" -#: ../../include/js_strings.php:55 -#, php-format -msgid "%d months" -msgstr "%d meses" - -#: ../../include/js_strings.php:56 +#: ../../include/js_strings.php:65 msgid "about a year" msgstr "alrededor de un año" -#: ../../include/js_strings.php:57 -#, php-format -msgid "%d years" -msgstr "%d años" - -#: ../../include/js_strings.php:58 +#: ../../include/js_strings.php:67 msgid " " msgstr " " -#: ../../include/js_strings.php:59 +#: ../../include/js_strings.php:68 msgid "timeago.numbers" msgstr "timeago.numbers" -#: ../../include/js_strings.php:65 +#: ../../include/js_strings.php:74 msgctxt "long" msgid "May" msgstr "mayo" -#: ../../include/js_strings.php:73 +#: ../../include/js_strings.php:82 msgid "Jan" msgstr "ene" -#: ../../include/js_strings.php:74 +#: ../../include/js_strings.php:83 msgid "Feb" msgstr "feb" -#: ../../include/js_strings.php:75 +#: ../../include/js_strings.php:84 msgid "Mar" msgstr "mar" -#: ../../include/js_strings.php:76 +#: ../../include/js_strings.php:85 msgid "Apr" msgstr "abr" -#: ../../include/js_strings.php:77 +#: ../../include/js_strings.php:86 msgctxt "short" msgid "May" msgstr "may" -#: ../../include/js_strings.php:78 +#: ../../include/js_strings.php:87 msgid "Jun" msgstr "jun" -#: ../../include/js_strings.php:79 +#: ../../include/js_strings.php:88 msgid "Jul" msgstr "jul" -#: ../../include/js_strings.php:80 +#: ../../include/js_strings.php:89 msgid "Aug" msgstr "ago" -#: ../../include/js_strings.php:81 +#: ../../include/js_strings.php:90 msgid "Sep" msgstr "sep" -#: ../../include/js_strings.php:82 +#: ../../include/js_strings.php:91 msgid "Oct" msgstr "oct" -#: ../../include/js_strings.php:83 +#: ../../include/js_strings.php:92 msgid "Nov" msgstr "nov" -#: ../../include/js_strings.php:84 +#: ../../include/js_strings.php:93 msgid "Dec" msgstr "dic" -#: ../../include/js_strings.php:92 +#: ../../include/js_strings.php:101 msgid "Sun" msgstr "dom" -#: ../../include/js_strings.php:93 +#: ../../include/js_strings.php:102 msgid "Mon" msgstr "lun" -#: ../../include/js_strings.php:94 +#: ../../include/js_strings.php:103 msgid "Tue" msgstr "mar" -#: ../../include/js_strings.php:95 +#: ../../include/js_strings.php:104 msgid "Wed" msgstr "mié" -#: ../../include/js_strings.php:96 +#: ../../include/js_strings.php:105 msgid "Thu" msgstr "jue" -#: ../../include/js_strings.php:97 +#: ../../include/js_strings.php:106 msgid "Fri" msgstr "vie" -#: ../../include/js_strings.php:98 +#: ../../include/js_strings.php:107 msgid "Sat" msgstr "sáb" -#: ../../include/js_strings.php:99 +#: ../../include/js_strings.php:108 msgctxt "calendar" msgid "today" msgstr "hoy" -#: ../../include/js_strings.php:100 +#: ../../include/js_strings.php:109 msgctxt "calendar" msgid "month" msgstr "mes" -#: ../../include/js_strings.php:101 +#: ../../include/js_strings.php:110 msgctxt "calendar" msgid "week" msgstr "semana" -#: ../../include/js_strings.php:102 +#: ../../include/js_strings.php:111 msgctxt "calendar" msgid "day" msgstr "día" -#: ../../include/js_strings.php:103 +#: ../../include/js_strings.php:112 msgctxt "calendar" msgid "All day" msgstr "Todos los días" @@ -13857,25 +13895,28 @@ msgstr "[sin asunto]" msgid "Stored post could not be verified." msgstr "No se han podido verificar las publicaciones guardadas." -#: ../../include/text.php:1106 -msgid "slap" -msgstr "una bofetada " +#: ../../include/activities.php:41 +msgid " and " +msgstr " y " -#: ../../include/text.php:1106 -msgid "slapped" -msgstr "ha abofeteado a " +#: ../../include/activities.php:49 +msgid "public profile" +msgstr "el perfil público" -#: ../../include/text.php:1107 -msgid "finger" -msgstr "un \"finger\" " +#: ../../include/activities.php:58 +#, php-format +msgid "%1$s changed %2$s to “%3$s”" +msgstr "%1$s ha cambiado %2$s a “%3$s”" -#: ../../include/text.php:1107 -msgid "fingered" -msgstr "envió un \"finger\" a" +#: ../../include/activities.php:59 +#, php-format +msgid "Visit %1$s's %2$s" +msgstr "Visitar %2$s de %1$s" -#: ../../include/text.php:1108 -msgid "rebuff" -msgstr "un reproche" +#: ../../include/activities.php:62 +#, php-format +msgid "%1$s has an updated %2$s, changing %3$s." +msgstr "%1$s ha actualizado %2$s, cambiando %3$s." #: ../../include/attach.php:265 ../../include/attach.php:374 msgid "Item was not found." @@ -14219,35 +14260,35 @@ msgstr "Llamadas de trabajo" msgid "Work, Fax" msgstr "Fax de trabajo" -#: ../../include/network.php:760 +#: ../../include/network.php:770 msgid "view full size" msgstr "Ver en el tamaño original" -#: ../../include/network.php:1766 +#: ../../include/network.php:1776 msgid "GNU-Social" msgstr "GNU Social" -#: ../../include/network.php:1767 +#: ../../include/network.php:1777 msgid "RSS/Atom" msgstr "RSS/Atom" -#: ../../include/network.php:1771 +#: ../../include/network.php:1781 msgid "Facebook" msgstr "Facebook" -#: ../../include/network.php:1773 +#: ../../include/network.php:1783 msgid "LinkedIn" msgstr "LinkedIn" -#: ../../include/network.php:1774 +#: ../../include/network.php:1784 msgid "XMPP/IM" msgstr "XMPP/IM" -#: ../../include/network.php:1775 +#: ../../include/network.php:1785 msgid "MySpace" msgstr "MySpace" -#: ../../include/language.php:410 +#: ../../include/language.php:436 msgid "Select an alternate language" msgstr "Seleccionar un idioma alternativo" @@ -14888,55 +14929,55 @@ msgstr "Buscar en el sitio @nombre, !foro, #tag, ?docs, contenido" msgid "Site Setup and Configuration" msgstr "Ajustes y configuración del sitio" -#: ../../include/nav.php:294 +#: ../../include/nav.php:299 msgid "@name, !forum, #tag, ?doc, content" msgstr "@nombre, !foro, #tag, ?docs, contenido" -#: ../../include/nav.php:295 +#: ../../include/nav.php:300 msgid "Please wait..." msgstr "Espere por favor…" -#: ../../include/nav.php:301 +#: ../../include/nav.php:306 msgid "Add Apps" msgstr "Añadir aplicaciones" -#: ../../include/nav.php:302 +#: ../../include/nav.php:307 msgid "Arrange Apps" msgstr "Organizar aplicaciones" -#: ../../include/nav.php:303 +#: ../../include/nav.php:308 msgid "Toggle System Apps" msgstr "Alternar aplicaciones de sistema" -#: ../../include/nav.php:389 +#: ../../include/nav.php:394 msgid "Status Messages and Posts" msgstr "Mensajes de estado y publicaciones" -#: ../../include/nav.php:402 +#: ../../include/nav.php:407 msgid "Profile Details" msgstr "Detalles del perfil" -#: ../../include/nav.php:412 ../../include/photos.php:667 +#: ../../include/nav.php:417 ../../include/photos.php:667 msgid "Photo Albums" msgstr "Álbumes de fotos" -#: ../../include/nav.php:420 +#: ../../include/nav.php:425 msgid "Files and Storage" msgstr "Ficheros y repositorio" -#: ../../include/nav.php:458 +#: ../../include/nav.php:463 msgid "Saved Bookmarks" msgstr "Marcadores guardados" -#: ../../include/nav.php:469 +#: ../../include/nav.php:474 msgid "View Cards" msgstr "Ver las fichas" -#: ../../include/nav.php:480 +#: ../../include/nav.php:485 msgid "View Articles" msgstr "Ver los artículos" -#: ../../include/nav.php:492 +#: ../../include/nav.php:497 msgid "View Webpages" msgstr "Ver páginas web" diff --git a/view/es-es/hstrings.php b/view/es-es/hstrings.php index a7a4d6a3c..6daac9592 100644 --- a/view/es-es/hstrings.php +++ b/view/es-es/hstrings.php @@ -5,6 +5,7 @@ function string_plural_select_es_es($n){ return ($n != 1);; }} App::$rtl = 0; +App::$strings["plural_function_code"] = "(n != 1);"; 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."; @@ -535,9 +536,7 @@ App::$strings["%s - (Incompatible)"] = "%s - (Incompatible)"; App::$strings["mobile"] = "móvil"; App::$strings["experimental"] = "experimental"; App::$strings["unsupported"] = "no soportado"; -App::$strings["No"] = "No"; App::$strings["Yes - with approval"] = "Sí - con aprobación"; -App::$strings["Yes"] = "Sí"; App::$strings["My site is not a public server"] = "Mi sitio no es un servidor público"; App::$strings["My site has paid access only"] = "Mi sitio es un servicio de pago"; App::$strings["My site has free access only"] = "Mi sitio es un servicio gratuito"; @@ -573,7 +572,7 @@ App::$strings["This is displayed on the public server site list."] = "Esto se mu App::$strings["Register text"] = "Texto del registro"; App::$strings["Will be displayed prominently on the registration page."] = "Se mostrará de forma destacada en la página de registro."; App::$strings["Site homepage to show visitors (default: login box)"] = "Página personal que se mostrará a los visitantes (por defecto: la página de identificación)"; -App::$strings["example: 'public' to show public stream, 'page/sys/home' to show a system webpage called 'home' or 'include:home.html' to include a file."] = "ejemplo: 'public' para mostrar contenido público, 'page/sys/home' para mostrar la página web definida como \"home\" o 'include:home.html' para mostrar el contenido de un fichero."; +App::$strings["example: 'pubstream' to show public stream, 'page/sys/home' to show a system webpage called 'home' or 'include:home.html' to include a file."] = "ejemplo: 'pubstream' para mostrar el stream público, 'page/sys/home' para mostrar una página web del sistema llamada 'home' o 'include:home.html' para incluir un archivo."; App::$strings["Preserve site homepage URL"] = "Preservar la dirección de la página personal"; App::$strings["Present the site homepage in a frame at the original location instead of redirecting"] = "Presenta la página personal del sitio en un marco en la ubicación original, en vez de redirigirla."; App::$strings["Accounts abandoned after x days"] = "Cuentas abandonadas después de x días"; @@ -755,7 +754,6 @@ App::$strings["Maximum Friend Requests/Day:"] = "Máximo de solicitudes de amist App::$strings["May reduce spam activity"] = "Podría reducir la actividad de spam"; App::$strings["Default Privacy Group"] = "Grupo de canales predeterminado"; App::$strings["Use my default audience setting for the type of object published"] = "Usar los ajustes de mi audiencia predeterminada para el tipo de publicación"; -App::$strings["Profile to assign new connections"] = "Perfil para asignar a las nuevas conexiones"; App::$strings["Default permissions category"] = "Categoría de permisos por defecto"; App::$strings["Maximum private messages per day from unknown people:"] = "Máximo de mensajes privados por día de gente desconocida:"; App::$strings["Useful to reduce spamming"] = "Útil para reducir el envío de correo no deseado"; @@ -803,9 +801,7 @@ App::$strings["Miscellaneous Settings"] = "Ajustes diversos"; App::$strings["Default photo upload folder"] = "Carpeta por defecto de las fotos subidas"; App::$strings["%Y - current year, %m - current month"] = "%Y - año en curso, %m - mes actual"; App::$strings["Default file upload folder"] = "Carpeta por defecto de los ficheros subidos"; -App::$strings["Personal menu to display in your channel pages"] = "Menú personal que debe mostrarse en las páginas de su canal"; App::$strings["Remove this channel."] = "Eliminar este canal."; -App::$strings["Firefox Share \$Projectname provider"] = "Servicio de compartición de Firefox: proveedor \$Projectname"; App::$strings["Additional Features"] = "Funcionalidades"; App::$strings["Events Settings"] = "Gestión de eventos"; App::$strings["CalDAV Settings"] = "Ajustes de CalDav"; @@ -842,6 +838,7 @@ App::$strings["Addon Settings"] = "Ajustes de los complementos"; App::$strings["Please save/submit changes to any panel before opening another."] = "Guarde o envíe los cambios a cualquier panel antes de abrir otro."; App::$strings["Max height of content (in pixels)"] = "Altura máxima del contenido (en píxeles)"; App::$strings["Click to expand content exceeding this height"] = "Haga clic para expandir el contenido que exceda esta altura"; +App::$strings["Personal menu to display in your channel pages"] = "Menú personal que debe mostrarse en las páginas de su canal"; App::$strings["Channel Home Settings"] = "Ajustes del canal"; App::$strings["Directory Settings"] = "Configuración del directorio"; App::$strings["Editor Settings"] = "Ajustes del editor"; @@ -2069,6 +2066,9 @@ App::$strings["Communicate"] = "Comunicarse"; App::$strings["View your channel homepage"] = "Ver la página principal de su canal"; App::$strings["View your network stream"] = "Ver el \"stream\" de su red"; App::$strings["Documentation"] = "Documentación"; +App::$strings["Missing Features?"] = "¿Faltan Características?"; +App::$strings["Pin apps to navigation bar"] = "Fijar apps a la barra de navegación"; +App::$strings["Install more apps"] = "Instalar más apps"; App::$strings["View public stream"] = "Ver el \"stream\" público"; App::$strings["Member registrations waiting for confirmation"] = "Inscripciones de nuevos miembros pendientes de aprobación"; App::$strings["Inspect queue"] = "Examinar la cola"; @@ -2455,6 +2455,13 @@ App::$strings["Approve subscription requests from Hubzilla contacts automaticall App::$strings["Purge internal list of jabber addresses of contacts"] = "Purgar la lista interna de las direcciones de contactos de jabber"; App::$strings["Configuration Help"] = "Ayuda para los ajustes"; App::$strings["Jappix Mini Settings"] = "Ajustes de Jappix Mini"; +App::$strings["Your channel has been upgraded to the latest \$Projectname version."] = "Su canal ha sido actualizado a la última versión de \$Projectname."; +App::$strings["To improve usability, we have converted some features into installable stand-alone apps."] = "Para mejorar la usabilidad, hemos convertido algunas características en aplicaciones independientes instalables."; +App::$strings["Please visit the \$Projectname"] = "Por favor visite el sitio web de \$Projectname"; +App::$strings["app store"] = "depósito de apps"; +App::$strings["and install possibly missing apps."] = "e instalar aplicaciones que posiblemente falten."; +App::$strings["Upgrade Info"] = "Información de actualización"; +App::$strings["Do not show this again"] = "No mostrar esto de nuevo"; App::$strings["Access Denied"] = "Acceso denegado"; App::$strings["Enable Community Moderation"] = "Habilitar la moderación de la comunidad"; App::$strings["Reputation automatically given to new members"] = "La reputación se otorga automáticamente a los nuevos miembros"; @@ -2807,6 +2814,7 @@ App::$strings["%1\$d of %2\$d messages sent."] = "%1\$d de %2\$d mensajes enviad App::$strings["Send email to all hub members."] = "Enviar un correo electrónico a todos los miembros del hub."; App::$strings["Sender Email address"] = "Dirección de correo electrónico del remitente"; App::$strings["Test mode (only send to hub administrator)"] = "Modo de prueba (enviar sólo al administrador del hub)"; +App::$strings["Profile to assign new connections"] = "Perfil para asignar a las nuevas conexiones"; App::$strings["Frequently"] = "Frecuentemente"; App::$strings["Hourly"] = "Cada hora"; App::$strings["Twice daily"] = "Dos veces al día"; @@ -3069,21 +3077,36 @@ App::$strings["Thank you, this nickname is valid."] = "Gracias, este alias es v App::$strings["A channel name is required."] = "Se requiere un nombre de canal"; App::$strings["This is a "] = "Esto es un "; App::$strings[" channel name"] = "nombre de canal"; +App::$strings["%d minutes"] = array( + 0 => "%d minutos", + 1 => "%d minutos", +); +App::$strings["about %d hours"] = array( + 0 => "alrededor de %d horas", + 1 => "alrededor de %d horas", +); +App::$strings["%d days"] = array( + 0 => "%d días", + 1 => "%d días", +); +App::$strings["%d months"] = array( + 0 => "%d meses", + 1 => "%d meses", +); +App::$strings["%d years"] = array( + 0 => "%d años", + 1 => "%d años", +); App::$strings["timeago.prefixAgo"] = "hace "; App::$strings["timeago.prefixFromNow"] = "en "; App::$strings["timeago.suffixAgo"] = "NONE"; App::$strings["timeago.suffixFromNow"] = "NONE"; App::$strings["less than a minute"] = "menos de un minuto"; App::$strings["about a minute"] = "alrededor de un minuto"; -App::$strings["%d minutes"] = "%d minutos"; App::$strings["about an hour"] = "alrededor de una hora"; -App::$strings["about %d hours"] = "alrededor de %d horas"; App::$strings["a day"] = "un día"; -App::$strings["%d days"] = "%d días"; App::$strings["about a month"] = "alrededor de un mes"; -App::$strings["%d months"] = "%d meses"; App::$strings["about a year"] = "alrededor de un año"; -App::$strings["%d years"] = "%d años"; App::$strings[" "] = " "; App::$strings["timeago.numbers"] = "timeago.numbers"; App::$strings["__ctx:long__ May"] = "mayo"; diff --git a/view/fr/hmessages.po b/view/fr/hmessages.po index 8c75a9416..c5263c2df 100644 --- a/view/fr/hmessages.po +++ b/view/fr/hmessages.po @@ -4360,12 +4360,12 @@ msgstr "Notifications du système" msgid "Connection added." msgstr "Connexion ajoutée." -#: ../../Zotlabs/Module/Import.php:143 +#: ../../Zotlabs/Module/Import.php:144 #, php-format msgid "Your service plan only allows %d channels." msgstr "Votre forfait n'autorise que %d canaux." -#: ../../Zotlabs/Module/Import.php:157 +#: ../../Zotlabs/Module/Import.php:158 msgid "No channel. Import failed." msgstr "Pas de canal. Echec de l'import." @@ -8910,54 +8910,6 @@ msgstr "Voir le flux public" msgid "New Member Links" msgstr "Liens pour les nouveaux membres" -#: ../../Zotlabs/Widget/Newmember.php:33 -msgid "Profile Creation" -msgstr "Création de profil" - -#: ../../Zotlabs/Widget/Newmember.php:35 -msgid "Upload profile photo" -msgstr "Téléverser la photo du profil" - -#: ../../Zotlabs/Widget/Newmember.php:36 -msgid "Upload cover photo" -msgstr "Téléverser la photo de couverture" - -#: ../../Zotlabs/Widget/Newmember.php:37 ../../include/nav.php:119 -msgid "Edit your profile" -msgstr "Modifier votre profil" - -#: ../../Zotlabs/Widget/Newmember.php:40 -msgid "Find and Connect with others" -msgstr "Trouver et connecter avec des autres personnes" - -#: ../../Zotlabs/Widget/Newmember.php:44 -msgid "Manage your connections" -msgstr "Gérez vos connexions" - -#: ../../Zotlabs/Widget/Newmember.php:47 -msgid "Communicate" -msgstr "Communiquer" - -#: ../../Zotlabs/Widget/Newmember.php:49 -msgid "View your channel homepage" -msgstr "Voir la page d'accueil de votre canal" - -#: ../../Zotlabs/Widget/Newmember.php:50 -msgid "View your network stream" -msgstr "Visualisez votre flux réseau" - -#: ../../Zotlabs/Widget/Newmember.php:56 -msgid "Documentation" -msgstr "Documentation" - -#: ../../Zotlabs/Widget/Newmember.php:67 -msgid "View public stream. Warning: not moderated" -msgstr "Voir le flux public. Avertissement : non modéré" - -#: ../../Zotlabs/Widget/Newmember.php:71 -msgid "New Member Links" -msgstr "Liens pour les nouveaux membres" - #: ../../Zotlabs/Widget/Admin.php:23 ../../Zotlabs/Widget/Admin.php:60 msgid "Member registrations waiting for confirmation" msgstr "Inscriptions en attente d'approbation" diff --git a/view/it/hmessages.po b/view/it/hmessages.po index ae8107d44..fc4772846 100644 --- a/view/it/hmessages.po +++ b/view/it/hmessages.po @@ -5656,8 +5656,8 @@ msgstr "Permessi predefiniti dei nuovi contatti" #: ../../Zotlabs/Module/Connedit.php:850 ../../include/items.php:4214 #, php-format -msgid "%1$s tagged %2$s's %3$s with %4$s" -msgstr "%1$s ha taggato %3$s di %2$s con %4$s" +msgid "Connection: %s" +msgstr "Contatto: %s" #: ../../Zotlabs/Module/Connedit.php:851 ../../Zotlabs/Module/Defperms.php:239 msgid "Apply these permissions automatically" @@ -5690,9 +5690,9 @@ msgstr "Indirizzi disponibili" #: ../../Zotlabs/Module/Connedit.php:866 ../../Zotlabs/Module/Defperms.php:245 msgid "" -"Some individual permissions may have been preset or locked based on your " -"channel type and privacy settings." -msgstr "" +"The permissions indicated on this page will be applied to all new " +"connections." +msgstr "I permessi indicati su questa pagina saranno applicati a tutti i nuovi contatti da ora in poi." #: ../../Zotlabs/Module/Connedit.php:867 msgid "Connection Tools" @@ -5839,42 +5839,41 @@ msgstr "Foto" msgid "Files" msgstr "Archivio file" -#: ../../Zotlabs/Module/Profiles.php:594 -msgid "Profile updated." -msgstr "Profilo aggiornato." +#: ../../Zotlabs/Module/Menu.php:49 +msgid "Unable to update menu." +msgstr "Impossibile aggiornare il menù." -#: ../../Zotlabs/Module/Profiles.php:678 -msgid "Hide your connections list from viewers of this profile" -msgstr "Nascondi la tua lista di contatti ai visitatori di questo profilo" +#: ../../Zotlabs/Module/Menu.php:60 +msgid "Unable to create menu." +msgstr "Impossibile creare il menù." -#: ../../Zotlabs/Module/Profiles.php:725 -msgid "Edit Profile Details" -msgstr "Modifica i dettagli del profilo" +#: ../../Zotlabs/Module/Menu.php:98 ../../Zotlabs/Module/Menu.php:110 +msgid "Menu Name" +msgstr "Nome del menu" -#: ../../Zotlabs/Module/Profiles.php:727 -msgid "View this profile" -msgstr "Guarda questo profilo" +#: ../../Zotlabs/Module/Menu.php:98 +msgid "Unique name (not visible on webpage) - required" +msgstr "Nome unico (non visibile sulla pagina) - obbligatorio" -#: ../../Zotlabs/Module/Profiles.php:728 ../../Zotlabs/Module/Profiles.php:827 -#: ../../include/channel.php:1320 -msgid "Edit visibility" -msgstr "Cambia la visibilità" +#: ../../Zotlabs/Module/Menu.php:99 ../../Zotlabs/Module/Menu.php:111 +msgid "Menu Title" +msgstr "Titolo del menu" -#: ../../Zotlabs/Module/Profiles.php:729 -msgid "Profile Tools" -msgstr "Gestione del profilo" +#: ../../Zotlabs/Module/Menu.php:99 +msgid "Visible on webpage - leave empty for no title" +msgstr "Visibile sulla pagina - lascia vuoto per non avere un titolo" -#: ../../Zotlabs/Module/Profiles.php:730 -msgid "Change cover photo" -msgstr "Cambia la copertina del canale" +#: ../../Zotlabs/Module/Menu.php:100 +msgid "Allow Bookmarks" +msgstr "Permetti i segnalibri" -#: ../../Zotlabs/Module/Profiles.php:731 ../../include/channel.php:1290 -msgid "Change profile photo" -msgstr "Cambia la foto del profilo" +#: ../../Zotlabs/Module/Menu.php:100 ../../Zotlabs/Module/Menu.php:157 +msgid "Menu may be used to store saved bookmarks" +msgstr "Puoi salvare i segnalibri nei menù" -#: ../../Zotlabs/Module/Profiles.php:732 -msgid "Create a new profile using these settings" -msgstr "Crea un nuovo profilo usando queste impostazioni" +#: ../../Zotlabs/Module/Menu.php:101 ../../Zotlabs/Module/Menu.php:159 +msgid "Submit and proceed" +msgstr "Salva e procedi" #: ../../Zotlabs/Module/Menu.php:107 ../../include/text.php:2423 msgid "Menus" @@ -5884,14 +5883,13 @@ msgstr "Menù" msgid "Bookmarks allowed" msgstr "Permetti segnalibri" -#: ../../Zotlabs/Module/Profiles.php:739 ../../Zotlabs/Widget/Newmember.php:53 -#: ../../include/datetime.php:58 -msgid "Miscellaneous" -msgstr "Altro" +#: ../../Zotlabs/Module/Menu.php:119 +msgid "Delete this menu" +msgstr "Elimina questo menù" -#: ../../Zotlabs/Module/Profiles.php:741 -msgid "Import profile from file" -msgstr "Importa il profilo da un file" +#: ../../Zotlabs/Module/Menu.php:120 ../../Zotlabs/Module/Menu.php:154 +msgid "Edit menu contents" +msgstr "Modifica i contenuti del menù" #: ../../Zotlabs/Module/Menu.php:121 msgid "Edit this menu" @@ -6545,7 +6543,7 @@ msgstr "Homepage del progetto" #: ../../Zotlabs/Module/Siteinfo.php:32 msgid "Developer homepage" -msgstr "Homepage dello sviluppatore" +msgstr "Homepege dello sviluppatore" #: ../../Zotlabs/Module/Ratings.php:70 msgid "No ratings" diff --git a/view/it/hstrings.php b/view/it/hstrings.php index 1f5527946..42fc58347 100644 --- a/view/it/hstrings.php +++ b/view/it/hstrings.php @@ -1393,7 +1393,7 @@ App::$strings["This site is powered by \$Projectname"] = "Questo sito è costrui App::$strings["Federated and decentralised networking and identity services provided by Zot"] = ""; App::$strings["Version %s"] = "Versione %s"; App::$strings["Project homepage"] = "Homepage del progetto"; -App::$strings["Developer homepage"] = "Homepage dello sviluppatore"; +App::$strings["Developer homepage"] = "Homepege dello sviluppatore"; App::$strings["No ratings"] = "Nessuna valutazione"; App::$strings["Ratings"] = "Valutazioni"; App::$strings["Rating: "] = "Valutazione:"; diff --git a/view/js/autocomplete.js b/view/js/autocomplete.js index 54eb03e13..6b77f0631 100644 --- a/view/js/autocomplete.js +++ b/view/js/autocomplete.js @@ -163,7 +163,7 @@ function string2bb(element) { // Autocomplete contacts contacts = { - match: /(^|\s)(@\!*)([^ \n]{2,})$/, + match: /(^|\s)(@\!*)([^ \n]{3,})$/, index: 3, cache: true, search: function(term, callback) { contact_search(term, callback, backend_url, 'c', extra_channels, spinelement=false); }, @@ -195,12 +195,12 @@ function string2bb(element) { smilies = { - match: /(^|\s)(:[a-z_:]{2,})$/, + match: /(^|\s)(:[a-z0-9_:]{2,})$/, index: 2, cache: true, - search: function(term, callback) { $.getJSON('/smilies/json').done(function(data) { callback($.map(data, function(entry) { return entry.text.indexOf(term) === 0 ? entry : null; })); }); }, - //template: function(item) { return item.icon + item.text; }, + search: function(term, callback) { $.getJSON('/smilies/json').done(function(data) { callback($.map(data, function(entry) { return entry.text.indexOf(term.substr(1)) !== -1 ? entry : null; })); }); }, replace: function(item) { return "$1" + item.text + ' '; }, + context: function(text) { return text.toLowerCase(); }, template: smiley_format }; this.attr('autocomplete','off'); @@ -209,8 +209,12 @@ function string2bb(element) { $(this).each(function() { var editor = new Textarea(this); - var textcomplete = new Textcomplete(editor); - textcomplete.register([contacts,forums,smilies,tags], {className:'acpopup', zIndex:1020}); + var textcomplete = new Textcomplete(editor, { + dropdown: { + maxCount: 100 + } + }); + textcomplete.register([contacts,forums,smilies,tags]); }); @@ -264,8 +268,12 @@ function string2bb(element) { $(this).each(function() { var editor = new Textarea(this); - textcomplete = new Textcomplete(editor); - textcomplete.register([contacts,forums,tags], {className:'acpopup', maxCount:100, zIndex: 1020, appendTo:'nav'}); + textcomplete = new Textcomplete(editor, { + dropdown: { + maxCount: 100 + } + }); + textcomplete.register([contacts,forums,tags]); }); textcomplete.on('selected', function() { this.editor.el.form.submit(); }); @@ -299,8 +307,12 @@ function string2bb(element) { $(this).each(function() { var editor = new Textarea(this); - textcomplete = new Textcomplete(editor); - textcomplete.register([contacts], {className:'acpopup', zIndex:1020}); + textcomplete = new Textcomplete(editor, { + dropdown: { + maxCount: 100 + } + }); + textcomplete.register([contacts]); }); if(autosubmit) @@ -338,8 +350,12 @@ function string2bb(element) { $(this).each(function() { var editor = new Textarea(this); - textcomplete = new Textcomplete(editor); - textcomplete.register([names], {className:'acpopup', zIndex:1020}); + textcomplete = new Textcomplete(editor, { + dropdown: { + maxCount: 100 + } + }); + textcomplete.register([names]); }); if(autosubmit) @@ -358,8 +374,8 @@ function string2bb(element) { return; if(type=='bbcode') { - var open_close_elements = ['bold', 'italic', 'underline', 'overline', 'strike', 'superscript', 'subscript', 'quote', 'code', 'open', 'spoiler', 'map', 'nobb', 'list', 'checklist', 'ul', 'ol', 'dl', 'li', 'table', 'tr', 'th', 'td', 'center', 'color', 'font', 'size', 'zrl', 'zmg', 'rpost', 'qr', 'observer', 'observer.language','embed', 'highlight', 'url', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6']; - var open_elements = ['observer.baseurl', 'observer.address', 'observer.photo', 'observer.name', 'observer.webname', 'observer.url', '*', 'hr', ]; + var open_close_elements = ['bold', 'italic', 'underline', 'overline', 'strike', 'superscript', 'subscript', 'quote', 'code', 'open', 'spoiler', 'summary', 'map', 'nobb', 'list', 'checklist', 'ul', 'ol', 'dl', 'li', 'table', 'tr', 'th', 'td', 'center', 'color', 'font', 'size', 'zrl', 'zmg', 'rpost', 'qr', 'observer', 'observer.language','embed', 'highlight', 'url', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6']; + var open_elements = ['observer.baseurl', 'observer.address', 'observer.photo', 'observer.name', 'observer.webname', 'observer.url', '*', 'hr' ]; var elements = open_close_elements.concat(open_elements); } @@ -420,7 +436,7 @@ function string2bb(element) { $(this).each(function() { var editor = new Textarea(this); var textcomplete = new Textcomplete(editor); - textcomplete.register([bbco], {className:'acpopup', zIndex:1020}); + textcomplete.register([bbco]); }); this.keypress(function(e){ diff --git a/view/ru/hmessages.po b/view/ru/hmessages.po index 006e3a80e..d21f707d1 100644 --- a/view/ru/hmessages.po +++ b/view/ru/hmessages.po @@ -1,7 +1,7 @@ -# hubzilla -# Copyright (C) 2012-2016 hubzilla -# This file is distributed under the same license as the hubzilla package. -# Mike Macgirvin, 2012 +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. # # Translators: # Alex , 2016-2017 @@ -21,9 +21,9 @@ msgstr "" "Language: ru\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : (n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2))\n" -#: ../../Zotlabs/Access/Permissions.php:56 -msgid "Can view my channel stream and posts" -msgstr "Может просматривать мою ленту и сообщения" +#: ../../util/nconfig.php:34 +msgid "Source channel not found." +msgstr "Канал-источник не найден." #: ../../view/theme/redbasic/php/config.php:15 ../../include/text.php:3087 #: ../../Zotlabs/Module/Admin/Site.php:187 @@ -3699,21 +3699,21 @@ msgstr "В процессе" msgid "Cancelled" msgstr "Отменено" -#: ../../Zotlabs/Module/Settings/Channel.php:543 -msgid "Default Privacy Group" -msgstr "Группа конфиденциальности по умолчанию" +#: ../../include/auth.php:192 +msgid "Delegation session ended." +msgstr "Делегированная сессия завершена." -#: ../../Zotlabs/Module/Settings/Channel.php:545 -msgid "Use my default audience setting for the type of object published" -msgstr "Использовать настройки аудитории по умолчанию для типа опубликованного объекта" +#: ../../include/auth.php:196 +msgid "Logged out." +msgstr "Вышел из системы." -#: ../../Zotlabs/Module/Settings/Channel.php:546 -msgid "Profile to assign new connections" -msgstr "Назначить профиль для новых контактов" +#: ../../include/auth.php:291 +msgid "Email validation is incomplete. Please check your email." +msgstr "Проверка email не завершена. Пожалуйста, проверьте вашу почту." -#: ../../Zotlabs/Module/Settings/Channel.php:556 -msgid "Default permissions category" -msgstr "Категория разрешений по умолчанию" +#: ../../include/auth.php:307 +msgid "Failed authentication" +msgstr "Ошибка аутентификации" #: ../../include/auth.php:317 #: ../../extend/addon/hzaddons/openid/Mod_Openid.php:188 diff --git a/view/ru/hstrings.php b/view/ru/hstrings.php index 27d5d10aa..598d02718 100644 --- a/view/ru/hstrings.php +++ b/view/ru/hstrings.php @@ -1569,7 +1569,6 @@ App::$strings["or"] = "или"; App::$strings["Your channel address is"] = "Адрес вашего канала"; App::$strings["Your files/photos are accessible via WebDAV at"] = "Ваши файлы / фотографии доступны через WebDAV по"; App::$strings["Automatic membership approval"] = "Членство одобрено автоматически"; -App::$strings["If enabled, connection requests will be approved without your interaction"] = "Если включено, запросы контактов будут одобрены без вашего участия"; App::$strings["Channel Settings"] = "Настройки канала"; App::$strings["Basic Settings"] = "Основные настройки"; App::$strings["Your Timezone:"] = "Часовой пояс:"; @@ -1974,10 +1973,7 @@ App::$strings["This role will be used for the first channel created after regist App::$strings["Site"] = "Сайт"; App::$strings["File upload"] = "Загрузка файла"; App::$strings["Policies"] = "Правила"; -App::$strings["Site default technical skill level"] = "Уровень технических навыков на сайте по умолчанию"; -App::$strings["Used to provide a member experience matched to technical comfort level"] = "Используется чтобы обеспечить удобство на уровне технических навыков пользователя"; -App::$strings["Lock the technical skill level setting"] = "Заблокировать уровень технических навыков"; -App::$strings["Members can set their own technical comfort level by default"] = "Участники могут выбрать уровень своих технических навыков по умолчанию"; +App::$strings["Site name"] = "Название сайта"; App::$strings["Banner/Logo"] = "Баннер / логотип"; App::$strings["Unfiltered HTML/CSS/JS is allowed"] = "Разрешён нефильтруемый HTML/CSS/JS"; App::$strings["Administrator Information"] = "Информация об администраторе"; diff --git a/view/theme/redbasic/css/style.css b/view/theme/redbasic/css/style.css index 4f0658477..489d71735 100644 --- a/view/theme/redbasic/css/style.css +++ b/view/theme/redbasic/css/style.css @@ -1474,6 +1474,12 @@ blockquote { background-color: $item_colour; } +.textcomplete-dropdown { + max-height: 300px; + max-width: 250px; + overflow: auto; +} + .dropdown-item.active { color: #fff; background-color: #007bff; diff --git a/view/tpl/build_query.tpl b/view/tpl/build_query.tpl index 2c55a8140..fcb22b605 100755 --- a/view/tpl/build_query.tpl +++ b/view/tpl/build_query.tpl @@ -31,6 +31,7 @@ var bParam_verb = "{{$verb}}"; var bParam_net = "{{$net}}"; var bParam_pf = "{{$pf}}"; + var bParam_unseen = "{{$unseen}}"; function buildCmd() { var udargs = ((page_load) ? "/load" : ""); @@ -62,6 +63,7 @@ if(bParam_net != "") bCmd = bCmd + "&net=" + bParam_net; if(bParam_page != 1) bCmd = bCmd + "&page=" + bParam_page; if(bParam_pf != 0) bCmd = bCmd + "&pf=" + bParam_pf; + if(bParam_unseen != 0) bCmd = bCmd + "&unseen=" + bParam_unseen; return(bCmd); } diff --git a/view/tpl/notifications_widget.tpl b/view/tpl/notifications_widget.tpl index 9b3d7487e..f43d82301 100644 --- a/view/tpl/notifications_widget.tpl +++ b/view/tpl/notifications_widget.tpl @@ -143,7 +143,7 @@