Commit 49a91162 authored by liuqiao's avatar liuqiao

修改分站房源管理发布/编辑房源的 全景图/室内图/外景图/户型图上传图片方法

parent 963f994b
<style> <style>
.picPreviewBoxM_new{ .picPreviewBoxM_new{
overflow: visible; overflow: visible;
} }
.picPreviewBoxM_new .funMtext .input_r{ .picPreviewBoxM_new .funMtext .input_r{
margin:5px 3px 0; margin:5px 3px 0;
} }
.picPreviewBoxM_new .funMtext .delBtn{ .picPreviewBoxM_new .funMtext .delBtn{
margin:5px 3px 0; margin:5px 3px 0;
} }
.picPreviewBoxM_new .inputBoxM{ .picPreviewBoxM_new .inputBoxM{
padding-top: 10px; padding-top: 10px;
position: relative; position: relative;
} }
.picPreviewBoxM_new .inputBoxM .cha_new{ .picPreviewBoxM_new .inputBoxM .cha_new{
position: absolute;right: 6px;bottom: 10px; position: absolute;right: 6px;bottom: 10px;
display: block;width: 8px;height: 7px;background: url("close_1.png"); display: block;width: 8px;height: 7px;background: url("close_1.png");
cursor: pointer; cursor: pointer;
} }
.picPreviewBoxM_new .inputBoxM .input_text{ .picPreviewBoxM_new .inputBoxM .input_text{
color: #000; color: #000;
} }
.picPreviewBox_new .picPreviewBox_new
{ {
overflow: visible; overflow: visible;
} }
.listImitate_new .inner{ .listImitate_new .inner{
width: 134px; width: 134px;
} }
.listImitate_new .link{ .listImitate_new .link{
width: 126px; width: 126px;
} }
.labelImitate_new{ .labelImitate_new{
width: 110px; width: 110px;
} }
.labelImitate_new .newred{ .labelImitate_new .newred{
color: #ff0000; color: #ff0000;
} }
.imitateSelect_new .imitateIe { .imitateSelect_new .imitateIe {
width: 121px; width: 121px;
border-color: #e0e0e0; border-color: #e0e0e0;
} }
.imitateSelect_new .inputHover{ .imitateSelect_new .inputHover{
border-color: #d9d9d9; border-color: #d9d9d9;
} }
.mt10{ .mt10{
margin-top: 10px; margin-top: 10px;
} }
input::-ms-clear{display:none;} input::-ms-clear{display:none;}
</style> </style>
...@@ -61,9 +61,8 @@ input::-ms-clear{display:none;} ...@@ -61,9 +61,8 @@ input::-ms-clear{display:none;}
<div class="addPicBox radius3"> <div class="addPicBox radius3">
<div class="addPicLeft">全景图</div> <div class="addPicLeft">全景图</div>
<div class="addPicRight pre"> <div class="addPicRight pre">
<div class="addBtn radius5"> <div style="width: 89px;" id="spanButtonPlaceholder<?=$key?>" class="addBtn radius5">
<span id="360image"></span> <span>从电脑选择图片</span>
<span id="360imageFlag" style="display:none;"></span>
</div> </div>
<div class="addBtn radius5 "> <div class="addBtn radius5 ">
...@@ -156,48 +155,113 @@ input::-ms-clear{display:none;} ...@@ -156,48 +155,113 @@ input::-ms-clear{display:none;}
<script> <script>
//360全景传图方法 //360全景传图方法
var get_panorama_wechat_info; var get_panorama_wechat_info;
//
var imageNum = <?php echo $imageNum;?>;
//360全景上传图片数据集
var imageArr = [];
//
var imageType = <?php echo json_encode($imageType);?>;
var pic_from_sell = 0;
const uploadImgLimit = 15; //最大上传数量
function uploads_zsb_360(id,key) {
var uploader = new plupload.Uploader({
browse_button: id, //触发文件选择对话框的按钮,为那个元素id
//url: '/pic/house?pic_from_sell='+pic_from_sell, //服务器端的上传页面地址
url:'http://newrent.house365.com/ajax-action/upload-file',
flash_swf_url: '/source/common/js/plupload-2.3.6/js/Moxie.swf', //swf文件,当需要使用swf方式进行上传时需要配置该参数
silverlight_xap_url: '/source/common/js/plupload-2.3.6/js/Moxie.xap', //silverlight文件,当需要使用silverlight方式进行上传时需要配置该参数
multi_selection: true,
filters: {
mime_types: [ //只允许上传图片和zip文件
{title: "images", extensions: "jpg,jpeg,png"},
],
max_file_size:'5M'
},
file_data_name:'file_name',
resize:{
quality:70
}
});
// //在实例对象上调用init()方法进行初始化
var imageNum = <?php echo $imageNum;?>; uploader.init();
//360全景上传图片数据集 uploader.bind('BeforeUpload',function (uploader,file) {
var imageArr = []; let uploadImgLength = $("#showImage").find('img').length; //已经存在的全景图数量
if(uploadImgLength >= uploadImgLimit){
alert('全景图上传最多'+uploadImgLimit+'张');
uploader.stop();
// uploader.removeFile(file)
return;
}
// });
var imageType = <?php echo json_encode($imageType);?>;
$(function(){ //绑定各种事件,并在事件监听函数中做你想做的事
<?php if(!empty($houseRelation360PicData)){ foreach($houseRelation360PicData as $key => $item){ ?> uploader.bind('FilesAdded', function (uploader, files) {
imageArr["image_"+<?php echo $item['id'];?>] = "<?php echo $item['filename'];?>"; //每个事件监听函数都会传入一些很有用的参数,
<?php }}?> //我们可以利用这些参数提供的信息来做比如更新UI,提示上传进度等操作
uploader.start(); //调用实例对象的start()方法开始上传文件,当然你也可以在其他地方调用该方法
});
uploader.bind('UploadProgress', function (uploader, file) {
//每个事件监听函数都会传入一些很有用的参数,
//我们可以利用这些参数提供的信息来做比如更新UI,提示上传进度等操作
});
//上传成功处理事件 uploader.bind('FileUploaded', function (uploader, files, result) {
function uploadSuccessEvent(file, serverData) var response = JSON.parse(result.response);
{ var status = response.status;
if(serverData == '0') if(status != 'success'){
{ alert('图片上传失败:'+ response.msg);
return false; return false;
} }
else if(serverData == '1')
{ var imgurl = response.pic_url;
alert('图片的宽不可小于322像素,高不可小于236像素'); if(imgurl == '1'){
if(pic_from_sell==1){
alert('图片的宽不可小于700像素,高不可小于500像素');
}else{
alert('图片的宽不可小于322像素,高不可小于200像素');
}
return false;
}
uploadSuccessEvent(imgurl,key,'thumbnails'+key)
});
uploader.bind('Error',function (uploader,errObject) {
if(errObject.code == '-600'){
alert('图片过大,不能超过5M');
return false;
}else if(errObject.code == plupload.FILE_EXTENSION_ERROR){
alert("文件格式不是图片,上传失败");
return false;
}else{
alert('上传失败');
return false; return false;
} }
})
}
//上传成功处理事件
function uploadSuccessEvent(src) {
imageNum++; imageNum++;
imageArr['image_'+imageNum] = serverData; imageArr['image_'+imageNum] = src;
//租售宝360全景图片HTML结构 //租售宝360全景图片HTML结构
var html = ''; var html = '';
html += '<div class="mItem" id="image_'+imageNum+'" imageNum="'+imageNum+'">'; html += '<div class="mItem" id="image_'+imageNum+'" imageNum="'+imageNum+'">';
html += '<div class="mItemInner">'; html += '<div class="mItemInner">';
html += '<div class="mPic">'; html += '<div class="mPic">';
html += '<img width="130" height="100" alt="" src="'+serverData+'" style="opacity: 1;">'; html += '<img width="130" height="100" alt="" src="'+src+'" style="opacity: 1;">';
html += '<input type="hidden" name="imageUrl['+imageNum+']" value="'+serverData+'">'; html += '<input type="hidden" name="imageUrl['+imageNum+']" value="'+src+'">';
//html += '<input type="hidden" name="p_sort[]" value="0" class="psort">'; //html += '<input type="hidden" name="p_sort[]" value="0" class="psort">';
html += '<div class="funM" style="opacity: 0.6;"></div>'; html += '<div class="funM" style="opacity: 0.6;"></div>';
...@@ -205,7 +269,7 @@ $(function(){ ...@@ -205,7 +269,7 @@ $(function(){
html += '<label>'; html += '<label>';
html += '<a imageNum='+imageNum+' title="查看大图" href="javascript:void(0);" target="_balnk" style="bottom:84px;" class="bigPicLin bigPicLinpanorama"></a>'; html += '<a imageNum='+imageNum+' title="查看大图" href="javascript:void(0);" target="_balnk" style="bottom:84px;" class="bigPicLin bigPicLinpanorama"></a>';
html += '<input type="radio" class="input_r Js_defaultPic" name="jsPicPreviewList" id="picPreview_'+imageNum+'" value="'+serverData+'">封面'; html += '<input type="radio" class="input_r Js_defaultPic" name="jsPicPreviewList" id="picPreview_'+imageNum+'" value="'+src+'">封面';
html += '</label>'; html += '</label>';
html += '<div class="delBtn delImage" imageNum="'+imageNum+'" title="删除"></div>'; html += '<div class="delBtn delImage" imageNum="'+imageNum+'" title="删除"></div>';
...@@ -240,6 +304,15 @@ $(function(){ ...@@ -240,6 +304,15 @@ $(function(){
$('#showImage').append(html); $('#showImage').append(html);
$('#imageInfo').show(); $('#imageInfo').show();
} }
$(function(){
<?php if(!empty($houseRelation360PicData)){ foreach($houseRelation360PicData as $key => $item){ ?>
imageArr["image_"+<?php echo $item['id'];?>] = "<?php echo $item['filename'];?>";
<?php }}?>
var ids<?=$key?>;
uploads_zsb_360("spanButtonPlaceholder<?=$key?>","<?=$key?>");
$('.imageSelect').live('click',function(){ $('.imageSelect').live('click',function(){
$(this).find(".imitate").focus().addClass("inputHover"); $(this).find(".imitate").focus().addClass("inputHover");
...@@ -252,53 +325,6 @@ $(function(){ ...@@ -252,53 +325,6 @@ $(function(){
$(this).find(".imitate").removeClass("inputHover").end().find(".listImitate").hide(); $(this).find(".imitate").removeClass("inputHover").end().find(".listImitate").hide();
}); });
//初始化页面是否加载swfUpload事件
function swfUploadLoadedEvent()
{
//判断是否超过图片限制
var mItemObj = $('#showImage').find('.mItem');
if(mItemObj.length >= this.customSettings.upload_limit)
{
this.setButtonDisabled(true);
}
}
function fileDialogStartEvent()
{
//判断是否超过图片限制
var mItemObj = $('#showImage').find('.mItem');
var n = this.customSettings.upload_limit - mItemObj.length;
this.setFileQueueLimit(n);
}
//确认选择某个文件之后,触发事件
function fileDialogCompleteEvent(numFilesSelected, numFilesQueued)
{
//判断是否超过图片限制
var mItemObj = $('#showImage').find('.mItem');
var count = parseInt(this.customSettings.upload_limit);
if(numFilesSelected + mItemObj.length > count)
{
return false;
}
this.startUpload();
}
//检查上传文件是否小于下限
function fileQueuedMinLimit(fileObj)
{
if(fileObj.size < 358400)
{
alert(fileObj.name+'图片小于350,全景图大小不可低于350K,请换一张图片!');
this.stopUpload();
}
}
//删除全景图片 //删除全景图片
$('.delImage').live('click',function(){ $('.delImage').live('click',function(){
var imageNum = $(this).attr('imageNum'); var imageNum = $(this).attr('imageNum');
...@@ -337,49 +363,6 @@ $(function(){ ...@@ -337,49 +363,6 @@ $(function(){
$('#imageType_'+imageNum).val(type); $('#imageType_'+imageNum).val(type);
}); });
var upload_url = 'http://<?php echo GB_CITY; ?>.zsb.house365.com/pic/house/?uploadType=1';
var swfUploadObj = new SWFUpload({
// Backend Settings
upload_url : upload_url,
// File Upload Settings
file_size_limit : "5 MB",
file_types : "*.jpg;*.png;",
file_types_description : "Images",
file_upload_limit : "0",
file_queue_limit : "5",
custom_settings : {
upload_target : "360imageFlag",
upload_limit : "15"
},
// Event Handler Settings - these functions as defined in Handlers.js
// The handlers are not part of SWFUpload but are part of my website and control how
// my website reacts to the SWFUpload events.
swfupload_loaded_handler : swfUploadLoadedEvent,
file_queue_error_handler : fileQueueError,
file_dialog_start_handler : fileDialogStartEvent,
file_dialog_complete_handler : fileDialogCompleteEvent,
file_queued_handler : fileQueuedMinLimit,
upload_progress_handler : uploadProgress,
upload_error_handler : uploadError,
upload_success_handler : uploadSuccessEvent,
upload_complete_handler : uploadComplete,
// Button Settings
button_image_url : "",
button_placeholder_id : "360image",
button_width: 96,
button_height: 28,
button_cursor: SWFUpload.CURSOR.HAND,
button_text : '从电脑选择图片',
// Flash Settings
//flash_url : "<?=STATIC_SOURCE_URL?>/common/js/swf/swfupload.swf"
flash_url : "/swfupload.swf"
//Debug Settings
//debug: true
});
//图片选择拖动 //图片选择拖动
...@@ -503,5 +486,5 @@ $(function(){ ...@@ -503,5 +486,5 @@ $(function(){
$(this).attr('href',url); $(this).attr('href',url);
} }
}); });
}); });
</script> </script>
\ No newline at end of file
...@@ -8,8 +8,8 @@ foreach($arr_sort as $key=>$sort) { ?> ...@@ -8,8 +8,8 @@ foreach($arr_sort as $key=>$sort) { ?>
<div class="addPicBox radius3"> <div class="addPicBox radius3">
<div class="addPicLeft"><?=$sort?></div> <div class="addPicLeft"><?=$sort?></div>
<div class="addPicRight pre"> <div class="addPicRight pre">
<div class="addBtn radius5"> <div style="width: 89px;" id="spanButtonPlaceholder<?=$key?>" class="addBtn radius5">
<span id="spanButtonPlaceholder<?=$key?>"></span> <span>从电脑选择图片</span>
</div> </div>
<?php <?php
...@@ -144,56 +144,11 @@ foreach($arr_sort as $key=>$sort) { ?> ...@@ -144,56 +144,11 @@ foreach($arr_sort as $key=>$sort) { ?>
<script type="text/javascript"> <script type="text/javascript">
var swfu<?=$key?>; var swfu<?=$key?>;
var ids<?=$key?>;
$(function() { $(function() {
swfu<?=$key?> = new SWFUpload({
// Backend Settings
upload_url: "<?=$upload_pic_url?>",
//post_params: {"PHPSESSID": "5onmcek5m1qsu5e5nor2tiq325"},
//post_params: {"postion" : position},
// File Upload Settings
file_size_limit : "5 MB", // 5MB
file_types : "*.jpg;*.png;*.jpeg;",
file_types_description : "Images",
file_upload_limit : "0",
file_queue_limit : "5",
custom_settings : {
upload_target : "jsPicPreviewBoxM<?=$key?>",
upload_limit : <?=$uploadlimit[$key]?>,
upload_nail : "thumbnails<?=$key?>",
upload_infotype : <?=$key?>
},
// Event Handler Settings - these functions as defined in Handlers.js uploads_zsb("spanButtonPlaceholder<?=$key?>","<?=$key?>");
// The handlers are not part of SWFUpload but are part of my website and control how
// my website reacts to the SWFUpload events.
swfupload_loaded_handler : swfUploadLoaded,
file_queue_error_handler : fileQueueError,
file_dialog_start_handler : fileDialogStart,
file_dialog_complete_handler : fileDialogComplete,
upload_progress_handler : uploadProgress,
upload_error_handler : uploadError,
upload_success_handler : uploadSuccess,
upload_complete_handler : uploadComplete,
// Button Settings
button_image_url : "",
button_placeholder_id : "spanButtonPlaceholder<?=$key?>",
button_width: 96,
button_height: 28,
button_cursor: SWFUpload.CURSOR.HAND,
button_text:"从电脑选择图片",
// Flash Settings
//flash_url : "<?=STATIC_SOURCE_URL?>/common/js/swf/swfupload.swf"
flash_url : "/swfupload.swf"
// Debug Settings
//debug: true
});
}); });
</script> </script>
...@@ -276,10 +231,121 @@ foreach($arr_sort as $key=>$sort) { ?> ...@@ -276,10 +231,121 @@ foreach($arr_sort as $key=>$sort) { ?>
<input type='hidden' name='deleteupload' value='1' /> <input type='hidden' name='deleteupload' value='1' />
<input type='hidden' id="delpic" name='delpic' value='' /> <input type='hidden' id="delpic" name='delpic' value='' />
<input type='hidden' id="pic1" name='pic1' value='<?=$house_detail['pic1']?>' /> <input type='hidden' id="pic1" name='pic1' value='<?=$house_detail['pic1']?>' />
<script src="/source/common/js/plupload-2.3.6/js/plupload.full.min.js"></script>
<script type="text/javascript"> <script type="text/javascript">
$(function(){
var pic_from_sell = <?php echo empty($pic_from_sell) ? 0 : 1?>;
var mycars=new Array();
mycars[2]=10;
mycars[1]=5;
mycars[0]=3;
function uploads_zsb(id,key) {
var uploader = new plupload.Uploader({
browse_button: id, //触发文件选择对话框的按钮,为那个元素id
//url: '/pic/house?pic_from_sell='+pic_from_sell, //服务器端的上传页面地址
url:'http://newrent.house365.com/ajax-action/upload-file',
flash_swf_url: '/source/common/js/plupload-2.3.6/js/Moxie.swf', //swf文件,当需要使用swf方式进行上传时需要配置该参数
silverlight_xap_url: '/source/common/js/plupload-2.3.6/js/Moxie.xap', //silverlight文件,当需要使用silverlight方式进行上传时需要配置该参数
multi_selection: true,
filters: {
mime_types: [ //只允许上传图片和zip文件
{title: "images", extensions: "jpg,jpeg,png"},
],
max_file_size:'5M'
},
file_data_name:'file_name',
resize:{
quality:70
}
});
//在实例对象上调用init()方法进行初始化
uploader.init();
uploader.bind('BeforeUpload',function (uploader,file) {
var leng = mycars[key];
var kid = $('#thumbnails'+key).find('img').length;
if(kid >= leng){
alert('图片上传最多'+leng+'张');
uploader.stop();
uploader.removeFile(file)
return;
}
});
//绑定各种事件,并在事件监听函数中做你想做的事
uploader.bind('FilesAdded', function (uploader, files) {
//每个事件监听函数都会传入一些很有用的参数,
//我们可以利用这些参数提供的信息来做比如更新UI,提示上传进度等操作
uploader.start(); //调用实例对象的start()方法开始上传文件,当然你也可以在其他地方调用该方法
});
uploader.bind('UploadProgress', function (uploader, file) {
//每个事件监听函数都会传入一些很有用的参数,
//我们可以利用这些参数提供的信息来做比如更新UI,提示上传进度等操作
});
uploader.bind('FileUploaded', function (uploader, files, result) {
var response = JSON.parse(result.response);
var status = response.status;
if(status != 'success'){
alert('图片上传失败:'+ response.msg);
return false;
}
var imgurl = response.pic_url;
if(imgurl == '1'){
if(pic_from_sell==1){
alert('图片的宽不可小于700像素,高不可小于500像素');
}else{
alert('图片的宽不可小于322像素,高不可小于200像素');
}
return false;
}
addImageNew(imgurl,key,'thumbnails'+key)
});
uploader.bind('Error',function (uploader,errObject) {
if(errObject.code == '-600'){
alert('图片过大,不能超过5M');
return false;
}else if(errObject.code == plupload.FILE_EXTENSION_ERROR){
alert("文件格式不是图片,上传失败");
return false;
}else{
alert('上传失败');
return false;
}
})
}
function addImageNew(src, upload_infotype, upload_nail) {
var oSwfu = upload_infotype == 0 ? swfu0 : (upload_infotype == 1 ? swfu1 : swfu2);
if (src != '' && src != '0')
{
var pid = src.split('pid=');
var joinhtml = upload_infotype == 0 || upload_infotype == 1 ? "<table style='line-height:20px;height:20px;background:#EDEDED;'><tr><td style='width:12px;'><input style='width:12px;margin-left:5px;border:0px;' type='checkbox' onclick='checkPblockPic(this);' value='p_block_" + pid[1] + "' checked /><input id='p_block_" + pid[1] + "' type='hidden' name='p_block[]' value='1' /></td><td>愿加入365图库</td></tr></table>" : "</td></tr><tr><td><input type='hidden' name='p_block[]' value='0' />&nbsp;";
var tableheight = upload_infotype == 2 ? "height:165px;" : "height:167px;";
var bigimg = src.replace('/thumb', '');
if(upload_infotype==10)
{
var content = '<div class="housepic"><img width="130" height="100" src="' + src + '" alt=""><input type="hidden" value="' + src + '" name="p_filename_real[]"><div class="funMtext"><div title="删除" id="' + upload_infotype + '" class="delBtn" imageSrc="' + src + '"></div></div></div>';
}
else {
var content = '<div class="mItem" style=""><div class="mItemInner"><div class="mPic"><img width="130" height="100" src="' + src + '" alt=""><input type="hidden" value="' + src + '" name="p_filename[]"><input class="psort" type="hidden" value="' + upload_infotype + '" name="p_sort[]"><div class="funM"></div><div class="funMtext"><label><input type="radio" value="' + src + '" onclick="setIndexPic(this);" name="jsPicPreviewList" class="input_r">封面</label><a class="bigPicLin" style="bottom:84px;" target="_balnk" href="' + bigimg + '" title="查看大图">查看大图</a><div title="删除" id="' + upload_infotype + '" class="delBtn" imageSrc="' + src + '"></div></div></div></div><div class="inputBoxM jsNameInput nameInput "><input type="text" onblur="if(this.value==\'\')this.value=\'图片描述30字\',this.className=\'jsInputCount input_text w126\'" onclick="if(this.value==\'图片描述30字\')this.value=\'\',this.className=\'jsInputCount input_text w126 input_text_on\'" class="jsInputCount input_text w126" value="图片描述30字" name="p_title[]"></div></div>';
}
$("#" + upload_nail).append(content);
$("#picshow" + upload_infotype).show();
}
}
$(function(){
/**** /****
var showBtn = $('.show-btn'), var showBtn = $('.show-btn'),
...@@ -566,7 +632,7 @@ foreach($arr_sort as $key=>$sort) { ?> ...@@ -566,7 +632,7 @@ foreach($arr_sort as $key=>$sort) { ?>
{ {
$('#pic1').val(''); $('#pic1').val('');
} }
/*
if($(this).attr("id")==0) if($(this).attr("id")==0)
{ {
swfu0.setButtonDisabled(false); swfu0.setButtonDisabled(false);
...@@ -578,7 +644,7 @@ foreach($arr_sort as $key=>$sort) { ?> ...@@ -578,7 +644,7 @@ foreach($arr_sort as $key=>$sort) { ?>
if($(this).attr("id")==2) if($(this).attr("id")==2)
{ {
swfu2.setButtonDisabled(false); swfu2.setButtonDisabled(false);
} }*/
$(this).parents(".mItem").remove(); $(this).parents(".mItem").remove();
var oNum = $(this).parents(".mItem").find("img").attr("num"); var oNum = $(this).parents(".mItem").find("img").attr("num");
...@@ -645,9 +711,9 @@ foreach($arr_sort as $key=>$sort) { ?> ...@@ -645,9 +711,9 @@ foreach($arr_sort as $key=>$sort) { ?>
}) })
} }
picPreview("jsPicPreviewList1",5,"thumbnails1",10) picPreview("jsPicPreviewList1",5,"thumbnails1",1)
picPreview("jsPicPreviewList2",10,"thumbnails2",2) picPreview("jsPicPreviewList2",10,"thumbnails2",2)
picPreview("jsPicPreviewList",3,"thumbnails0",9) picPreview("jsPicPreviewList",3,"thumbnails0",0)
......
...@@ -500,7 +500,7 @@ if (isset($infotype)) { ...@@ -500,7 +500,7 @@ if (isset($infotype)) {
$(this).parents(".housepic").remove(); $(this).parents(".housepic").remove();
swfu10.setButtonDisabled(false); // swfu10.setButtonDisabled(false);
}) })
......
{
"name": "plupload",
"license": "AGPLv3",
"authors": [
"Davit Barbakadze <davit.barbakadze@ephox.com>"
],
"homepage": "http://plupload.com",
"repository": {
"type": "git",
"url": "https://github.com/moxiecode/plupload.git"
},
"main": [
"./js/plupload.full.min.js"
],
"ignore": [
"tests/",
"src/",
"build/",
"examples/",
"Jakefile.js",
"package.json",
"bower.json",
"composer.json",
"README.md",
".*"
]
}
\ No newline at end of file
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Plupload - Custom example</title>
<!-- production -->
<script type="text/javascript" src="../js/plupload.full.min.js"></script>
<!-- debug
<script type="text/javascript" src="../js/moxie.js"></script>
<script type="text/javascript" src="../js/plupload.dev.js"></script>
-->
</head>
<body style="font: 13px Verdana; background: #eee; color: #333">
<h1>Custom example</h1>
<p>Shows you how to use the core plupload API.</p>
<div id="filelist">Your browser doesn't have Flash, Silverlight or HTML5 support.</div>
<br />
<div id="container">
<a id="pickfiles" href="javascript:;">[Select files]</a>
<a id="uploadfiles" href="javascript:;">[Upload files]</a>
</div>
<br />
<pre id="console"></pre>
<script type="text/javascript">
// Custom example logic
var uploader = new plupload.Uploader({
runtimes : 'html5,flash,silverlight,html4',
browse_button : 'pickfiles', // you can pass an id...
container: document.getElementById('container'), // ... or DOM Element itself
url : 'upload.php',
flash_swf_url : '../js/Moxie.swf',
silverlight_xap_url : '../js/Moxie.xap',
filters : {
max_file_size : '10mb',
mime_types: [
{title : "Image files", extensions : "jpg,gif,png"},
{title : "Zip files", extensions : "zip"}
]
},
init: {
PostInit: function() {
document.getElementById('filelist').innerHTML = '';
document.getElementById('uploadfiles').onclick = function() {
uploader.start();
return false;
};
},
FilesAdded: function(up, files) {
plupload.each(files, function(file) {
document.getElementById('filelist').innerHTML += '<div id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ') <b></b></div>';
});
},
UploadProgress: function(up, file) {
document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>";
},
Error: function(up, err) {
document.getElementById('console').appendChild(document.createTextNode("\nError #" + err.code + ": " + err.message));
}
}
});
uploader.init();
</script>
</body>
</html>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Plupload - Form dump</title>
</head>
<body style="font: 13px Verdana; background: #eee; color: #333">
<h1>Post dump</h1>
<p>Shows the form items posted.</p>
<table>
<tr>
<th>Name</th>
<th>Value</th>
</tr>
<?php $count = 0; foreach ($_POST as $name => $value) { ?>
<tr class="<?php echo $count % 2 == 0 ? 'alt' : ''; ?>">
<td><?php echo htmlentities(stripslashes($name)) ?></td>
<td><?php echo nl2br(htmlentities(stripslashes($value))) ?></td>
</tr>
<?php } ?>
</table>
</body>
</html>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Plupload - Events example</title>
<!-- production -->
<script type="text/javascript" src="../js/plupload.full.min.js"></script>
<!-- debug
<script type="text/javascript" src="../js/moxie.js"></script>
<script type="text/javascript" src="../js/plupload.dev.js"></script>
-->
</head>
<body style="font: 13px Verdana; background: #eee; color: #333">
<h1>Events example</h1>
<div id="container">
<a id="pickfiles" href="javascript:;">[Select files]</a>
<a id="uploadfiles" href="javascript:;">[Upload files]</a>
</div>
<br />
<pre id="console"></pre>
 
<script type="text/javascript">
var uploader = new plupload.Uploader({
        // General settings
        runtimes : 'silverlight,html4',
browse_button : 'pickfiles', // you can pass in id...
        url : 'upload.php',
        chunk_size : '1mb',
        unique_names : true,
 
        // Resize images on client-side if we can
        resize : { width : 320, height : 240, quality : 90 },
        
        filters : {
            max_file_size : '10mb',
// Specify what files to browse for
            mime_types: [
                {title : "Image files", extensions : "jpg,gif,png"},
                {title : "Zip files", extensions : "zip"}
            ]
        },
 
flash_swf_url : '../js/Moxie.swf',
silverlight_xap_url : '../js/Moxie.xap',
         
        // PreInit events, bound before the internal events
        preinit : {
            Init: function(up, info) {
                log('[Init]', 'Info:', info, 'Features:', up.features);
            },
 
            UploadFile: function(up, file) {
                log('[UploadFile]', file);
 
                // You can override settings before the file is uploaded
                // up.setOption('url', 'upload.php?id=' + file.id);
                // up.setOption('multipart_params', {param1 : 'value1', param2 : 'value2'});
            }
        },
 
        // Post init events, bound after the internal events
        init : {
PostInit: function() {
// Called after initialization is finished and internal event handlers bound
log('[PostInit]');
document.getElementById('uploadfiles').onclick = function() {
uploader.start();
return false;
};
},
Browse: function(up) {
                // Called when file picker is clicked
                log('[Browse]');
            },
            Refresh: function(up) {
                // Called when the position or dimensions of the picker change
                log('[Refresh]');
            },
 
            StateChanged: function(up) {
                // Called when the state of the queue is changed
                log('[StateChanged]', up.state == plupload.STARTED ? "STARTED" : "STOPPED");
            },
 
            QueueChanged: function(up) {
                // Called when queue is changed by adding or removing files
                log('[QueueChanged]');
            },
OptionChanged: function(up, name, value, oldValue) {
// Called when one of the configuration options is changed
log('[OptionChanged]', 'Option Name: ', name, 'Value: ', value, 'Old Value: ', oldValue);
},
BeforeUpload: function(up, file) {
// Called right before the upload for a given file starts, can be used to cancel it if required
log('[BeforeUpload]', 'File: ', file);
},
 
            UploadProgress: function(up, file) {
                // Called while file is being uploaded
                log('[UploadProgress]', 'File:', file, "Total:", up.total);
            },
FileFiltered: function(up, file) {
// Called when file successfully files all the filters
                log('[FileFiltered]', 'File:', file);
},
 
            FilesAdded: function(up, files) {
                // Called when files are added to queue
                log('[FilesAdded]');
 
                plupload.each(files, function(file) {
                    log('  File:', file);
                });
            },
 
            FilesRemoved: function(up, files) {
                // Called when files are removed from queue
                log('[FilesRemoved]');
 
                plupload.each(files, function(file) {
                    log('  File:', file);
                });
            },
 
            FileUploaded: function(up, file, info) {
                // Called when file has finished uploading
                log('[FileUploaded] File:', file, "Info:", info);
            },
 
            ChunkUploaded: function(up, file, info) {
                // Called when file chunk has finished uploading
                log('[ChunkUploaded] File:', file, "Info:", info);
            },
UploadComplete: function(up, files) {
// Called when all files are either uploaded or failed
                log('[UploadComplete]');
},
Destroy: function(up) {
// Called when uploader is destroyed
                log('[Destroy] ');
},
 
            Error: function(up, args) {
                // Called when error occurs
                log('[Error] ', args);
            }
        }
    });
 
 
    function log() {
        var str = "";
 
        plupload.each(arguments, function(arg) {
            var row = "";
 
            if (typeof(arg) != "string") {
                plupload.each(arg, function(value, key) {
                    // Convert items in File objects to human readable form
                    if (arg instanceof plupload.File) {
                        // Convert status to human readable
                        switch (value) {
                            case plupload.QUEUED:
                                value = 'QUEUED';
                                break;
 
                            case plupload.UPLOADING:
                                value = 'UPLOADING';
                                break;
 
                            case plupload.FAILED:
                                value = 'FAILED';
                                break;
 
                            case plupload.DONE:
                                value = 'DONE';
                                break;
                        }
                    }
 
                    if (typeof(value) != "function") {
                        row += (row ? ', ' : '') + key + '=' + value;
                    }
                });
 
                str += row + " ";
            } else {
                str += arg + " ";
            }
        });
 
        var log = document.getElementById('console');
        log.innerHTML += str + "\n";
    }
uploader.init();
</script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Plupload - Queue widget example</title>
<link rel="stylesheet" href="../../js/jquery.plupload.queue/css/jquery.plupload.queue.css" type="text/css" media="screen" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<!-- production -->
<script type="text/javascript" src="../../js/plupload.full.min.js"></script>
<script type="text/javascript" src="../../js/jquery.plupload.queue/jquery.plupload.queue.js"></script>
<!-- debug
<script type="text/javascript" src="../../js/moxie.js"></script>
<script type="text/javascript" src="../../js/plupload.dev.js"></script>
<script type="text/javascript" src="../../js/jquery.plupload.queue/jquery.plupload.queue.js"></script>
-->
</head>
<body style="font: 13px Verdana; background: #eee; color: #333">
<form method="post" action="dump.php">
<h1>Queue widget example</h1>
<p>Shows the jQuery Plupload Queue widget and under different runtimes.</p>
<div style="float: left; margin-right: 20px">
<h3>Flash runtime</h3>
<div id="flash_uploader" style="width: 500px; height: 330px;">Your browser doesn't have Flash installed.</div>
<h3>Silverlight runtime</h3>
<div id="silverlight_uploader" style="width: 500px; height: 330px;">Your browser doesn't have Silverlight installed.</div>
</div>
<div style="float: left; margin-right: 20px">
<h3>HTML 4 runtime</h3>
<div id="html4_uploader" style="width: 500px; height: 330px;">Your browser doesn't have HTML 4 support.</div>
<h3>HTML 5 runtime</h3>
<div id="html5_uploader" style="width: 500px; height: 330px;">Your browser doesn't support native upload.</div>
</div>
<br style="clear: both" />
<input type="submit" value="Send" />
</form>
<script type="text/javascript">
$(function() {
// Setup flash version
$("#flash_uploader").pluploadQueue({
// General settings
runtimes : 'flash',
url : '../upload.php',
chunk_size : '1mb',
unique_names : true,
filters : {
max_file_size : '10mb',
mime_types: [
{title : "Image files", extensions : "jpg,gif,png"},
{title : "Zip files", extensions : "zip"}
]
},
// Resize images on clientside if we can
resize : {width : 320, height : 240, quality : 90},
// Flash settings
flash_swf_url : '../../js/Moxie.swf'
});
// Setup silverlight version
$("#silverlight_uploader").pluploadQueue({
// General settings
runtimes : 'silverlight',
url : '../upload.php',
chunk_size : '1mb',
unique_names : true,
filters : {
max_file_size : '10mb',
mime_types: [
{title : "Image files", extensions : "jpg,gif,png"},
{title : "Zip files", extensions : "zip"}
]
},
// Resize images on clientside if we can
resize : {width : 320, height : 240, quality : 90},
// Silverlight settings
silverlight_xap_url : '../../js/Moxie.xap'
});
// Setup html5 version
$("#html5_uploader").pluploadQueue({
// General settings
runtimes : 'html5',
url : '../upload.php',
chunk_size : '1mb',
unique_names : true,
filters : {
max_file_size : '10mb',
mime_types: [
{title : "Image files", extensions : "jpg,gif,png"},
{title : "Zip files", extensions : "zip"}
]
},
// Resize images on clientside if we can
resize : {width : 320, height : 240, quality : 90}
});
// Setup html4 version
$("#html4_uploader").pluploadQueue({
// General settings
runtimes : 'html4',
url : '../upload.php',
unique_names : true,
filters : {
mime_types: [
{title : "Image files", extensions : "jpg,gif,png"},
{title : "Zip files", extensions : "zip"}
]
}
});
});
</script>
</body>
</html>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Plupload - jQuery UI Widget</title>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/themes/base/jquery-ui.css" type="text/css" />
<link rel="stylesheet" href="../../js/jquery.ui.plupload/css/jquery.ui.plupload.css" type="text/css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>
<!-- production -->
<script type="text/javascript" src="../../js/plupload.full.min.js"></script>
<script type="text/javascript" src="../../js/jquery.ui.plupload/jquery.ui.plupload.js"></script>
<!-- debug
<script type="text/javascript" src="../../js/moxie.js"></script>
<script type="text/javascript" src="../../js/plupload.dev.js"></script>
<script type="text/javascript" src="../../js/jquery.ui.plupload/jquery.ui.plupload.js"></script>
-->
</head>
<body style="font: 13px Verdana; background: #eee; color: #333">
<h1>jQuery UI Widget</h1>
<p>You can see this example with different themes on the <a href="http://plupload.com/example_jquery_ui.php">www.plupload.com</a> website.</p>
<form id="form" method="post" action="../dump.php">
<div id="uploader">
<p>Your browser doesn't have Flash, Silverlight or HTML5 support.</p>
</div>
<br />
<input type="submit" value="Submit" />
</form>
<script type="text/javascript">
// Initialize the widget when the DOM is ready
$(function() {
$("#uploader").plupload({
// General settings
runtimes : 'html5,flash,silverlight,html4',
url : '../upload.php',
// User can upload no more then 20 files in one go (sets multiple_queues to false)
max_file_count: 20,
chunk_size: '1mb',
// Resize images on clientside if we can
resize : {
width : 200,
height : 200,
quality : 90,
crop: true // crop to exact dimensions
},
filters : {
// Maximum file size
max_file_size : '1000mb',
// Specify what files to browse for
mime_types: [
{title : "Image files", extensions : "jpg,gif,png"},
{title : "Zip files", extensions : "zip"}
]
},
// Rename files by clicking on their titles
rename: true,
// Sort files
sortable: true,
// Enable ability to drag'n'drop files onto the widget (currently only HTML5 supports that)
dragdrop: true,
// Views to activate
views: {
list: true,
thumbs: true, // Show thumbs
active: 'thumbs'
},
// Flash settings
flash_swf_url : '../../js/Moxie.swf',
// Silverlight settings
silverlight_xap_url : '../../js/Moxie.xap'
});
// Handle the case when form was submitted before uploading has finished
$('#form').submit(function(e) {
// Files in queue upload them first
if ($('#uploader').plupload('getFiles').length > 0) {
// When all files are uploaded submit form
$('#uploader').on('complete', function() {
$('#form')[0].submit();
});
$('#uploader').plupload('start');
} else {
alert("You must have at least one file in the queue.");
}
return false; // Keep the form from submitting
});
});
</script>
</body>
</html>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Plupload - Queue widget example</title>
<link rel="stylesheet" href="../../js/jquery.plupload.queue/css/jquery.plupload.queue.css" type="text/css" media="screen" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<!-- production -->
<script type="text/javascript" src="../../js/plupload.full.min.js"></script>
<script type="text/javascript" src="../../js/jquery.plupload.queue/jquery.plupload.queue.js"></script>
<!-- debug
<script type="text/javascript" src="../../js/moxie.js"></script>
<script type="text/javascript" src="../../js/plupload.dev.js"></script>
<script type="text/javascript" src="../../js/jquery.plupload.queue/jquery.plupload.queue.js"></script>
-->
</head>
<body style="font: 13px Verdana; background: #eee; color: #333">
<form method="post" action="dump.php">
<div id="uploader">
<p>Your browser doesn't have Flash, Silverlight or HTML5 support.</p>
</div>
<input type="submit" value="Send" />
</form>
<script type="text/javascript">
$(function() {
// Setup html5 version
$("#uploader").pluploadQueue({
// General settings
runtimes : 'html5,flash,silverlight,html4',
url : '../upload.php',
chunk_size: '1mb',
rename : true,
dragdrop: true,
filters : {
// Maximum file size
max_file_size : '10mb',
// Specify what files to browse for
mime_types: [
{title : "Image files", extensions : "jpg,gif,png"},
{title : "Zip files", extensions : "zip"}
]
},
// Resize images on clientside if we can
resize : {width : 320, height : 240, quality : 90},
flash_swf_url : '../../js/Moxie.swf',
silverlight_xap_url : '../../js/Moxie.xap'
});
});
</script>
</body>
</html>
<?php
/*
In order to upload files to S3 using Flash runtime, one should start by placing crossdomain.xml into the bucket.
crossdomain.xml can be as simple as this:
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" secure="false" />
</cross-domain-policy>
In our tests SilverLight didn't require anything special and worked with this configuration just fine. It may fail back
to the same crossdomain.xml as last resort.
!!!Important!!! Plupload UI Widget here, is used only for demo purposes and is not required for uploading to S3.
*/
// important variables that will be used throughout this example
$bucket = 'BUCKET';
// these can be found on your Account page, under Security Credentials > Access Keys
$accessKeyId = 'ACCESS_KEY_ID';
$secret = 'SECRET_ACCESS_KEY';
// prepare policy
$policy = base64_encode(json_encode(array(
// ISO 8601 - date('c'); generates uncompatible date, so better do it manually
'expiration' => date('Y-m-d\TH:i:s.000\Z', strtotime('+1 day')),
'conditions' => array(
array('bucket' => $bucket),
array('acl' => 'public-read'),
array('starts-with', '$key', ''),
// for demo purposes we are accepting only images
array('starts-with', '$Content-Type', 'image/'),
// Plupload internally adds name field, so we need to mention it here
array('starts-with', '$name', ''),
// One more field to take into account: Filename - gets silently sent by FileReference.upload() in Flash
// http://docs.amazonwebservices.com/AmazonS3/latest/dev/HTTPPOSTFlash.html
array('starts-with', '$Filename', ''),
)
)));
// sign policy
$signature = base64_encode(hash_hmac('sha1', $policy, $secret, true));
?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Plupload to Amazon S3 Example</title>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/themes/base/jquery-ui.css" type="text/css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>
<!-- Load plupload and all it's runtimes and finally the UI widget -->
<link rel="stylesheet" href="../../js/jquery.ui.plupload/css/jquery.ui.plupload.css" type="text/css" />
<!-- production -->
<script type="text/javascript" src="../../js/plupload.full.min.js"></script>
<script type="text/javascript" src="../../js/jquery.ui.plupload/jquery.ui.plupload.js"></script>
<!-- debug
<script type="text/javascript" src="../../js/moxie.js"></script>
<script type="text/javascript" src="../../js/plupload.dev.js"></script>
<script type="text/javascript" src="../../js/jquery.ui.plupload/jquery.ui.plupload.js"></script>
-->
</head>
<body style="font: 13px Verdana; background: #eee; color: #333">
<h1>Plupload to Amazon S3 Example</h1>
<div id="uploader">
<p>Your browser doesn't have Flash, Silverlight or HTML5 support.</p>
</div>
<script type="text/javascript">
// Convert divs to queue widgets when the DOM is ready
$(function() {
$("#uploader").plupload({
runtimes : 'html5,flash,silverlight',
url : 'http://<?php echo $bucket; ?>.s3.amazonaws.com/',
multipart: true,
multipart_params: {
'key': '${filename}', // use filename as a key
'Filename': '${filename}', // adding this to keep consistency across the runtimes
'acl': 'public-read',
'Content-Type': 'image/jpeg',
'AWSAccessKeyId' : '<?php echo $accessKeyId; ?>',
'policy': '<?php echo $policy; ?>',
'signature': '<?php echo $signature; ?>'
},
// !!!Important!!!
// this is not recommended with S3, since it will force Flash runtime into the mode, with no progress indication
//resize : {width : 800, height : 600, quality : 60}, // Resize images on clientside, if possible
// optional, but better be specified directly
file_data_name: 'file',
filters : {
// Maximum file size
max_file_size : '10mb',
// Specify what files to browse for
mime_types: [
{title : "Image files", extensions : "jpg,jpeg"}
]
},
// Flash settings
flash_swf_url : '../../js/Moxie.swf',
// Silverlight settings
silverlight_xap_url : '../../js/Moxie.xap'
});
});
</script>
</body>
</html>
<?php
/**
* upload.php
*
* Copyright 2013, Moxiecode Systems AB
* Released under GPL License.
*
* License: http://www.plupload.com/license
* Contributing: http://www.plupload.com/contributing
*/
#!! IMPORTANT:
#!! this file is just an example, it doesn't incorporate any security checks and
#!! is not recommended to be used in production environment as it is. Be sure to
#!! revise it and customize to your needs.
// Make sure file is not cached (as it happens for example on iOS devices)
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
/*
// Support CORS
header("Access-Control-Allow-Origin: *");
// other CORS headers if any...
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
exit; // finish preflight CORS requests here
}
*/
// 5 minutes execution time
@set_time_limit(5 * 60);
// Uncomment this one to fake upload time
// usleep(5000);
// Settings
$targetDir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload";
//$targetDir = 'uploads';
$cleanupTargetDir = true; // Remove old files
$maxFileAge = 5 * 3600; // Temp file age in seconds
// Create target dir
if (!file_exists($targetDir)) {
@mkdir($targetDir);
}
// Get a file name
if (isset($_REQUEST["name"])) {
$fileName = $_REQUEST["name"];
} elseif (!empty($_FILES)) {
$fileName = $_FILES["file"]["name"];
} else {
$fileName = uniqid("file_");
}
$filePath = $targetDir . DIRECTORY_SEPARATOR . $fileName;
// Chunking might be enabled
$chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0;
$chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 0;
// Remove old temp files
if ($cleanupTargetDir) {
if (!is_dir($targetDir) || !$dir = opendir($targetDir)) {
die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}');
}
while (($file = readdir($dir)) !== false) {
$tmpfilePath = $targetDir . DIRECTORY_SEPARATOR . $file;
// If temp file is current file proceed to the next
if ($tmpfilePath == "{$filePath}.part") {
continue;
}
// Remove temp file if it is older than the max age and is not the current file
if (preg_match('/\.part$/', $file) && (filemtime($tmpfilePath) < time() - $maxFileAge)) {
@unlink($tmpfilePath);
}
}
closedir($dir);
}
// Open temp file
if (!$out = @fopen("{$filePath}.part", $chunks ? "ab" : "wb")) {
die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
}
if (!empty($_FILES)) {
if ($_FILES["file"]["error"] || !is_uploaded_file($_FILES["file"]["tmp_name"])) {
die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}');
}
// Read binary input stream and append it to temp file
if (!$in = @fopen($_FILES["file"]["tmp_name"], "rb")) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
}
} else {
if (!$in = @fopen("php://input", "rb")) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
}
}
while ($buff = fread($in, 4096)) {
fwrite($out, $buff);
}
@fclose($out);
@fclose($in);
// Check if file has been uploaded
if (!$chunks || $chunk == $chunks - 1) {
// Strip the temp .part suffix off
rename("{$filePath}.part", $filePath);
}
// Return Success JSON-RPC response
die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}');
// Arabic (ar)
plupload.addI18n({"Stop Upload":"أيقاف التحميل","Upload URL might be wrong or doesn't exist.":"عنوان التحميل ربما يكون خاطئ أو غير متوفر","tb":"تيرابايت","Size":"الحجم","Close":"أغلاق","You must specify either browse_button or drop_element.":"","Init error.":"خطأ في تهيئة","Add files to the upload queue and click the start button.":"أضف ملفات إلى القائمة إنتظار التحميل ثم أضغط على زر البداية","List":"","Filename":"أسم الملف","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"صيغة الصورة أما خطاء أو غير مدعومه","Status":"الحالة","HTTP Error.":"خطأ في برتوكول نقل الملفات","Start Upload":"أبدا التحميل","Error: File too large:":" خطاء : حجم الملف كبير :","kb":"كيلوبايت","Duplicate file error.":"خطاء في تكرار الملف","File size error.":"خطأ في حجم الملف","N/A":"لا شي","gb":"جيجابايت","Error: Invalid file extension:":"خطاء : أمتداد الملف غير صالح :","Select files":"أختر الملفات","%s already present in the queue.":"%s الملف موجود بالفعل في قائمة الانتظار","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"ملف: %s","b":"بايت","Uploaded %d/%d files":"تحميل %d/%d ملف","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"العناصر المقبوله لتحميل هي %d ملف في هذا الوقت. الملفات الاضافية أزيلة.","%d files queued":"%d الملفات في قائمة الانتظار","File: %s, size: %d, max file size: %d":"ملف: %s, أقصى حجم للملف: %d, حجم: %d","Thumbnails":"","Drag files here.":"سحب الملف هنا","Runtime ran out of available memory.":"الذاكرة المتوفره أنتهت لمدة التشغيل","File count error.":"خطاء في عد الملفات","File extension error.":"خطأ في أمتداد الملف","mb":"ميجابايت","Add Files":"أضف ملفات"});
\ No newline at end of file
// Azerbaijani (az)
plupload.addI18n({"Stop Upload":"Yükləməni saxla","Upload URL might be wrong or doesn't exist.":"Yükləmə ünvanı səhvdir və ya mövcud deyil","tb":"tb","Size":"Həcm","Close":"Bağla","You must specify either browse_button or drop_element.":"","Init error.":"Init error.","Add files to the upload queue and click the start button.":"Faylları əlavə edin və yüklə düyməsinə klikləyin.","List":"","Filename":"Faylın adı","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Şəklin formatı uyğun deyil və ya dəstəklənmir.","Status":"Status","HTTP Error.":"HTTP xətası.","Start Upload":"Yüklə","Error: File too large:":"Xəta:Fayl həcmi çox böyükdür.","kb":"kb","Duplicate file error.":"Bu fayl artıq növbədə var.","File size error.":"Fayl həcmi xətası.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Xəta: Yanlış fayl uzantısı:","Select files":"Faylları seçin","%s already present in the queue.":"%s artıq növbədə var.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Fayl: %s","b":"b","Uploaded %d/%d files":"%d/%d fayl yüklənib","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"Növbədə %d fayl var","File: %s, size: %d, max file size: %d":"Fayl: %s, həcm: %d, max fayl həcmi: %d","Thumbnails":"","Drag files here.":"Faylları bura çəkin.","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"Fayl sayı çox böyükdür.","File extension error.":"Fayl uzantısı xətası.","mb":"mb","Add Files":"Fayl əlavə et"});
\ No newline at end of file
// Bulgarian (bg)
plupload.addI18n({"Stop Upload":"Спрете качването","Upload URL might be wrong or doesn't exist.":"URL за качване може да е грешен или да не съществува.","tb":"tb","Size":"Размер","Close":"Затвори","You must specify either browse_button or drop_element.":"","Init error.":"Грешка: инициализиране.","Add files to the upload queue and click the start button.":"Добавете файлове в опашката за качване, и щракнете бутона старт.","List":"","Filename":"Име на файла","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Формата на изображението или е объркан, или не се поддържа.","Status":"Статус","HTTP Error.":"Грешка: HTTP .","Start Upload":"Започнете качването","Error: File too large:":"Грешка: Файла е твърде голям:","kb":"kb","Duplicate file error.":"Грешка: файла е вече качен на сървъра.","File size error.":"Грешка: размер на файла.","N/A":"не приложимо","gb":"gb","Error: Invalid file extension:":"Грешка: Невалидно разширение на файл:","Select files":"Изберете файлове","%s already present in the queue.":"%s вече го има в опашката.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Файл: %s","b":"b","Uploaded %d/%d files":"Качени %d/%d файла","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Елемента за качване приема само %d файл(а) наведнъж. Допълнителните файлове бяха отстранени.","%d files queued":"%d файла в опашката","File: %s, size: %d, max file size: %d":"Файл: %s, размер: %d, максимален размер: %d","Thumbnails":"","Drag files here.":"Довлечете файловете тук.","Runtime ran out of available memory.":"Недостатъчна свободна памет.","File count error.":"Грешка в броя на файловете.","File extension error.":"Грешка: разширение на файла.","mb":"mb","Add Files":"Добавете файлове"});
\ No newline at end of file
// Bosnian (bs)
plupload.addI18n({"Stop Upload":"Prekini dodavanje","Upload URL might be wrong or doesn't exist.":"URL za dodavanje je neispravan ili ne postoji.","tb":"tb","Size":"Veličina","Close":"Zatvori","You must specify either browse_button or drop_element.":"","Init error.":"Inicijalizacijska greška.","Add files to the upload queue and click the start button.":"Dodajte datoteke u red i kliknite na dugme za pokretanje.","List":"","Filename":"Naziv datoteke","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Format slike je neispravan ili nije podržan.","Status":"Status","HTTP Error.":"HTTP greška.","Start Upload":"Započni dodavanje","Error: File too large:":"Greška! Datoteka je prevelika:","kb":"kb","Duplicate file error.":"Dupla datoteka.","File size error.":"Greška u veličini datoteke.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Greška! Neispravan ekstenzija datoteke:","Select files":"Odaberite datoteke","%s already present in the queue.":"%s se već nalazi u redu.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Datoteka: %s","b":"b","Uploaded %d/%d files":"Dodano %d/%d datoteka","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Dodavanje trenutno dozvoljava samo %d datoteka istovremeno. Dodatne datoteke su uklonjene.","%d files queued":"%d datoteka čeka","File: %s, size: %d, max file size: %d":"Datoteka: %s, veličina: %d, maksimalna veličina: %d","Thumbnails":"","Drag files here.":"Dovucite datoteke ovdje.","Runtime ran out of available memory.":"Nema više dostupne memorije.","File count error.":"Greška u brojanju datoeka.","File extension error.":"Greška u ekstenziji datoteke.","mb":"mb","Add Files":"Dodaj datoteke"});
\ No newline at end of file
// Catalan (ca)
plupload.addI18n({"Stop Upload":"Parar pujada","Upload URL might be wrong or doesn't exist.":"La URL de càrrega no és correcte o bé no existeix.","tb":"Tb","Size":"Tamany","Close":"Tancar","You must specify either browse_button or drop_element.":"Has d'especificar o bé el botó de selecció de fitxers `browse_button` o bé l'àrea per arrosegar els fitxers `drop_element`.","Init error.":"Error d´inicialització.","Add files to the upload queue and click the start button.":"Afegeixi els fitxers a la cua de pujada i cliqui el botó Iniciar","List":"Llistat","Filename":"Nom de fitxer","%s specified, but cannot be found.":"%s especificat, però no es pot trobar.","Image format either wrong or not supported.":"Format d'imatge incorrecte o no suportat.","Status":"Estat","HTTP Error.":"Error HTTP.","Start Upload":"Començar pujada","Error: File too large:":"Error: Fitxer massa gran:","kb":"Kb","Duplicate file error.":"Error per duplicitat de fitxer.","File size error.":"Error en la mida del fitxer.","N/A":"N/D","gb":"Gb","Error: Invalid file extension:":"Error: Extensió de fitxer no vàlida:","Select files":"Seleccionar fitxers","%s already present in the queue.":"%s ja existeix a la cua.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Resolució de la imatge massa gran! El pujador <b>%s</b> suporta mides d'imatge fins a %wx%hpx.","File: %s":"Fitxer: %s","b":"b","Uploaded %d/%d files":"Pujats %d/%d fitxers","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"La càrrega d'elements tan sols accepta %d fitxer(s) alhora. Els fitxers sobrants seran descartats.","%d files queued":"%d fitxers en cua","File: %s, size: %d, max file size: %d":"Fitxer: %s, mida: %d, mida màxima de fitxer: %d","Thumbnails":"Miniatures","Drag files here.":"Arrossegui fitxers aquí","Runtime ran out of available memory.":"L'execució ha arribat al límit de memòria.","File count error.":"Error en el recompte de fitxers","File extension error.":"Error en l´extensió del fitxer.","mb":"Mb","Add Files":"Afegir fitxers"});
\ No newline at end of file
// Czech (cs)
plupload.addI18n({"Stop Upload":"Zastavit nahrávání","Upload URL might be wrong or doesn't exist.":"URL uploadu je možná špatně, nebo neexistuje.","tb":"tb","Size":"Velikost","Close":"Zavřít","You must specify either browse_button or drop_element.":"Musíte specifikovat browse_button či drop_element.","Init error.":"Chyba inicializace.","Add files to the upload queue and click the start button.":"Přidejte soubory do fronty a pak spusťte nahrávání.","List":"Seznam","Filename":"Název souboru","%s specified, but cannot be found.":"%s bylo specifikováno, ale nebylo nalezeno.","Image format either wrong or not supported.":"Špatný, nebo nepodporovaný formát obrázku.","Status":"Stav","HTTP Error.":"Chyba HTTP.","Start Upload":"Spustit nahrávání","Error: File too large:":"Chyba: Soubor je příliš veliký:","kb":"kb","Duplicate file error.":"Chyba - duplikovaný soubor.","File size error.":"Chyba velikosti souboru.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Chyba: Neplatná koncovka souboru:","Select files":"Vyberte soubory","%s already present in the queue.":"%s je již zařazen ve frontě.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Rozlišení je mimo rozmezí! <b>%s</b> runtime podporuje obrázky pouze do %wx%hpx.","File: %s":"Soubor: %s","b":"b","Uploaded %d/%d files":"Nahráno %d/%d souborů","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload akceptuje pouze %d soubor(ů) najednou. Další soubory byly odstraněny.","%d files queued":"%d souborů ve frontě","File: %s, size: %d, max file size: %d":"Soubor: %s, velikost: %d, maximální velikost souboru: %d","Thumbnails":"Náhledy","Drag files here.":"Sem přetáhněte soubory.","Runtime ran out of available memory.":"Běh skriptu přesáhl dostupnou paměť.","File count error.":"Chyba v počtu souborů.","File extension error.":"Chyba přípony souboru.","mb":"mb","Add Files":"Přidat soubory"});
\ No newline at end of file
// Welsh (cy)
plupload.addI18n({"Stop Upload":"Atal Lanlwytho","Upload URL might be wrong or doesn't exist.":"URL y lanlwythiad ynb anghywir neu ddim yn bodoli.","tb":"tb","Size":"Maint","Close":"Cau","You must specify either browse_button or drop_element.":"","Init error.":"Gwall cych.","Add files to the upload queue and click the start button.":"Ychwanegwch ffeiliau i'r ciw lanlwytho a chlicio'r botwm dechrau.","List":"","Filename":"Enw'r ffeil","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Fformat delwedd yn anghywir neu heb ei gynnal.","Status":"Statws","HTTP Error.":"Gwall HTTP.","Start Upload":"Dechrau Lanlwytho","Error: File too large:":"Gwall: Ffeil yn rhy fawr:","kb":"kb","Duplicate file error.":"Gwall ffeil ddyblyg.","File size error.":"Gwall maint ffeil.","N/A":"Dd/A","gb":"gb","Error: Invalid file extension:":"Gwall: estyniad ffeil annilys:","Select files":"Dewis ffeiliau","%s already present in the queue.":"%s yn y ciw yn barod.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Ffeil: %s","b":"b","Uploaded %d/%d files":"Lanlwythwyd %d/%d ffeil","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Mae'r elfen lanlwytho yn derbyn %d ffeil ar y tro. Caiff ffeiliau ychwanegol eu tynnu.","%d files queued":"%d ffeil mewn ciw","File: %s, size: %d, max file size: %d":"Ffeil: %s, maint: %d, maint mwyaf ffeil: %d","Thumbnails":"","Drag files here.":"Llusgwch ffeiliau yma.","Runtime ran out of available memory.":"Allan o gof.","File count error.":"Gwall cyfri ffeiliau.","File extension error.":"Gwall estyniad ffeil.","mb":"mb","Add Files":"Ychwanegu Ffeiliau"});
\ No newline at end of file
// Danish (da)
plupload.addI18n({"Stop Upload":"Stop upload","Upload URL might be wrong or doesn't exist.":"Upload URL kan være forkert eller ikke eksisterende.","tb":"tb","Size":"Størrelse","Close":"Luk","You must specify either browse_button or drop_element.":"","Init error.":"Opstarts fejl.","Add files to the upload queue and click the start button.":"Tilføj filer til køen og klik Start upload knappen.","List":"","Filename":"Filnavn","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Billede format er enten forkert eller ikke understøttet.","Status":"Status","HTTP Error.":"HTTP fejl.","Start Upload":"Start upload","Error: File too large:":"Fejl: Filen er for stor:","kb":"kb","Duplicate file error.":"Filen findes allerede.","File size error.":"Filstørrelse fejl.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Fejl: Ugyldigt fil format:","Select files":"Vælg filer","%s already present in the queue.":"%s findes allerede i køen.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Fil: %s","b":"b","Uploaded %d/%d files":"Uploaded %d/%d filer","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload accepterer kun %d fil(er) af gangen. Ekstra filer blev skippet.","%d files queued":"%d filer i kø","File: %s, size: %d, max file size: %d":"Fil: %s, størrelse: %d, maks. filstørrelse: %d","Thumbnails":"","Drag files here.":"Træk filer her.","Runtime ran out of available memory.":"Runtime mangler tilgængelige hukommelse.","File count error.":"Fil antal fejl.","File extension error.":"Fil format fejl.","mb":"mb","Add Files":"Tilføj filer"});
\ No newline at end of file
// German (de)
plupload.addI18n({"Stop Upload":"Hochladen abbrechen","Upload URL might be wrong or doesn't exist.":"Upload-URL ist falsch oder existiert nicht.","tb":"TB","Size":"Größe","Close":"Schließen","You must specify either browse_button or drop_element.":"","Init error.":"Initialisierungsfehler","Add files to the upload queue and click the start button.":"Dateien hinzufügen und auf 'Hochladen' klicken.","List":"Liste","Filename":"Dateiname","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Bildformat falsch oder nicht unterstützt.","Status":"Status","HTTP Error.":"HTTP-Fehler","Start Upload":"Hochladen beginnen","Error: File too large:":"Fehler: Datei zu groß:","kb":"KB","Duplicate file error.":"Datei bereits hochgeladen","File size error.":"Fehler bei Dateigröße","N/A":"Nicht verfügbar","gb":"GB","Error: Invalid file extension:":"Fehler: Ungültige Dateiendung:","Select files":"Dateien auswählen","%s already present in the queue.":"%s ist bereits in der Warteschlange","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Datei: %s","b":"B","Uploaded %d/%d files":"%d/%d Dateien wurden hochgeladen","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Pro Durchgang können nur %d Datei(en) akzeptiert werden. Überzählige Dateien wurden ignoriert.","%d files queued":"%d Dateien in der Warteschlange","File: %s, size: %d, max file size: %d":"Datei: %s, Größe: %d, maximale Dateigröße: %d","Thumbnails":"Vorschaubilder","Drag files here.":"Dateien auf diese Fläche bewegen.","Runtime ran out of available memory.":"Nicht genügend Speicher verfügbar.","File count error.":"Fehlerhafte Dateianzahl.","File extension error.":"Fehler bei Dateiendung","mb":"MB","Add Files":"Dateien hinzufügen"});
\ No newline at end of file
// Greek (el)
plupload.addI18n({"Stop Upload":"Ακύρωση Μεταφόρτωσης","Upload URL might be wrong or doesn't exist.":"Το URL μεταφόρτωσης είναι λάθος ή δεν υπάρχει.","tb":"tb","Size":"Μέγεθος","Close":"Κλείσιμο","You must specify either browse_button or drop_element.":"","Init error.":"Σφάλμα αρχικοποίησης.","Add files to the upload queue and click the start button.":"Προσθέστε αρχεία στην ουρά μεταφόρτωσης και πατήστε το κουμπί εκκίνησης.","List":"Λίστα","Filename":"Όνομα Αρχείου","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Ο τύπος εικόνας είναι λάθος ή δεν υποστηρίζεται.","Status":"Κατάσταση","HTTP Error.":"Σφάλμα HTTP.","Start Upload":"Εκκίνηση Μεταφόρτωσης","Error: File too large:":"Σφάλμα: Πολύ μεγάλο αρχείο:","kb":"kb","Duplicate file error.":"Το αρχείο έχει ξαναπροστεθεί.","File size error.":"Σφάλμα με το μέγεθος του αρχείου.","N/A":"Δεν ισχύει","gb":"gb","Error: Invalid file extension:":"Σφάλμα: Μη έγκυρος τύπος αρχείου:","Select files":"Επιλέξτε Αρχεία","%s already present in the queue.":"Το «%s» βρίσκεται ήδη στην ουρά.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Αρχείο: %s","b":"b","Uploaded %d/%d files":"Μεταφορτώθηκαν %d/%d αρχεία","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Μπορείτε να μεταφορτώσετε μεχρι και %d αρχείο/α κάθε φορά. Τα επιπλέον αρχεία αφαιρέθηκαν.","%d files queued":"%d αρχεία στην ουρά","File: %s, size: %d, max file size: %d":"Αρχείο: %s, μέγεθος: %d, μέγιστο μέγεθος αρχείου: %d","Thumbnails":"Μικρογραφίες","Drag files here.":"Σύρετε αρχεία εδώ","Runtime ran out of available memory.":"Δεν υπάρχει αρκετή διαθέσιμη μνήμη.","File count error.":"Σφάλμα με τον αριθμό αρχείων.","File extension error.":"Σφάλμα με τον τύπο αρχείου.","mb":"mb","Add Files":"Προσθέστε Αρχεία"});
\ No newline at end of file
// English (en)
plupload.addI18n({"Stop Upload":"Stop Upload","Upload URL might be wrong or doesn't exist.":"Upload URL might be wrong or doesn't exist.","tb":"tb","Size":"Size","Close":"Close","You must specify either browse_button or drop_element.":"You must specify either browse_button or drop_element.","Init error.":"Init error.","Add files to the upload queue and click the start button.":"Add files to the upload queue and click the start button.","List":"List","Filename":"Filename","%s specified, but cannot be found.":"%s specified, but cannot be found.","Image format either wrong or not supported.":"Image format either wrong or not supported.","Status":"Status","HTTP Error.":"HTTP Error.","Start Upload":"Start Upload","Error: File too large:":"Error: File too large:","kb":"kb","Duplicate file error.":"Duplicate file error.","File size error.":"File size error.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Error: Invalid file extension:","Select files":"Select files","%s already present in the queue.":"%s already present in the queue.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.","File: %s":"File: %s","b":"b","Uploaded %d/%d files":"Uploaded %d/%d files","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"%d files queued","File: %s, size: %d, max file size: %d":"File: %s, size: %d, max file size: %d","Thumbnails":"Thumbnails","Drag files here.":"Drag files here.","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"File count error.","File extension error.":"File extension error.","mb":"mb","Add Files":"Add Files"});
\ No newline at end of file
// Spanish (es)
plupload.addI18n({"Stop Upload":"Detener Subida.","Upload URL might be wrong or doesn't exist.":"URL de carga inexistente.","tb":"TB","Size":"Tamaño","Close":"Cerrar","You must specify either browse_button or drop_element.":"Debe especificar el browse_button o el drop_element","Init error.":"Error de inicialización.","Add files to the upload queue and click the start button.":"Agregue archivos a la lista de subida y pulse clic en el botón de Iniciar carga","List":"Lista","Filename":"Nombre de archivo","%s specified, but cannot be found.":"%s especificado, pero no se puede encontrar","Image format either wrong or not supported.":"Formato de imagen no soportada.","Status":"Estado","HTTP Error.":"Error de HTTP.","Start Upload":"Iniciar carga","Error: File too large:":"Error: archivo demasiado grande:","kb":"KB","Duplicate file error.":"Error, archivo duplicado","File size error.":"Error de tamaño de archivo.","N/A":"No disponible","gb":"GB","Error: Invalid file extension:":"Error: Extensión de archivo inválida:","Select files":"Elija archivos","%s already present in the queue.":"%s ya se encuentra en la lista.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Resolución fuera de límites! El tiempo de ejecución <b>%s</b> sólo admite imágenes hasta %wx%hpx","File: %s":"Archivo: %s","b":"B","Uploaded %d/%d files":"Subidos %d/%d archivos","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Se aceptan sólo %d archivo(s) al tiempo. Más, no se tienen en cuenta.","%d files queued":"%d archivos en cola.","File: %s, size: %d, max file size: %d":"Archivo: %s, tamaño: %d, tamaño máximo de archivo: %d","Thumbnails":"Miniaturas","Drag files here.":"Arrastre archivos aquí","Runtime ran out of available memory.":"No hay memoria disponible.","File count error.":"Error en contador de archivos.","File extension error.":"Error de extensión de archivo.","mb":"MB","Add Files":"Agregar archivos"});
\ No newline at end of file
// Estonian (et)
plupload.addI18n({"Stop Upload":"Stop Upload","Upload URL might be wrong or doesn't exist.":"Üleslaadimise URL võib olla vale või seda pole.","tb":"","Size":"Suurus","Close":"Sulge","You must specify either browse_button or drop_element.":"","Init error.":"Lähtestamise viga.","Add files to the upload queue and click the start button.":"Lisa failid üleslaadimise järjekorda ja klõpsa alustamise nupule.","List":"","Filename":"Failinimi","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Image format either wrong or not supported.","Status":"Olek","HTTP Error.":"HTTP ühenduse viga.","Start Upload":"Start Upload","Error: File too large:":"Error: File too large:","kb":"","Duplicate file error.":"","File size error.":"Failisuuruse viga.","N/A":"N/A","gb":"","Error: Invalid file extension:":"Error: Invalid file extension:","Select files":"Vali faile","%s already present in the queue.":"","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Fail: %s","b":"","Uploaded %d/%d files":"Üles laaditud %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Üleslaadimise element saab vastu võtta ainult %d faili ühe korraga. Ülejäänud failid jäetakse laadimata.","%d files queued":"Järjekorras on %d faili","File: %s, size: %d, max file size: %d":"","Thumbnails":"","Drag files here.":"Lohista failid siia.","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"Failide arvu viga.","File extension error.":"Faililaiendi viga.","mb":"","Add Files":"Add Files"});
\ No newline at end of file
// Persian (fa)
plupload.addI18n({"Stop Upload":"توقف انتقال","Upload URL might be wrong or doesn't exist.":"Upload URL might be wrong or doesn't exist.","tb":"ترابایت","Size":"سایز","Close":"بستن","You must specify either browse_button or drop_element.":"","Init error.":"خطا در استارت اسکریپت","Add files to the upload queue and click the start button.":"اضافه کنید فایل ها را به صف آپلود و دکمه شروع را کلیک کنید.","List":"","Filename":"نام فایل","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Image format either wrong or not supported.","Status":"وضعیت","HTTP Error.":"HTTP خطای","Start Upload":"شروع انتقال","Error: File too large:":"Error: File too large:","kb":"کیلوبایت","Duplicate file error.":"خطای فایل تکراری","File size error.":"خطای سایز فایل","N/A":"N/A","gb":"گیگابایت","Error: Invalid file extension:":"Error: Invalid file extension:","Select files":"انتخاب فایل","%s already present in the queue.":"%s در لیست آپلود وجود دارد.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":" فایل ها : %s","b":"بایت","Uploaded %d/%d files":"منتقل شد %d/%d از فایلها","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"عنصر بارگذار فقط %d فایل رو در یک زمان می پذیرد. سایر فایل ها مجرد از این موضوع هستند.","%d files queued":"%d فایل در صف","File: %s, size: %d, max file size: %d":"فایل: %s, اندازه: %d, محدودیت اندازه فایل: %d","Thumbnails":"","Drag files here.":"بکشید فایل ها رو به اینجا","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"خطای تعداد فایل","File extension error.":"خطا پیشوند فایل","mb":"مگابایت","Add Files":"افزودن فایل"});
\ No newline at end of file
// Finnish (fi)
plupload.addI18n({"Stop Upload":"Pysäytä lähetys","Upload URL might be wrong or doesn't exist.":"Lähetyksen URL-osoite saattaa olla väärä tai sitä ei ole olemassa.","tb":"TB","Size":"Koko","Close":"Sulje","You must specify either browse_button or drop_element.":"","Init error.":"Init virhe.","Add files to the upload queue and click the start button.":"Lisää tiedostoja lähetysjonoon ja klikkaa aloita-nappia.","List":"","Filename":"Tiedostonimi","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Kuvaformaatti on joko väärä tai ei tuettu.","Status":"Tila","HTTP Error.":"HTTP-virhe.","Start Upload":"Aloita lähetys","Error: File too large:":"Virhe: Liian suuri tiedosto:","kb":"kB","Duplicate file error.":"Tuplatiedostovirhe.","File size error.":"Tiedostokokovirhe.","N/A":"N/A","gb":"GB","Error: Invalid file extension:":"Virhe: Virheellinen tiedostopääte:","Select files":"Valitse tiedostoja","%s already present in the queue.":"%s on jo jonossa.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Tiedosto: %s","b":"B","Uploaded %d/%d files":"Lähetetty %d/%d tiedostoa","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Vain %d tiedosto(a) voidaan lähettää kerralla. Ylimääräiset tiedostot ohitettiin.","%d files queued":"%d tiedostoa jonossa","File: %s, size: %d, max file size: %d":"Tiedosto: %s, koko: %d, suurin sallittu tiedostokoko: %d","Thumbnails":"","Drag files here.":"Raahaa tiedostot tähän.","Runtime ran out of available memory.":"Toiminnon käytettävissä oleva muisti loppui kesken.","File count error.":"Tiedostolaskentavirhe.","File extension error.":"Tiedostopäätevirhe.","mb":"MB","Add Files":"Lisää tiedostoja"});
\ No newline at end of file
// French (fr)
plupload.addI18n({"Stop Upload":"Arrêter l'envoi.","Upload URL might be wrong or doesn't exist.":"L'URL d'envoi est soit erronée soit n'existe pas.","tb":"To","Size":"Taille","Close":"Fermer","You must specify either browse_button or drop_element.":"Vous devez spécifier browse_button ou drop_element.","Init error.":"Erreur d'initialisation.","Add files to the upload queue and click the start button.":"Ajoutez des fichiers à la file d'attente de téléchargement et appuyez sur le bouton 'Démarrer l'envoi'","List":"Liste","Filename":"Nom du fichier","%s specified, but cannot be found.":"%s spécifié, mais ne peut pas être trouvé.","Image format either wrong or not supported.":"Le format d'image est soit erroné soit pas géré.","Status":"État","HTTP Error.":"Erreur HTTP.","Start Upload":"Démarrer l'envoi","Error: File too large:":"Erreur: Fichier trop volumineux:","kb":"Ko","Duplicate file error.":"Erreur: Fichier déjà sélectionné.","File size error.":"Erreur de taille de fichier.","N/A":"Non applicable","gb":"Go","Error: Invalid file extension:":"Erreur: Extension de fichier non valide:","Select files":"Sélectionnez les fichiers","%s already present in the queue.":"%s déjà présent dans la file d'attente.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Résolution sur les frontières ! L'exécution de <b>%s</b> supporte seulement les images de %wx%hpx","File: %s":"Fichier: %s","b":"o","Uploaded %d/%d files":"%d fichiers sur %d ont été envoyés","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Que %d fichier(s) peuvent être envoyé(s) à la fois. Les fichiers supplémentaires ont été ignorés.","%d files queued":"%d fichiers en attente","File: %s, size: %d, max file size: %d":"Fichier: %s, taille: %d, taille max. d'un fichier: %d","Thumbnails":"Miniatures","Drag files here.":"Déposez les fichiers ici.","Runtime ran out of available memory.":"Le traitement a manqué de mémoire disponible.","File count error.":"Erreur: Nombre de fichiers.","File extension error.":"Erreur d'extension de fichier","mb":"Mo","Add Files":"Ajouter des fichiers"});
\ No newline at end of file
// Hebrew (he)
plupload.addI18n({"Stop Upload":"בטל העלאה","Upload URL might be wrong or doesn't exist.":"כתובת URL שגויה או לא קיימת.","tb":"tb","Size":"גודל","Close":"סגור","You must specify either browse_button or drop_element.":"יש לציין או browse_button או drop_element.","Init error.":"שגיאת איתחול","Add files to the upload queue and click the start button.":"הוסף קבצים לרשימה ולחץ על כפתור שליחה להתחלת פעולות העלאה","List":"רשימה","Filename":"שם קובץ","%s specified, but cannot be found.":"%s צויין, אך לא נמצא.","Image format either wrong or not supported.":"תמונה פגומה או סוג תמונה לא נתמך","Status":"אחוז","HTTP Error.":"שגיאת פרוטוקול","Start Upload":"שליחה","Error: File too large:":"שגיאה: קובץ חורג מהגודל המותר:","kb":"KB","Duplicate file error.":"קובץ כפול","File size error.":"גודל קובץ חורג מהמותר","N/A":"שגיאה","gb":"GB","Error: Invalid file extension:":"שגיאה: סוג קובץ לא נתמך:","Select files":"בחר קבצים","%s already present in the queue.":"%sקובץ נמצא כבר ברשימת הקבצים.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"הרזולוציה גבוהה מדי! <b>%s</b> הפלטפורמה תומכת בתמונות עד גודל px.","File: %s":"קובץ: %s","b":"B","Uploaded %d/%d files":"מעלה: %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"אלמנטי ההעלאה מקבלים רק %d קובץ(ים) בפעם אחת. קבצים נוספים הוסרו.","%d files queued":"%d קבצים נותרו","File: %s, size: %d, max file size: %d":"קובץ: %s, גודל: %d, גודל מקסימלי: %d","Thumbnails":"תמונות ממוזערות","Drag files here.":"גרור קבצים לכאן","Runtime ran out of available memory.":"שגיאת מחסור בזיכרון","File count error.":"שגיאת מספר קבצים","File extension error.":"קובץ זה לא נתמך","mb":"MB","Add Files":"הוסף קבצים"});
\ No newline at end of file
// Croatian (hr)
plupload.addI18n({"Stop Upload":"Zaustavi upload.","Upload URL might be wrong or doesn't exist.":"Upload URL might be wrong or doesn't exist.","tb":"tb","Size":"Veličina","Close":"Zatvori","You must specify either browse_button or drop_element.":"","Init error.":"Greška inicijalizacije.","Add files to the upload queue and click the start button.":"Dodajte datoteke u listu i kliknite Upload.","List":"","Filename":"Ime datoteke","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Image format either wrong or not supported.","Status":"Status","HTTP Error.":"HTTP greška.","Start Upload":"Pokreni upload.","Error: File too large:":"Pogreška: Datoteka je prevelika:","kb":"kb","Duplicate file error.":"Pogreška dvostruke datoteke.","File size error.":"Greška veličine datoteke.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Pogreška: Nevažeći nastavak datoteke:","Select files":"Odaberite datoteke:","%s already present in the queue.":"%s je već prisutan u listi čekanja.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Datoteka: %s","b":"b","Uploaded %d/%d files":"Uploadano %d/%d datoteka","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"%d datoteka na čekanju.","File: %s, size: %d, max file size: %d":"Datoteka: %s, veličina: %d, maksimalna veličina: %d","Thumbnails":"","Drag files here.":"Dovucite datoteke ovdje","Runtime ran out of available memory.":"Runtime aplikaciji je ponestalo memorije.","File count error.":"Pogreška u broju datoteka.","File extension error.":"Pogreška u nastavku datoteke.","mb":"mb","Add Files":"Dodaj datoteke"});
\ No newline at end of file
// Hungarian (hu)
plupload.addI18n({"Stop Upload":"Feltöltés leállítása","Upload URL might be wrong or doesn't exist.":"A feltöltő URL hibás vagy nem létezik.","tb":"TB","Size":"Méret","Close":"Bezárás","You must specify either browse_button or drop_element.":"","Init error.":"Init hiba.","Add files to the upload queue and click the start button.":"A fájlok feltöltési sorhoz való hozzáadása után az Indítás gombra kell kattintani.","List":"","Filename":"Fájlnév","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Rossz vagy nem támogatott képformátum.","Status":"Állapot","HTTP Error.":"HTTP-hiba.","Start Upload":"Feltöltés indítása","Error: File too large:":"Hiba: a fájl túl nagy:","kb":"kB","Duplicate file error.":"Duplikáltfájl-hiba.","File size error.":"Hibás fájlméret.","N/A":"Nem elérhető","gb":"GB","Error: Invalid file extension:":"Hiba: érvénytelen fájlkiterjesztés:","Select files":"Fájlok kiválasztása","%s already present in the queue.":"%s már szerepel a listában.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Fájl: %s","b":"b","Uploaded %d/%d files":"Feltöltött fájlok: %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"A feltöltés egyszerre csak %d fájlt fogad el, a többi fájl nem lesz feltöltve.","%d files queued":"%d fájl sorbaállítva","File: %s, size: %d, max file size: %d":"Fájl: %s, méret: %d, legnagyobb fájlméret: %d","Thumbnails":"","Drag files here.":"Ide lehet húzni a fájlokat.","Runtime ran out of available memory.":"Futásidőben elfogyott a rendelkezésre álló memória.","File count error.":"A fájlok számával kapcsolatos hiba.","File extension error.":"Hibás fájlkiterjesztés.","mb":"MB","Add Files":"Fájlok hozzáadása"});
\ No newline at end of file
// Armenian (hy)
plupload.addI18n({"Stop Upload":"Կանգնեցնել","Upload URL might be wrong or doesn't exist.":"Ավեցաված URL-ը սխալ է կամ գոյություն չունի։","tb":"տբ","Size":"Չափ","Close":"Փակել","You must specify either browse_button or drop_element.":"","Init error.":"Ստեղծման սխալ","Add files to the upload queue and click the start button.":"Ավելացրեք ֆայլեր ցուցակում և սեղմեք \"Վերբեռնել\"։","List":"","Filename":"Ֆայլի անուն","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Նկարի ֆորմատը սխալ է կամ չի ընդունվում։","Status":"Կարգավիճակ","HTTP Error.":"HTTP սխալ","Start Upload":"Վերբեռնել","Error: File too large:":"Սխալ։ Ֆայլի չափը մեծ է։","kb":"կբ","Duplicate file error.":"Ֆայլի կրկնման սխալ","File size error.":"Ֆայլի չափի սխալ","N/A":"N/A","gb":"գբ","Error: Invalid file extension:":"Սխալ։ Ֆայլի ընդլայնումը սխալ է։","Select files":"Ընտրեք ֆայլերը","%s already present in the queue.":"%s ֆայլը արդեն ավելացված է ցուցակում.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Ֆայլ: %s","b":"բ","Uploaded %d/%d files":"Վերբեռնվել են %d/%d ֆայլերը","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Վերբեռնիչը միանգամից ըդունում է միայն %d ֆայլ(եր). Ավելորդ ֆայլերը հեռացվել են.","%d files queued":"ցուցակում կա %d ֆայլ","File: %s, size: %d, max file size: %d":"Ֆայլ: %s, չափ: %d, ֆայլի մաքսիմում չափ: %d","Thumbnails":"","Drag files here.":"Տեղափոխեք ֆայլերը այստեղ","Runtime ran out of available memory.":"Օպերատիվ հիշողության անբավարարուտյուն.","File count error.":"Ֆայլերի քանակի սխալ","File extension error.":"Ֆայլի ընդլայնման սխալ","mb":"մբ","Add Files":"Ավելացնել ֆայլեր"});
\ No newline at end of file
// Indonesian (id)
plupload.addI18n({"Stop Upload":"Hentikan Upload","Upload URL might be wrong or doesn't exist.":"Alamat URL untuk upload tidak benar atau tidak ada","tb":"tb","Size":"Ukuran","Close":"Tutup","You must specify either browse_button or drop_element.":"","Init error.":"Kesalahan pada Init","Add files to the upload queue and click the start button.":"Tambahkan file kedalam antrian upload dan klik tombol Mulai","List":"","Filename":"Nama File","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Kesalahan pada jenis gambar atau jenis file tidak didukung","Status":"Status","HTTP Error.":"HTTP Bermasalah","Start Upload":"Mulai Upload","Error: File too large:":"Kesalahan: File terlalu besar","kb":"kb","Duplicate file error.":"Terjadi duplikasi file","File size error.":"Kesalahan pada ukuran file","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Kesalahan: Ekstensi file tidak dikenal","Select files":"Pilih file","%s already present in the queue.":"%s sudah ada dalam daftar antrian","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"File: %s","b":"b","Uploaded %d/%d files":"File terupload %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Tempat untuk upload hanya menerima %d file(s) dalam setiap upload. File lainnya tidak akan disertakan","%d files queued":"%d file dalam antrian","File: %s, size: %d, max file size: %d":"File: %s, ukuran: %d, maksimum ukuran file: %d","Thumbnails":"","Drag files here.":"Tarik file kesini","Runtime ran out of available memory.":"Tidak cukup memori","File count error.":"Kesalahan pada jumlah file","File extension error.":"Kesalahan pada ekstensi file","mb":"mb","Add Files":"Tambah File"});
\ No newline at end of file
// Italian (it)
plupload.addI18n({"Stop Upload":"Ferma Upload","Upload URL might be wrong or doesn't exist.":"URL di Upload errata o non esistente","tb":"tb","Size":"Dimensione","Close":"Chiudi","You must specify either browse_button or drop_element.":"Devi indicare almeno uno tra browse_button o drop_element.","Init error.":"Errore inizializzazione.","Add files to the upload queue and click the start button.":"Aggiungi i file alla coda di caricamento e clicca il pulsante di avvio.","List":"Lista","Filename":"Nome file","%s specified, but cannot be found.":"%s specificato, ma non è stato possibile trovarlo.","Image format either wrong or not supported.":"Formato immagine errato o non supportato.","Status":"Stato","HTTP Error.":"Errore HTTP.","Start Upload":"Inizia Upload","Error: File too large:":"Errore: File troppo grande:","kb":"kb","Duplicate file error.":"Errore file duplicato.","File size error.":"Errore dimensione file.","N/A":"N/D","gb":"gb","Error: Invalid file extension:":"Errore: Estensione file non valida:","Select files":"Seleziona i files","%s already present in the queue.":"%s già presente nella coda.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Risoluzione oltre i limiti! <b>%s</b> runtime supporta immagini fino a %wx%hpx.","File: %s":"File: %s","b":"byte","Uploaded %d/%d files":"Caricati %d/%d file","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"%d file in coda","File: %s, size: %d, max file size: %d":"File: %s, dimensione: %d, dimensione max file: %d","Thumbnails":"Anteprime","Drag files here.":"Trascina i files qui.","Runtime ran out of available memory.":"Runtime ha esaurito la memoria disponibile.","File count error.":"File count error.","File extension error.":"Errore estensione file.","mb":"mb","Add Files":"Aggiungi file"});
\ No newline at end of file
// Japanese (ja)
plupload.addI18n({"Stop Upload":"アップロード停止","Upload URL might be wrong or doesn't exist.":"アップロード先の URL が存在しません","tb":"TB","Size":"サイズ","Close":"閉じる","You must specify either browse_button or drop_element.":"ブラウザのボタンで または ファイルをドロップするか いずれかの方法で指定する必要があります。","Init error.":"イニシャライズエラー","Add files to the upload queue and click the start button.":"ファイルをアップロードキューに追加してスタートボタンをクリックしてください","List":"リスト","Filename":"ファイル名","%s specified, but cannot be found.":"指定された %s は見つかりません。","Image format either wrong or not supported.":"画像形式が間違っているかサポートされていません","Status":"ステータス","HTTP Error.":"HTTP エラー","Start Upload":"アップロード開始","Error: File too large:":"エラー: ファイルが大きすぎます:","kb":"KB","Duplicate file error.":"重複ファイルエラー","File size error.":"ファイルサイズエラー","N/A":"N/A","gb":"GB","Error: Invalid file extension:":"エラー: ファイルの拡張子が無効です:","Select files":"ファイル選択","%s already present in the queue.":"%s 既にキューに存在しています","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"解像度がしきい値を超えています! ランタイム <b>%s</b> は縦 %h px 横 %w px までをサポートします","File: %s":"ファイル: %s","b":"B","Uploaded %d/%d files":"アップロード中 %d/%d ファイル","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"アップロード可能なファイル数は %d です 余分なファイルは削除されました","%d files queued":"%d ファイルが追加されました","File: %s, size: %d, max file size: %d":"ファイル: %s, サイズ: %d, 最大ファイルサイズ: %d","Thumbnails":"サムネイル","Drag files here.":"ここにファイルをドラッグ","Runtime ran out of available memory.":"ランタイムが使用するメモリが不足しました","File count error.":"ファイル数エラー","File extension error.":"ファイル拡張子エラー","mb":"MB","Add Files":"ファイルを追加"});
\ No newline at end of file
// Georgian (ka)
plupload.addI18n({"Stop Upload":"ატვირთვის შეჩერება","Upload URL might be wrong or doesn't exist.":"ატვირთვის მისამართი არასწორია ან არ არსებობს.","tb":"ტბ","Size":"ზომა","Close":"დავხუროთ","You must specify either browse_button or drop_element.":"თქვენ უნდა მიუთითოთ browse_button ან drop_element.","Init error.":"ინიციალიზაციის შეცდომა.","Add files to the upload queue and click the start button.":"დაამატეთ ფაილები და დააჭირეთ ღილაკს - ატვირთვა.","List":"","Filename":"ფაილის სახელი","%s specified, but cannot be found.":"%s მითითებულია, მაგრამ ვერ მოიძებნა.","Image format either wrong or not supported.":"ფაილის ფორმატი არ არის მხარდაჭერილი ან არასწორია.","Status":"სტატუსი","HTTP Error.":"HTTP შეცდომა.","Start Upload":"ატვირთვა","Error: File too large:":"შეცდომა: ფაილი ზედმეტად დიდია.","kb":"კბ","Duplicate file error.":"ესეთი ფაილი უკვე დამატებულია.","File size error.":"ფაილის ზომა დაშვებულზე დიდია.","N/A":"N/A","gb":"გბ","Error: Invalid file extension:":"შეცდომა: ფაილს აქვს არასწორი გაფართოება.","Select files":"ფაილების მონიშვნა","%s already present in the queue.":"%s უკვე დამატებულია.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"სურათის გარჩევადობა აღემატება <b>%s</b> გარემოს მიერ მხარდაჭერილ მქსიმუმებს - %wx%hpx.","File: %s":"ფაილი: %s","b":"ბ","Uploaded %d/%d files":"ატვირთულია %d/%d ფაილი","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"ერთდროულად დაშვებულია მხოლოდ %d ფაილის დამატება.","%d files queued":"რიგშია %d ფაილი","File: %s, size: %d, max file size: %d":"ფაილი: %s, ზომა: %d, მაქსიმალური დაშვებული ზომა: %d","Thumbnails":"","Drag files here.":"ჩააგდეთ ფაილები აქ.","Runtime ran out of available memory.":"ხელმისაწვდომი მეხსიერება გადაივსო.","File count error.":"აღმოჩენილია ზედმეტი ფაილები.","File extension error.":"ფაილის ფორმატი დაშვებული არ არის.","mb":"მბ","Add Files":"დაამატეთ ფაილები"});
\ No newline at end of file
// Kazakh (kk)
plupload.addI18n({"Stop Upload":"Жүктеуді тоқтату","Upload URL might be wrong or doesn't exist.":"Жүктеуді қабылдаушы URL қате не мүлдем көрсетілмеген.","tb":"тб","Size":"Өлшемі","Close":"Жабу","You must specify either browse_button or drop_element.":"","Init error.":"Инициализация қатесі.","Add files to the upload queue and click the start button.":"Жүктеу кезегіне файлдар қосып, Бастау кнопкасын басыңыз.","List":"","Filename":"Файл аты","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Сурет форматы қате немесе оның қолдауы жоқ.","Status":"Күйі","HTTP Error.":"HTTP қатесі.","Start Upload":"Жүктеуді бастау","Error: File too large:":"Қате: Файл мөлшері тым үлкен:","kb":"кб","Duplicate file error.":"Файл қайталамасының қатесі.","File size error.":"Файл өлшемінің қатесі.","N/A":"Қ/Ж","gb":"гб","Error: Invalid file extension:":"Қате: Файл кеңейтілуі қате:","Select files":"Файлдар таңдаңыз","%s already present in the queue.":"%s файлы кезекте бұрыннан бар.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Файл: %s","b":"б","Uploaded %d/%d files":"Жүктелген: %d/%d файл","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Жүктеу элементі бір кезде %d файл ғана жүктей алады. Артық файлдар жүктелмейді.","%d files queued":"%d файл кезекке қойылды","File: %s, size: %d, max file size: %d":"Файл: %s, өлшемі: %d, макс. файл өлшемі: %d","Thumbnails":"","Drag files here.":"Файлдарды мына жерге тастаңыз.","Runtime ran out of available memory.":"Орындау кезінде жады жетпей қалды.","File count error.":"Файл санының қатесі.","File extension error.":"Файл кеңейтілуінің қатесі.","mb":"мб","Add Files":"Файл қосу"});
\ No newline at end of file
// Khmer (km)
plupload.addI18n({"Stop Upload":"បញ្ឈប់​ការ​ផ្ទុក​ឡើង","Upload URL might be wrong or doesn't exist.":"URL ផ្ទុក​ឡើង​អាច​ខុស ឬ​ក៏​គ្មាន។","tb":"tb","Size":"ទំហំ","Close":"បិទ","You must specify either browse_button or drop_element.":"","Init error.":"កំហុស Init។","Add files to the upload queue and click the start button.":"បន្ថែម​ឯកសារ​ទៅ​ក្នុង​ជួរ​លំដាប់​ផ្ទុក​ឡើង ហើយ​ចុច​ប៊ូតុង​ចាប់​ផ្ដើម។","List":"","Filename":"ឈ្មោះ​ឯកសារ","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"ទ្រង់​ទ្រាយ​រូបភាព​អាច​ខុស ឬ​ក៏​មិន​ស្គាល់​តែ​ម្ដង។","Status":"ស្ថានភាព","HTTP Error.":"កំហុស HTTP ។","Start Upload":"ចាប់​ផ្ដើម​ផ្ទុក​ឡើង","Error: File too large:":"កំហុស៖ ឯកសារ​ធំ​ពេក៖","kb":"kb","Duplicate file error.":"កំហុស​ឯកសារ​ស្ទួន​គ្នា។","File size error.":"កំហុស​ទំហំ​ឯកសារ។","N/A":"គ្មាន","gb":"gb","Error: Invalid file extension:":"កំហុស៖ កន្ទុយ​ឯកសារ​មិន​ត្រឹម​ត្រូវ៖","Select files":"ជ្រើស​ឯកសារ","%s already present in the queue.":"មាន %s នៅ​ក្នុង​ជួរ​លំដាប់​ហើយ។","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"ឯកសារ៖ %s","b":"b","Uploaded %d/%d files":"បាន​ផ្ទុក​ឡើង​ឯកសារ %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"ការ​ផ្ទុក​ឡើង​ទទួល​ឯកសារ​បាន​តែ %d ប៉ុណ្ណោះ​ក្នុង​ពេល​តែ​មួយ។ ឯកសារ​ផ្សេង​ទៀត​នឹង​ត្រូវ​ដក​ចេញ។","%d files queued":"បាន​ដាក់​ឯកសារ %d បន្ត​គ្នា","File: %s, size: %d, max file size: %d":"ឯកសារ៖ %s, size: %d, ទំហំ​ឯកសារ​អតិបរមា៖ %d","Thumbnails":"","Drag files here.":"អូស​ឯកសារ​មក​ទីនេះ។","Runtime ran out of available memory.":"ពេល​ដំណើរ​ការ​អស់​អង្គ​ចងចាំ​ទំនេរ​ហើយ។","File count error.":"កំហុស​ការ​រាប់​ឯកសារ។","File extension error.":"កំហុស​កន្ទុយ​ឯកសារ។","mb":"mb","Add Files":"បន្ថែម​ឯកសារ"});
\ No newline at end of file
// Korean (ko)
plupload.addI18n({"Stop Upload":"업로드 중지","Upload URL might be wrong or doesn't exist.":"업로드할 URL이 존재하지 않습니다.","tb":"tb","Size":"크기","Close":"닫기","You must specify either browse_button or drop_element.":"browse_button 이나 drop_element 둘 중 하나를 지정해 주세요.","Init error.":"초기화 오류.","Add files to the upload queue and click the start button.":"파일을 업로드 큐에 추가한 후 시작 버튼을 클릭하십시오.","List":"목록","Filename":"파일명","%s specified, but cannot be found.":"%s 가 지정됐지만, 찾을 수 없습니다.","Image format either wrong or not supported.":"지원되지 않는 이미지 형식입니다.","Status":"상태","HTTP Error.":"HTTP 오류.","Start Upload":"업로드 시작","Error: File too large:":"오류: 파일 크기가 너무 큽니다.","kb":"kb","Duplicate file error.":"파일 중복 오류.","File size error.":"파일 크기 오류.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"오류: 허용되지 않은 확장자입니다.","Select files":"파일 선택","%s already present in the queue.":"%s 파일이 이미 대기열에 존재합니다.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"해상도 지원 범위를 초과했습니다! <b>%s</b> 런타임은 %wx%hpx 이상의 이미지를 지원합니다.","File: %s":"파일: %s","b":"b","Uploaded %d/%d files":"%d / %d 파일 업로드 완료","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"업로드 가능한 파일의 수는 %d 입니다. 불필요한 파일은 삭제되었습니다.","%d files queued":"%d 파일이 추가됨","File: %s, size: %d, max file size: %d":"파일: %s, 크기: %d, 최대 파일 크기: %d","Thumbnails":"미리보기","Drag files here.":"이곳에 파일을 드래그 하세요.","Runtime ran out of available memory.":"런타임 메모리가 부족합니다.","File count error.":"파일 갯수 오류.","File extension error.":"파일 확장자 오류.","mb":"mb","Add Files":"파일 추가"});
\ No newline at end of file
// Kurdish (Iraq) (ku_IQ)
plupload.addI18n({"Stop Upload":"وەستانی بارکردن","Upload URL might be wrong or doesn't exist.":".بەستەری بارکراو نادروستە یان بەردەست نییە","tb":"تێرابایت","Size":"قەبارە","Close":"داخستن","You must specify either browse_button or drop_element.":"","Init error.":".هەڵەی ئامادەکردن","Add files to the upload queue and click the start button.":".زیادکردنی پەڕگەکان بۆ ڕیزی بارکردن و کرتەکردن لە دوگمەی دەستپێکردن","List":"","Filename":"ناوی پەڕگە","%s specified, but cannot be found.":"","Image format either wrong or not supported.":".شێوازی وێنە هەڵەیە یان پاڵپشتی ناکرێت","Status":"ڕەوش","HTTP Error.":".HTTP هەڵەی","Start Upload":"دەستپێکردنی بارکردن","Error: File too large:":":هەڵە: پەڕگەکە زۆر گەورەیە","kb":"کیلۆبایت","Duplicate file error.":".هەڵەی پەڕگەی دوبارە","File size error.":".هەڵەی قەبارەی پەڕگە","N/A":"بەردەست نییە","gb":"گێگابایت","Error: Invalid file extension:":":هەڵە: پاشگری پەڕگەی نادروست","Select files":"دیاریکردنی پەڕگەکان","%s already present in the queue.":".ئامادەیی هەیە لە ڕیز %s","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"%s :پەڕگە","b":"بایت","Uploaded %d/%d files":"پەڕگە بارکران %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"بەشی بارکردن تەنها %d پەڕگە(کان) وەردەگرێت لەیەک کاتدا. پەڕگە زیادەکان .جیادەکرێنەوە","%d files queued":"پەڕگە ڕیزکران %d","File: %s, size: %d, max file size: %d":"پەڕگە: %s، قەبارە: %d، گەورەترین قەبارەی پەڕگە: %d","Thumbnails":"","Drag files here.":".پەڕگەکان ڕاکێشە بۆ ئێرە","Runtime ran out of available memory.":"هەڵەی دەرچوون لە بیرگەی بەردەست.","File count error.":".هەڵەی ژماردنی پەڕگە","File extension error.":".هەڵەی پاشگری پەڕگە","mb":"مێگابایت","Add Files":"زیادکردنی پەڕگەکان"});
\ No newline at end of file
// Lithuanian (lt)
plupload.addI18n({"Stop Upload":"Stabdyti įkėlimą","Upload URL might be wrong or doesn't exist.":"Klaidinga arba neegzistuojanti įkėlimo nuoroda.","tb":"tb","Size":"Dydis","Close":"Uždaryti","You must specify either browse_button or drop_element.":"","Init error.":"Įkrovimo klaida.","Add files to the upload queue and click the start button.":"Pridėkite bylas į įkėlimo eilę ir paspauskite starto mygtuką.","List":"","Filename":"Bylos pavadinimas","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Paveiksliuko formatas klaidingas arba nebepalaikomas.","Status":"Statusas","HTTP Error.":"HTTP klaida.","Start Upload":"Pradėti įkėlimą","Error: File too large:":"Klaida: Byla per didelė:","kb":"kb","Duplicate file error.":"Pasikartojanti byla.","File size error.":"Netinkamas bylos dydis.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Klaida: Netinkamas bylos plėtinys:","Select files":"Žymėti bylas","%s already present in the queue.":"%s jau yra eilėje.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Byla: %s","b":"b","Uploaded %d/%d files":"Įkelta bylų: %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Vienu metu galima įkelti tik %d bylas(ų). Papildomos bylos buvo pašalintos.","%d files queued":"%d bylų eilėje","File: %s, size: %d, max file size: %d":"Byla: %s, dydis: %d, galimas dydis: %d","Thumbnails":"","Drag files here.":"Padėti bylas čia.","Runtime ran out of available memory.":"Išeikvota darbinė atmintis.","File count error.":"Netinkamas bylų kiekis.","File extension error.":"Netinkamas pletinys.","mb":"mb","Add Files":"Pridėti bylas"});
\ No newline at end of file
// Latvian (lv)
plupload.addI18n({"Stop Upload":"Apturēt augšupielādi","Upload URL might be wrong or doesn't exist.":"Augšupielādes saite neeksistē vai ir nepareiza.","tb":"terabaiti","Size":"Izmērs","Close":"Aizvērt","You must specify either browse_button or drop_element.":"Jums ir jānorāda vainu browse_button vai drop_element.","Init error.":"Inicializācijas kļūda.","Add files to the upload queue and click the start button.":"Pievienojiet failus rindai un klikšķiniet uz pogas \"Sākt augšupielādi\".","List":"Saraksts","Filename":"Faila nosaukums","%s specified, but cannot be found.":"%s norādīts, bet nevar tikt atrasts.","Image format either wrong or not supported.":"Attēla formāts ir nepareizs vai arī netiek atbalstīts.","Status":"Statuss","HTTP Error.":"HTTP kļūda.","Start Upload":"Sākt augšupielādi","Error: File too large:":"Kļūda: Fails pārāk liels:","kb":"kilobaiti","Duplicate file error.":"Atkārtota faila kļūda","File size error.":"Faila izmēra kļūda.","N/A":"N/A","gb":"gigabaiti","Error: Invalid file extension:":"Kļūda: Nepareizs faila paplašinājums:","Select files":"Izvēlieties failus","%s already present in the queue.":"%s jau ir atrodams rindā.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Izšķirtspēja ārpus robežām! <b>%s</b> atbalsta attēlus tikai līdz %wx%hpx","File: %s":"Fails: %s","b":"baiti","Uploaded %d/%d files":"Augšupielādēti %d/%d faili","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Iespējams ielādēt tikai %d failus vienā reizē. Atlikušie faili netika pievienoti","%d files queued":"%d faili pievienoti rindai","File: %s, size: %d, max file size: %d":"Fails: %s, izmērs: %d, max faila izmērs: %d","Thumbnails":"Ikonas","Drag files here.":"Ievelciet failus šeit","Runtime ran out of available memory.":"Pietrūkst izmantojamās atmiņas.","File count error.":"Failu skaita kļūda","File extension error.":"Faila paplašinājuma kļūda.","mb":"megabaiti","Add Files":"Pievienot failus"});
\ No newline at end of file
// Malay (ms)
plupload.addI18n({"Stop Upload":"Berhenti Muat naik","Upload URL might be wrong or doesn't exist.":"URL muat naik mungkin salah atau tidak wujud.","tb":"tb","Size":"saiz","Close":"Tutup","You must specify either browse_button or drop_element.":"","Init error.":"Ralat perlaksanaan.","Add files to the upload queue and click the start button.":"Tambah fail ke dalam giliran muat naik dan klik butang Muat Naik.","List":"","Filename":"Nama fail","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Format imej sama ada salah atau tidak disokong.","Status":"Status","HTTP Error.":"Ralat HTTP.","Start Upload":"Muat Naik","Error: File too large:":"Ralat: Fail terlalu bersar:","kb":"kb","Duplicate file error.":"Ralat menggandakan fail.","File size error.":"Ralat saiz fail.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Ralat: Sambungan fail tidak sah:","Select files":"Pilih fail","%s already present in the queue.":"%s telah ada dalam barisan.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Fail: %s","b":"b","Uploaded %d/%d files":"%d/%d telah dimuat naik","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Element muat naik hanya menerima %d fail(-fail) pada satu masa. Fail tambahan telah digugurkan.","%d files queued":"%d fail dalam barisan","File: %s, size: %d, max file size: %d":"Fail: %s, saiz: %d, saiz maks fail: %d","Thumbnails":"","Drag files here.":"Seret fail ke sini.","Runtime ran out of available memory.":"Ruang ingatan masa larian tidak mencukupi.","File count error.":"Ralat bilangan fail.","File extension error.":"Ralat sambungan fail.","mb":"mb","Add Files":"Tambah Fail"});
\ No newline at end of file
// Dutch (nl)
plupload.addI18n({"Stop Upload":"Stop Upload","Upload URL might be wrong or doesn't exist.":"Upload URL is verkeerd of bestaat niet.","tb":"tb","Size":"Grootte","Close":"Sluiten","You must specify either browse_button or drop_element.":"","Init error.":"Initialisatie error.","Add files to the upload queue and click the start button.":"Voeg bestanden toe aan de wachtrij en druk op 'Start'.","List":"","Filename":"Bestandsnaam","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"bestandsextensie is verkeerd of niet ondersteund.","Status":"Status","HTTP Error.":"HTTP Error.","Start Upload":"Start Upload","Error: File too large:":"Error: Bestand te groot:","kb":"kb","Duplicate file error.":"Bestand bestaat al.","File size error.":"Bestandsgrootte error.","N/A":"Niet beschikbaar","gb":"gb","Error: Invalid file extension:":"Error: Ongeldige bestandsextensie:","Select files":"Selecteer bestand(en):","%s already present in the queue.":"%s is al aan de wachtrij toegevoegd.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Bestand: %s","b":"b","Uploaded %d/%d files":"%d/%d bestanden ge-upload","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload accepteert alleen %d bestand(en) tegelijk. Extra bestanden zijn verwijderd.","%d files queued":"%d bestand(en) in de wachtrij","File: %s, size: %d, max file size: %d":"Bestand: %s, grootte: %d, maximale bestandsgrootte: %d","Thumbnails":"","Drag files here.":"Sleep bestanden hierheen.","Runtime ran out of available memory.":"Het maximum bruikbare geheugen is overschreden.","File count error.":"Teveel bestand(en) error.","File extension error.":"Ongeldig bestandsextensie.","mb":"mb","Add Files":"Bestand(en) toevoegen"});
\ No newline at end of file
// Polish (pl)
plupload.addI18n({"Stop Upload":"Przerwij transfer.","Upload URL might be wrong or doesn't exist.":"Adres URL może być nieprawidłowy lub może nie istnieć","tb":"tb","Size":"Rozmiar","Close":"Zamknij","You must specify either browse_button or drop_element.":"Musisz określić browse_button albo drop_element.","Init error.":"Błąd inicjalizacji.","Add files to the upload queue and click the start button.":"Dodaj pliki i kliknij 'Rozpocznij transfer'.","List":"Lista","Filename":"Nazwa pliku","%s specified, but cannot be found.":"%s określony ale nie można znaleźć.","Image format either wrong or not supported.":"Format zdjęcia jest zły lub nieobsługiwany","Status":"Status","HTTP Error.":"Błąd HTTP.","Start Upload":"Wyślij","Error: File too large:":"Błąd: Plik za duży:","kb":"kb","Duplicate file error.":"Błąd: duplikacja pliku.","File size error.":"Plik jest zbyt duży.","N/A":"Nie dostępne","gb":"gb","Error: Invalid file extension:":"Błąd: Nieprawidłowe rozszerzenie pliku:","Select files":"Wybierz pliki:","%s already present in the queue.":"%s już występuje w kolejce.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Za duża rozdzielczość! <b>%s</b> maksymalna rozdzielczość to: %wx%hpx.","File: %s":"Plik: %s","b":"b","Uploaded %d/%d files":"Wysłano %d/%d plików","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Można jednocześnie dodać %d plików. Dodatkowe pliki zostały usunięte.","%d files queued":"%d plików w kolejce.","File: %s, size: %d, max file size: %d":"Plik: %s, rozmiar: %d, maksymalny rozmiar pliku: %d","Thumbnails":"Miniatury","Drag files here.":"Przeciągnij tu pliki","Runtime ran out of available memory.":"Wyczerpano pamięć RAM.","File count error.":"Błąd liczenia pliku.","File extension error.":"Nie obsługiwany format pliku.","mb":"mb","Add Files":"Dodaj pliki"});
\ No newline at end of file
// Portuguese (pt)
plupload.addI18n({"Stop Upload":"Parar envio","Upload URL might be wrong or doesn't exist.":"O URL para carregar os ficheiros pode estar errado ou não existir.","tb":"tb","Size":"Tamanho","Close":"Fechar","You must specify either browse_button or drop_element.":"Deve especificar ou o botão de navegação browse_button ou o elemento de recolha drop_element.","Init error.":"Erro ao iniciar.","Add files to the upload queue and click the start button.":"Adicione ficheiros à fila e clique no botão iniciar.","List":"Lista","Filename":"Nome do ficheiro","%s specified, but cannot be found.":"%s definido mas não foi encontrado.","Image format either wrong or not supported.":"Formato da imagem errado ou não é suportado.","Status":"Estado","HTTP Error.":"Erro HTTP.","Start Upload":"Começar envio","Error: File too large:":"Erro: Ficheiro demasiado grande:","kb":"kb","Duplicate file error.":"Erro: ficheiro duplicado.","File size error.":"Tamanho do ficheiro errado.","N/A":"N/D","gb":"gb","Error: Invalid file extension:":"Erro: Extensão de ficheiro inválida:","Select files":"Seleccione ficheiros","%s already present in the queue.":"%s já se encontra em fila.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Resolução excede os limites! <b>%s</b> suporta imagens até %wx%hpx.","File: %s":"Ficheiro: %s","b":"b","Uploaded %d/%d files":"Carregados %d/%d ficheiros","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Só é possível enviar %d ficheiro(s) de cada vez. Os restantes ficheiros foram excluídos.","%d files queued":"%d ficheiros em fila","File: %s, size: %d, max file size: %d":"Ficheiro: %s, tamanho: %d, tamanho máximo do ficheiro: %d","Thumbnails":"Miniaturas","Drag files here.":"Largar ficheiros aqui.","Runtime ran out of available memory.":"A execução esgotou a memória disponível.","File count error.":"Erro: contagem de ficheiros.","File extension error.":"Error de extensão do ficheiro.","mb":"mb","Add Files":"Adicionar ficheiros"});
\ No newline at end of file
// Portuguese (Brazil) (pt_BR)
plupload.addI18n({"Stop Upload":"Parar o envio","Upload URL might be wrong or doesn't exist.":"URL de envio incorreta ou inexistente","tb":"TB","Size":"Tamanho","Close":"Fechar","You must specify either browse_button or drop_element.":"Você deve especificar o botão para escolher(browse_button) os arquivos ou o elemento para arrastar(drop_element).","Init error.":"Erro ao iniciar.","Add files to the upload queue and click the start button.":"Adicione os arquivos à fila e clique no botão \"Iniciar o envio\".","List":"Listagem","Filename":"Nome do arquivo","%s specified, but cannot be found.":"Método de envio <b>%s</b> especificado, mas não pôde ser encontrado.","Image format either wrong or not supported.":"Imagem em formato desconhecido ou não permitido.","Status":"Status","HTTP Error.":"Erro HTTP.","Start Upload":"Iniciar o envio","Error: File too large:":"Erro: Arquivo muito grande:","kb":"KB","Duplicate file error.":"Erro: Arquivo duplicado.","File size error.":"Tamanho de arquivo não permitido.","N/A":"N/D","gb":"GB","Error: Invalid file extension:":"Erro: Extensão de arquivo inválida:","Select files":"Selecione os arquivos","%s already present in the queue.":"%s já presentes na fila.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Resolução fora de tamanho. O método de envio <b>%s</b> suporta imagens com no máximo %wx%hpx.","File: %s":"Arquivo: %s","b":"Bytes","Uploaded %d/%d files":"%d\\/%d arquivo(s) enviados(s)","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Só são aceitos %d arquivos por vez. O que passou disso foi descartado.","%d files queued":"%d arquivo(s)","File: %s, size: %d, max file size: %d":"Arquivo: %s, Tamanho: %d , Tamanho Máximo do Arquivo: %d","Thumbnails":"Miniaturas","Drag files here.":"Arraste os arquivos pra cá","Runtime ran out of available memory.":"Método de envio ficou sem mem\\u00f3ria.","File count error.":"Erro na contagem dos arquivos","File extension error.":"Tipo de arquivo não permitido.","mb":"MB","Add Files":"Adicionar arquivo(s)"});
\ No newline at end of file
// Romanian (ro)
plupload.addI18n({"Stop Upload":"Oprește încărcarea","Upload URL might be wrong or doesn't exist.":"Upload URL might be wrong or doesn't exist.","tb":"tb","Size":"Mărime","Close":"Închide","You must specify either browse_button or drop_element.":"","Init error.":"Eroare inițializare.","Add files to the upload queue and click the start button.":"Adaugă fișiere în lista apoi apasă butonul \"Începe încărcarea\".","List":"","Filename":"Nume fișier","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Formatul de imagine ori este greșit ori nu este suportat.","Status":"Stare","HTTP Error.":"Eroare HTTP","Start Upload":"Începe încărcarea","Error: File too large:":"Eroare: Fișierul este prea mare:","kb":"kb","Duplicate file error.":"Eroare duplicat fișier.","File size error.":"Eroare dimensiune fișier.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Eroare: Extensia fișierului este invalidă:","Select files":"Selectează fișierele","%s already present in the queue.":"%s există deja în lista de așteptare.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Fișier: %s","b":"b","Uploaded %d/%d files":"Fișiere încărcate %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"%d fișiere listate","File: %s, size: %d, max file size: %d":"Fișier: %s, mărime: %d, mărime maximă: %d","Thumbnails":"","Drag files here.":"Trage aici fișierele.","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"Eroare numărare fișiere.","File extension error.":"Eroare extensie fișier.","mb":"mb","Add Files":"Adaugă fișiere"});
\ No newline at end of file
// Russian (ru)
plupload.addI18n({"Stop Upload":"Остановить Загрузку","Upload URL might be wrong or doesn't exist.":"Адрес заргузки неправильный или он не существует.","tb":"тб","Size":"Размер","Close":"Закрыть","You must specify either browse_button or drop_element.":"Вы должны указать browse_button или drop_element.","Init error.":"Ошибка инициализации.","Add files to the upload queue and click the start button.":"Добавьте файлы в очередь и нажмите кнопку \"Загрузить файлы\".","List":"Список","Filename":"Имя файла","%s specified, but cannot be found.":"%s существует, но не может быть найден.","Image format either wrong or not supported.":"Формат картинки неправильный или он не поддерживается.","Status":"Статус","HTTP Error.":"Ошибка HTTP.","Start Upload":"Начать загрузку","Error: File too large:":"Ошибка: Файл слишком большой:","kb":"кб","Duplicate file error.":"Такой файл уже присутствует в очереди.","File size error.":"Неправильный размер файла.","N/A":"N/A","gb":"гб","Error: Invalid file extension:":"Ошибка: У файла неправильное расширение:","Select files":"Выберите файлы","%s already present in the queue.":"%s уже присутствует в очереди.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Слишком большое разрешение! <b>%s</b> поддерживаются изображения с размером не более %wx%hpx","File: %s":"Файл: %s","b":"б","Uploaded %d/%d files":"Загружено %d/%d файлов","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Загрузочный элемент за раз принимает только %d файл(ов). Лишние файлы были отброшены.","%d files queued":"В очереди %d файл(ов)","File: %s, size: %d, max file size: %d":"Файл: %s, размер: %d, макс. размер файла: %d","Thumbnails":"Миниатюра","Drag files here.":"Перетащите файлы сюда.","Runtime ran out of available memory.":"Рабочая среда превысила лимит достуной памяти.","File count error.":"Слишком много файлов.","File extension error.":"Неправильное расширение файла.","mb":"мб","Add Files":"Добавьте файлы"});
\ No newline at end of file
// Slovak (sk)
plupload.addI18n({"Stop Upload":"Zastaviť nahrávanie","Upload URL might be wrong or doesn't exist.":"URL pre nahratie nie je správna alebo neexistuje.","tb":"tb","Size":"Veľkosť","Close":"Zatvoriť","You must specify either browse_button or drop_element.":"","Init error.":"Chyba inicializácie.","Add files to the upload queue and click the start button.":"Pridajte súbory do zoznamu a potom spustite nahrávanie.","List":"","Filename":"Názov súboru","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Formát obrázku je nesprávny alebo nie je podporovaný.","Status":"Stav","HTTP Error.":"HTTP Chyba.","Start Upload":"Spustiť nahrávanie","Error: File too large:":"Chyba: Súbor je príliš veľký:","kb":"kb","Duplicate file error.":"Duplicitný súbor.","File size error.":"Súbor je príliš veľký.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Error: Nesprávny typ súboru:","Select files":"Vyberte súbory","%s already present in the queue.":"%s sa už nachádza v zozname.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Súbor: %s","b":"b","Uploaded %d/%d files":"Nahraných %d/%d súborov","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"%d súborov pridaných do zoznamu","File: %s, size: %d, max file size: %d":"Súbor: %s, veľkosť: %d, max. veľkosť súboru: %d","Thumbnails":"","Drag files here.":"Sem pretiahnite súbory.","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"Nesprávny počet súborov.","File extension error.":"Chybný typ súboru.","mb":"mb","Add Files":"Pridať súbory"});
\ No newline at end of file
// Slovenian (sl)
plupload.addI18n({"Stop Upload":"Ustavi prenos","Upload URL might be wrong or doesn't exist.":"URL za nalaganje je napačen ali ne obstaja.","tb":"tb","Size":"Velikost","Close":"Zapri","You must specify either browse_button or drop_element.":"","Init error.":"Napaka pri inicializaciji.","Add files to the upload queue and click the start button.":"Dodaj datoteke na seznam in klikni na gumb začni","List":"Seznam","Filename":"Ime datoteke","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Format slike je napačen ali ni podrpt.","Status":"Status","HTTP Error.":"Neznana HTTP napaka.","Start Upload":"Začni prenos","Error: File too large:":"Napaka: datoteka je prevelika:","kb":"kb","Duplicate file error.":"Datoteka je že na seznamu.","File size error.":"Datoteka je prevelika.","N/A":"Ni na voljo","gb":"gb","Error: Invalid file extension:":"Napaka: napačen tip datoteke:","Select files":"Izberi datoteke","%s already present in the queue.":"%s je že na seznamu.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Datoteka: %s","b":"b","Uploaded %d/%d files":"Naloženo %d/%d datotek","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Nalagalnik sprejme samo %d datotek na enkrat. Višek datotek je odstranjen iz seznama.","%d files queued":"%d datotek na seznamu","File: %s, size: %d, max file size: %d":"Datoteka: %s, velikost: %d, največja dovoljena velikost: %d","Thumbnails":"Sličice","Drag files here.":"Potegni datoteke sem.","Runtime ran out of available memory.":"Zmanjkalo je pomnilnika.","File count error.":"Napačno število datotek.","File extension error.":"Napačen tip datoteke.","mb":"mb","Add Files":"Dodaj datoteke"});
\ No newline at end of file
// Albanian (sq)
plupload.addI18n({"Stop Upload":"Ndalimi i ngarkimit","Upload URL might be wrong or doesn't exist.":"Ngarkimi i URL-s është i gabuar ose nuk ekziston.","tb":"TB","Size":"Madhësia","Close":"Mbyll","You must specify either browse_button or drop_element.":"","Init error.":"Init gabim.","Add files to the upload queue and click the start button.":"Mbas ngarkimit të dosjeve sipas rradhës duhet të klikoni butonin Start.","List":"","Filename":"Emri i dosjes","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Formati i fotove është i keq ose nuk është i pranueshëm.","Status":"Statusi","HTTP Error.":"HTTP Gabim.","Start Upload":"Nisja e ngarkimit","Error: File too large:":"Gabim: dosja është shumë e madhe:","kb":"KB","Duplicate file error.":"Gabim i dublikimit të dosjes.","File size error.":"Gabim i madhësisë së dosjes.","N/A":"Nuk është në dispozicion","gb":"GB","Error: Invalid file extension:":"Gabim: përhapja e llojit të dosjes është e pavlefshme:","Select files":"Zhgjidhni dosjet","%s already present in the queue.":"%s tashmë ekziston në list.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"Dosje: %s","b":"B","Uploaded %d/%d files":"Dosjet e ngarkuara: %d/%d","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Ngarkimi pranon njëherësh vetëm %d dosje, dosjet e tjera nuk do të jenë të ngarkuara.","%d files queued":"Dosja %d e vendosur në rradhë","File: %s, size: %d, max file size: %d":"Dosje: %s, madhësia: %d, madhësia maximale e dosjes: %d","Thumbnails":"","Drag files here.":"Këtu mund të tërhiqni dosjet","Runtime ran out of available memory.":"Memoria që ishte në dispozicion ka mbaruar.","File count error.":"Gabim në lidhje me numrin e dosjeve.","File extension error.":"Gabim i zgjerimit të dosjes.","mb":"MB","Add Files":"Shtoni dosjet"});
\ No newline at end of file
// Serbian (sr)
plupload.addI18n({"Stop Upload":"Stop Upload","Upload URL might be wrong or doesn't exist.":"Upload URL might be wrong or doesn't exist.","tb":"","Size":"Veličina","Close":"Close","You must specify either browse_button or drop_element.":"","Init error.":"Init error.","Add files to the upload queue and click the start button.":"Dodajte fajlove u listu i kliknite na dugme Start.","List":"","Filename":"Naziv fajla","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"Image format either wrong or not supported.","Status":"Status","HTTP Error.":"HTTP Error.","Start Upload":"Počni upload","Error: File too large:":"Error: File too large:","kb":"","Duplicate file error.":"","File size error.":"File size error.","N/A":"N/A","gb":"","Error: Invalid file extension:":"Error: Invalid file extension:","Select files":"Izaberite fajlove","%s already present in the queue.":"","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"File: %s","b":"","Uploaded %d/%d files":"Snimljeno %d/%d fajlova","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Upload element accepts only %d file(s) at a time. Extra files were stripped.","%d files queued":"%d files queued","File: %s, size: %d, max file size: %d":"","Thumbnails":"","Drag files here.":"Prevucite fajlove ovde.","Runtime ran out of available memory.":"Runtime ran out of available memory.","File count error.":"File count error.","File extension error.":"File extension error.","mb":"","Add Files":"Dodaj fajlove"});
\ No newline at end of file
// Swedish (sv)
plupload.addI18n({"Stop Upload":"Avbryt","Upload URL might be wrong or doesn't exist.":"URL:en va fel eller existerar inte.","tb":"tb","Size":"Storlek","Close":"Stäng","You must specify either browse_button or drop_element.":"Du behöver specificera browse_button eller drop_element.","Init error.":"Problem vid initialisering.","Add files to the upload queue and click the start button.":"Lägg till filer till kön och tryck på start.","List":"Lista","Filename":"Filnamn","%s specified, but cannot be found.":"%s specificerad, men hittades inte.","Image format either wrong or not supported.":"Bildformatet är fel eller så finns inte stöd för det.","Status":"Status","HTTP Error.":"HTTP problem.","Start Upload":"Starta","Error: File too large:":"Fel: Filen är för stor:","kb":"kb","Duplicate file error.":"Problem med dubbla filer.","File size error.":"Problem med filstorlek.","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"Fel: Ej godkänd filändelse.","Select files":"Välj filer","%s already present in the queue.":"%s är redan tillagd.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Upplösning utanför gränserna! <b>%s</b> bara bilder upp till %wx%hpx stöds.","File: %s":"Fil: %s","b":"b","Uploaded %d/%d files":"Laddade upp %d/%d filer","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Det går bara lägga till %d filer åt gången, allt utöver detta togs bort.","%d files queued":"%d filer i kö","File: %s, size: %d, max file size: %d":"Fil: %s, storlek: %d, max storlek: %d","Thumbnails":"Miniatyrer","Drag files here.":"Dra filer hit","Runtime ran out of available memory.":"Slut på minne.","File count error.":"Räknefel.","File extension error.":"Problem med filändelse.","mb":"mb","Add Files":"Lägg till"});
\ No newline at end of file
// Thai (Thailand) (th_TH)
plupload.addI18n({"Stop Upload":"หยุดอัพโหลด","Upload URL might be wrong or doesn't exist.":"URL ของการอัพโหลดอาจจะผิดหรือไม่มีอยู่","tb":"เทราไบต์","Size":"ขนาด","Close":"ปิด","You must specify either browse_button or drop_element.":"","Init error.":"Init เกิดข้อผิดพลาด","Add files to the upload queue and click the start button.":"เพิ่มไฟล์ไปยังคิวอัพโหลดและคลิกที่ปุ่มเริ่ม","List":"","Filename":"ชื่อไฟล์","%s specified, but cannot be found.":"","Image format either wrong or not supported.":"รูปแบบรูปภาพทั้งสองผิดหรือไม่รองรับ","Status":"สถานะ","HTTP Error.":"HTTP เกิดข้อผิดพลาด","Start Upload":"เริ่มอัพโหลด","Error: File too large:":"ข้อผิดพลาด: ไฟล์ใหญ่เกินไป:","kb":"กิโลไบต์","Duplicate file error.":"ไฟล์ที่ซ้ำกันเกิดข้อผิดพลาด","File size error.":"ขนาดไฟล์เกิดข้อผิดพลาด","N/A":"N/A","gb":"กิกะไบต์","Error: Invalid file extension:":"ข้อผิดพลาด: นามสกุลไฟล์ไม่ถูกต้อง:","Select files":"เลือกไฟล์","%s already present in the queue.":"%s อยู่ในคิวแล้ว","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"","File: %s":"ไฟล์: %s","b":"ไบต์","Uploaded %d/%d files":"อัพโหลดแล้ว %d/%d ไฟล์","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"การอัพโหลดจะยอมรับเฉพาะ %d ไฟล์(s) ในช่วงเวลาเดียวกัน เมื่อไฟล์พิเศษถูกปลดออก","%d files queued":"%d ไฟล์ที่อยู่ในคิว","File: %s, size: %d, max file size: %d":"ไฟล์: %s, ขนาด: %d, ขนาดไฟล์สูงสุด: %d","Thumbnails":"","Drag files here.":"ลากไฟล์มาที่นี่","Runtime ran out of available memory.":"รันไทม์วิ่งออกมาจากหน่วยความจำ","File count error.":"การนับไฟล์เกิดข้อผิดพลาด","File extension error.":"นามสกุลไฟล์เกิดข้อผิดพลาด","mb":"เมกะไบต์","Add Files":"เพิ่มไฟล์"});
\ No newline at end of file
// Turkish (tr)
plupload.addI18n({"Stop Upload":"Yüklemeyi durdur","Upload URL might be wrong or doesn't exist.":"URL yok ya da hatalı olabilir.","tb":"tb","Size":"Boyut","Close":"Kapat","You must specify either browse_button or drop_element.":"browse_button veya drop_element değişkenlerini belirlemelisiniz.","Init error.":"Başlangıç hatası.","Add files to the upload queue and click the start button.":"Dosyaları kuyruğa ekleyin ve başlatma butonuna tıklayın.","List":"Liste","Filename":"Dosya adı","%s specified, but cannot be found.":"%s tanımlandı fakat bulunamadı.","Image format either wrong or not supported.":"Resim formatı yanlış ya da desteklenmiyor.","Status":"Durum","HTTP Error.":"HTTP hatası.","Start Upload":"Yüklemeyi başlat","Error: File too large:":"Hata: Dosya çok büyük:","kb":"kb","Duplicate file error.":"Yinelenen dosya hatası.","File size error.":"Dosya boyutu hatası.","N/A":"-","gb":"gb","Error: Invalid file extension:":"Hata: Geçersiz dosya uzantısı:","Select files":"Dosyaları seç","%s already present in the queue.":"%s kuyrukta zaten mevcut.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Çözünürlük sınırların dışındadır! <b>%s</b> modu en fazla %wx%hpx desteklemektedir.","File: %s":"Dosya: %s","b":"bayt","Uploaded %d/%d files":"%d/%d dosya yüklendi","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Yükleme elemanı aynı anda %d dosya kabul eder. Ekstra dosyalar işleme konulmaz.","%d files queued":"Kuyrukta %d dosya var.","File: %s, size: %d, max file size: %d":"Dosya: %s, boyut: %d, maksimum dosya boyutu: %d","Thumbnails":"Önizlemeler","Drag files here.":"Dosyaları buraya bırakın.","Runtime ran out of available memory.":"İşlem için yeterli bellek yok.","File count error.":"Dosya sayım hatası.","File extension error.":"Dosya uzantısı hatası.","mb":"mb","Add Files":"Dosya ekle"});
\ No newline at end of file
// Ukrainian (Ukraine) (uk_UA)
plupload.addI18n({"Stop Upload":"Зупинити завантаження","Upload URL might be wrong or doesn't exist.":"Адреса завантаження неправильна або не існує.","tb":"тб","Size":"Розмір","Close":"Закрити","You must specify either browse_button or drop_element.":"Ви маєте вказати або browse_button, або drop_element.","Init error.":"Помилка ініціалізації.","Add files to the upload queue and click the start button.":"Додайте файли в чергу та натисніть кнопку \"Завантажити файли\".","List":"Список","Filename":"Назва файлу","%s specified, but cannot be found.":"%s вказано, але не може бути знайдено.","Image format either wrong or not supported.":"Формат картинки не правильний або не підтримується.","Status":"Статус","HTTP Error.":"Помилка HTTP.","Start Upload":"Почати завантаження","Error: File too large:":"Помилка: Файл занадто великий:","kb":"кб","Duplicate file error.":"Такий файл вже присутній в черзі.","File size error.":"Неправильний розмір файлу.","N/A":"Н/Д","gb":"гб","Error: Invalid file extension:":"Помилка: У файлу неправильне розширення:","Select files":"Оберіть файли","%s already present in the queue.":"%s вже присутній у черзі.","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Роздільна здатність поза межами! Робоче середовище <b>%s</b> підтримує зображення лише до %wx%hpx.","File: %s":"Файл: %s","b":"б","Uploaded %d/%d files":"Завантажено %d/%d файлів","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Завантажувальний елемент приймає лише %d файл(ів) одночасно. Зайві файли було відкинуто.","%d files queued":"В черзі %d файл(ів)","File: %s, size: %d, max file size: %d":"Файл: %s, розмір: %d, макс. розмір файлу: %d","Thumbnails":"Мініатюри","Drag files here.":"Перетягніть файли сюди.","Runtime ran out of available memory.":"Робоче середовище перевищило ліміт доступної пам'яті.","File count error.":"Занадто багато файлів.","File extension error.":"Неправильне розширення файлу.","mb":"мб","Add Files":"Додати файли"});
\ No newline at end of file
// Vietnamese (vi)
plupload.addI18n({"Stop Upload":"Dừng","Upload URL might be wrong or doesn't exist.":"Đường dẫn URL tải lên không đúng hoặc không tồn tại.","tb":"TB","Size":"Dung lượng","Close":"Đóng","You must specify either browse_button or drop_element.":"","Init error.":"Lỗi khởi tạo","Add files to the upload queue and click the start button.":"Thêm tập tin để tải lên và bấm vào nút bắt đầu","List":"Danh sách","Filename":"Tên tập tin","%s specified, but cannot be found.":"%s đã chỉ định nhưng không thể tìm thấy.","Image format either wrong or not supported.":"Định dạng hình ảnh không đúng hoặc không được hỗ trợ.","Status":"Trạng thái","HTTP Error.":"Lỗi HTTP","Start Upload":"Bắt đầu","Error: File too large:":"Lỗi: Dung lượng tập tin quá lớn:","kb":"KB","Duplicate file error.":"Tập tin đã tồn tại","File size error.":"Lỗi dung lượng tập tin","N/A":"Chưa có thông tin","gb":"GB","Error: Invalid file extension:":"Lỗi: Định dạng tập tin không xác định:","Select files":"Chọn tập tin","%s already present in the queue.":"%s đã có trong danh sách chờ tải lên","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"Độ phân giải quá lớn! <b>%s</b> chỉ hỗ trợ kích thước tối đa %wx%hpx.","File: %s":"Tập tin: %s","b":"B","Uploaded %d/%d files":"Đã tải lên %d/%d tập tin","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"Chỉ có thể tải lên (%d) tập tin cùng một lúc. Những tập tin còn lại đã bị huỷ bỏ.","%d files queued":"%d tập tin trong danh sách chờ","File: %s, size: %d, max file size: %d":"Tập tin: %s, dung lượng %d, dung lượng tối đa: %d","Thumbnails":"Ảnh thu nhỏ","Drag files here.":"Thả tập tin vào đây","Runtime ran out of available memory.":"Thời gian chạy vượt quá giới hạn bộ nhớ cho phép.","File count error.":"Lỗi đếm tập tin","File extension error.":"Lỗi định dạng tập tin","mb":"MB","Add Files":"Thêm tập tin"});
\ No newline at end of file
// Chinese (China) (zh_CN)
plupload.addI18n({"Stop Upload":"停止上传","Upload URL might be wrong or doesn't exist.":"上传的URL可能是错误的或不存在。","tb":"tb","Size":"大小","Close":"关闭","You must specify either browse_button or drop_element.":"您必须指定 browse_button 或者 drop_element。","Init error.":"初始化错误。","Add files to the upload queue and click the start button.":"将文件添加到上传队列,然后点击”开始上传“按钮。","List":"列表","Filename":"文件名","%s specified, but cannot be found.":"%s 已指定,但是没有找到。","Image format either wrong or not supported.":"图片格式错误或者不支持。","Status":"状态","HTTP Error.":"HTTP 错误。","Start Upload":"开始上传","Error: File too large:":"错误: 文件太大:","kb":"kb","Duplicate file error.":"重复文件错误。","File size error.":"文件大小错误。","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"错误:无效的文件扩展名:","Select files":"选择文件","%s already present in the queue.":"%s 已经在当前队列里。","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"超限。<b>%s</b> 支持最大 %wx%hpx 的图片。","File: %s":"文件: %s","b":"b","Uploaded %d/%d files":"已上传 %d/%d 个文件","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"每次只接受同时上传 %d 个文件,多余的文件将会被删除。","%d files queued":"%d 个文件加入到队列","File: %s, size: %d, max file size: %d":"文件: %s, 大小: %d, 最大文件大小: %d","Thumbnails":"缩略图","Drag files here.":"把文件拖到这里。","Runtime ran out of available memory.":"运行时已消耗所有可用内存。","File count error.":"文件数量错误。","File extension error.":"文件扩展名错误。","mb":"mb","Add Files":"增加文件"});
\ No newline at end of file
// Chinese (Taiwan) (zh_TW)
plupload.addI18n({"Stop Upload":"停止上傳","Upload URL might be wrong or doesn't exist.":"檔案URL可能有誤或者不存在。","tb":"tb","Size":"大小","Close":"關閉","You must specify either browse_button or drop_element.":"您必須指定 browse_button 或 drop_element。","Init error.":"初始化錯誤。","Add files to the upload queue and click the start button.":"將檔案加入上傳序列,然後點選”開始上傳“按鈕。","List":"清單","Filename":"檔案名稱","%s specified, but cannot be found.":"找不到已選擇的 %s。","Image format either wrong or not supported.":"圖片格式錯誤或者不支援。","Status":"狀態","HTTP Error.":"HTTP 錯誤。","Start Upload":"開始上傳","Error: File too large:":"錯誤: 檔案大小太大:","kb":"kb","Duplicate file error.":"錯誤:檔案重複。","File size error.":"錯誤:檔案大小超過限制。","N/A":"N/A","gb":"gb","Error: Invalid file extension:":"錯誤:不接受的檔案格式:","Select files":"選擇檔案","%s already present in the queue.":"%s 已經存在目前的檔案序列。","Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.":"圖片解析度超出範圍! <b>%s</b> 最高只支援到 %wx%hpx。","File: %s":"檔案: %s","b":"b","Uploaded %d/%d files":"已上傳 %d/%d 個文件","Upload element accepts only %d file(s) at a time. Extra files were stripped.":"每次只能上傳 %d 個檔案,超過限制數量的檔案將被忽略。","%d files queued":"%d 個檔案加入到序列","File: %s, size: %d, max file size: %d":"檔案: %s, 大小: %d, 檔案大小上限: %d","Thumbnails":"縮圖","Drag files here.":"把檔案拖曳到這裡。","Runtime ran out of available memory.":"執行時耗盡了所有可用的記憶體。","File count error.":"檔案數量錯誤。","File extension error.":"檔案副檔名錯誤。","mb":"mb","Add Files":"增加檔案"});
\ No newline at end of file
/*
Plupload
------------------------------------------------------------------- */
.plupload_wrapper * {
box-sizing: content-box;
}
.plupload_button {
display: -moz-inline-box; /* FF < 3*/
display: inline-block;
font: normal 12px sans-serif;
text-decoration: none;
color: #42454a;
border: 1px solid #bababa;
padding: 2px 8px 3px 20px;
margin-right: 4px;
background: #f3f3f3 url('../img/buttons.png') no-repeat 0 center;
outline: 0;
/* Optional rounded corners for browsers that support it */
-moz-border-radius: 3px;
-khtml-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
}
.plupload_button:hover {
color: #000;
text-decoration: none;
}
.plupload_disabled, a.plupload_disabled:hover {
color: #737373;
border-color: #c5c5c5;
background: #ededed url('../img/buttons-disabled.png') no-repeat 0 center;
cursor: default;
}
.plupload_add {
background-position: -181px center;
}
.plupload_wrapper {
font: normal 11px Verdana,sans-serif;
width: 100%;
}
.plupload_container {
padding: 8px;
background: url('../img/transp50.png');
/*-moz-border-radius: 5px;*/
}
.plupload_container input {
border: 1px solid #DDD;
font: normal 11px Verdana,sans-serif;
width: 98%;
}
.plupload_header {background: #2A2C2E url('../img/backgrounds.gif') repeat-x;}
.plupload_header_content {
background: url('../img/backgrounds.gif') no-repeat 0 -317px;
min-height: 56px;
padding-left: 60px;
color: #FFF;
}
.plupload_header_title {
font: normal 18px sans-serif;
padding: 6px 0 3px;
}
.plupload_header_text {
font: normal 12px sans-serif;
}
.plupload_filelist {
margin: 0;
padding: 0;
list-style: none;
}
.plupload_scroll .plupload_filelist {
height: 185px;
background: #F5F5F5;
overflow-y: scroll;
}
.plupload_filelist li {
padding: 10px 8px;
background: #F5F5F5 url('../img/backgrounds.gif') repeat-x 0 -156px;
border-bottom: 1px solid #DDD;
}
.plupload_filelist_header, .plupload_filelist_footer {
background: #DFDFDF;
padding: 8px 8px;
color: #42454A;
}
.plupload_filelist_header {
border-top: 1px solid #EEE;
border-bottom: 1px solid #CDCDCD;
}
.plupload_filelist_footer {border-top: 1px solid #FFF; height: 22px; line-height: 20px; vertical-align: middle;}
.plupload_file_name {float: left; overflow: hidden}
.plupload_file_status {color: #777;}
.plupload_file_status span {color: #42454A;}
.plupload_file_size, .plupload_file_status, .plupload_progress {
float: right;
width: 80px;
}
.plupload_file_size, .plupload_file_status, .plupload_file_action {text-align: right;}
.plupload_filelist .plupload_file_name {
width: 205px;
white-space: nowrap;
text-overflow: ellipsis;
}
.plupload_file_action {
float: right;
width: 16px;
height: 16px;
margin-left: 15px;
}
.plupload_file_action * {
display: none;
width: 16px;
height: 16px;
}
li.plupload_uploading {background: #ECF3DC url('../img/backgrounds.gif') repeat-x 0 -238px;}
li.plupload_done {color:#AAA}
li.plupload_delete a {
background: url('../img/delete.gif');
}
li.plupload_failed a {
background: url('../img/error.gif');
cursor: default;
}
li.plupload_done a {
background: url('../img/done.gif');
cursor: default;
}
.plupload_progress, .plupload_upload_status {
display: none;
}
.plupload_progress_container {
margin-top: 3px;
border: 1px solid #CCC;
background: #FFF;
padding: 1px;
}
.plupload_progress_bar {
width: 0px;
height: 7px;
background: #CDEB8B;
}
.plupload_scroll .plupload_filelist_header .plupload_file_action, .plupload_scroll .plupload_filelist_footer .plupload_file_action {
margin-right: 17px;
}
/* Floats */
.plupload_clear,.plupload_clearer {clear: both;}
.plupload_clearer, .plupload_progress_bar {
display: block;
font-size: 0;
line-height: 0;
}
li.plupload_droptext {
background: transparent;
text-align: center;
vertical-align: middle;
border: 0;
line-height: 165px;
}
/**
* jquery.plupload.queue.js
*
* Copyright 2009, Moxiecode Systems AB
* Released under GPL License.
*
* License: http://www.plupload.com/license
* Contributing: http://www.plupload.com/contributing
*/
/* global jQuery:true, alert:true */
/**
jQuery based implementation of the Plupload API - multi-runtime file uploading API.
To use the widget you must include _jQuery_. It is not meant to be extended in any way and is provided to be
used as it is.
@example
<!-- Instantiating: -->
<div id="uploader">
<p>Your browser doesn't have Flash, Silverlight or HTML5 support.</p>
</div>
<script>
$('#uploader').pluploadQueue({
url : '../upload.php',
filters : [
{title : "Image files", extensions : "jpg,gif,png"}
],
rename: true,
flash_swf_url : '../../js/Moxie.swf',
silverlight_xap_url : '../../js/Moxie.xap',
});
</script>
@example
// Retrieving a reference to plupload.Uploader object
var uploader = $('#uploader').pluploadQueue();
uploader.bind('FilesAdded', function() {
// Autostart
setTimeout(uploader.start, 1); // "detach" from the main thread
});
@class pluploadQueue
@constructor
@param {Object} settings For detailed information about each option check documentation.
@param {String} settings.url URL of the server-side upload handler.
@param {Number|String} [settings.chunk_size=0] Chunk size in bytes to slice the file into. Shorcuts with b, kb, mb, gb, tb suffixes also supported. `e.g. 204800 or "204800b" or "200kb"`. By default - disabled.
@param {String} [settings.file_data_name="file"] Name for the file field in Multipart formated message.
@param {Array} [settings.filters=[]] Set of file type filters, each one defined by hash of title and extensions. `e.g. {title : "Image files", extensions : "jpg,jpeg,gif,png"}`. Dispatches `plupload.FILE_EXTENSION_ERROR`
@param {String} [settings.flash_swf_url] URL of the Flash swf.
@param {Object} [settings.headers] Custom headers to send with the upload. Hash of name/value pairs.
@param {Number|String} [settings.max_file_size] Maximum file size that the user can pick, in bytes. Optionally supports b, kb, mb, gb, tb suffixes. `e.g. "10mb" or "1gb"`. By default - not set. Dispatches `plupload.FILE_SIZE_ERROR`.
@param {Number} [settings.max_retries=0] How many times to retry the chunk or file, before triggering Error event.
@param {Boolean} [settings.multipart=true] Whether to send file and additional parameters as Multipart formated message.
@param {Object} [settings.multipart_params] Hash of key/value pairs to send with every file upload.
@param {Boolean} [settings.multi_selection=true] Enable ability to select multiple files at once in file dialog.
@param {Boolean} [settings.prevent_duplicates=false] Do not let duplicates into the queue. Dispatches `plupload.FILE_DUPLICATE_ERROR`.
@param {String|Object} [settings.required_features] Either comma-separated list or hash of required features that chosen runtime should absolutely possess.
@param {Object} [settings.resize] Enable resizng of images on client-side. Applies to `image/jpeg` and `image/png` only. `e.g. {width : 200, height : 200, quality : 90, crop: true}`
@param {Number} [settings.resize.width] If image is bigger, it will be resized.
@param {Number} [settings.resize.height] If image is bigger, it will be resized.
@param {Number} [settings.resize.quality=90] Compression quality for jpegs (1-100).
@param {Boolean} [settings.resize.crop=false] Whether to crop images to exact dimensions. By default they will be resized proportionally.
@param {String} [settings.runtimes="html5,flash,silverlight,html4"] Comma separated list of runtimes, that Plupload will try in turn, moving to the next if previous fails.
@param {String} [settings.silverlight_xap_url] URL of the Silverlight xap.
@param {Boolean} [settings.unique_names=false] If true will generate unique filenames for uploaded files.
@param {Boolean} [settings.dragdrop=true] Enable ability to add file to the queue by drag'n'dropping them from the desktop.
@param {Boolean} [settings.rename=false] Enable ability to rename files in the queue.
@param {Boolean} [settings.multiple_queues=true] Re-activate the widget after each upload procedure.
*/
;(function($, plupload) {
var uploaders = {};
function _(str) {
return plupload.translate(str) || str;
}
function renderUI(id, target) {
// Remove all existing non plupload items
target.contents().each(function(i, node) {
node = $(node);
if (!node.is('.plupload')) {
node.remove();
}
});
target.prepend(
'<div class="plupload_wrapper plupload_scroll">' +
'<div id="' + id + '_container" class="plupload_container">' +
'<div class="plupload">' +
'<div class="plupload_header">' +
'<div class="plupload_header_content">' +
'<div class="plupload_header_title">' + _('Select files') + '</div>' +
'<div class="plupload_header_text">' + _('Add files to the upload queue and click the start button.') + '</div>' +
'</div>' +
'</div>' +
'<div class="plupload_content">' +
'<div class="plupload_filelist_header">' +
'<div class="plupload_file_name">' + _('Filename') + '</div>' +
'<div class="plupload_file_action">&nbsp;</div>' +
'<div class="plupload_file_status"><span>' + _('Status') + '</span></div>' +
'<div class="plupload_file_size">' + _('Size') + '</div>' +
'<div class="plupload_clearer">&nbsp;</div>' +
'</div>' +
'<ul id="' + id + '_filelist" class="plupload_filelist"></ul>' +
'<div class="plupload_filelist_footer">' +
'<div class="plupload_file_name">' +
'<div class="plupload_buttons">' +
'<a href="#" class="plupload_button plupload_add" id="' + id + '_browse">' + _('Add Files') + '</a>' +
'<a href="#" class="plupload_button plupload_start">' + _('Start Upload') + '</a>' +
'</div>' +
'<span class="plupload_upload_status"></span>' +
'</div>' +
'<div class="plupload_file_action"></div>' +
'<div class="plupload_file_status"><span class="plupload_total_status">0%</span></div>' +
'<div class="plupload_file_size"><span class="plupload_total_file_size">0 b</span></div>' +
'<div class="plupload_progress">' +
'<div class="plupload_progress_container">' +
'<div class="plupload_progress_bar"></div>' +
'</div>' +
'</div>' +
'<div class="plupload_clearer">&nbsp;</div>' +
'</div>' +
'</div>' +
'</div>' +
'</div>' +
'<input type="hidden" id="' + id + '_count" name="' + id + '_count" value="0" />' +
'</div>'
);
}
$.fn.pluploadQueue = function(settings) {
if (settings) {
this.each(function() {
var uploader, target, id, contents_bak;
target = $(this);
id = target.attr('id');
if (!id) {
id = plupload.guid();
target.attr('id', id);
}
contents_bak = target.html();
renderUI(id, target);
settings = $.extend({
dragdrop : true,
browse_button : id + '_browse',
container : id
}, settings);
// Enable drag/drop (see PostInit handler as well)
if (settings.dragdrop) {
settings.drop_element = id + '_filelist';
}
uploader = new plupload.Uploader(settings);
uploaders[id] = uploader;
function handleStatus(file) {
var actionClass;
if (file.status == plupload.DONE) {
actionClass = 'plupload_done';
}
if (file.status == plupload.FAILED) {
actionClass = 'plupload_failed';
}
if (file.status == plupload.QUEUED) {
actionClass = 'plupload_delete';
}
if (file.status == plupload.UPLOADING) {
actionClass = 'plupload_uploading';
}
var icon = $('#' + file.id).attr('class', actionClass).find('a').css('display', 'block');
if (file.hint) {
icon.attr('title', file.hint);
}
}
function updateTotalProgress() {
$('span.plupload_total_status', target).html(uploader.total.percent + '%');
$('div.plupload_progress_bar', target).css('width', uploader.total.percent + '%');
$('span.plupload_upload_status', target).html(
plupload.sprintf(_('Uploaded %d/%d files'), uploader.total.uploaded, uploader.files.length)
);
}
function updateList() {
var fileList = $('ul.plupload_filelist', target).html(''), inputCount = 0, inputHTML;
$.each(uploader.files, function(i, file) {
inputHTML = '';
if (file.status == plupload.DONE) {
if (file.target_name) {
inputHTML += '<input type="hidden" name="' + id + '_' + inputCount + '_tmpname" value="' + plupload.xmlEncode(file.target_name) + '" />';
}
inputHTML += '<input type="hidden" name="' + id + '_' + inputCount + '_name" value="' + plupload.xmlEncode(file.name) + '" />';
inputHTML += '<input type="hidden" name="' + id + '_' + inputCount + '_status" value="' + (file.status == plupload.DONE ? 'done' : 'failed') + '" />';
inputCount++;
$('#' + id + '_count').val(inputCount);
}
fileList.append(
'<li id="' + file.id + '">' +
'<div class="plupload_file_name"><span>' + file.name + '</span></div>' +
'<div class="plupload_file_action"><a href="#"></a></div>' +
'<div class="plupload_file_status">' + file.percent + '%</div>' +
'<div class="plupload_file_size">' + plupload.formatSize(file.size) + '</div>' +
'<div class="plupload_clearer">&nbsp;</div>' +
inputHTML +
'</li>'
);
handleStatus(file);
$('#' + file.id + '.plupload_delete a').click(function(e) {
$('#' + file.id).remove();
uploader.removeFile(file);
e.preventDefault();
});
});
$('span.plupload_total_file_size', target).html(plupload.formatSize(uploader.total.size));
if (uploader.total.queued === 0) {
$('span.plupload_add_text', target).html(_('Add Files'));
} else {
$('span.plupload_add_text', target).html(plupload.sprintf(_('%d files queued'), uploader.total.queued));
}
$('a.plupload_start', target).toggleClass('plupload_disabled', uploader.files.length == (uploader.total.uploaded + uploader.total.failed));
// Scroll to end of file list
fileList[0].scrollTop = fileList[0].scrollHeight;
updateTotalProgress();
// Re-add drag message if there is no files
if (!uploader.files.length && uploader.features.dragdrop && uploader.settings.dragdrop) {
$('#' + id + '_filelist').append('<li class="plupload_droptext">' + _("Drag files here.") + '</li>');
}
}
function destroy() {
delete uploaders[id];
uploader.destroy();
target.html(contents_bak);
uploader = target = contents_bak = null;
}
uploader.bind("UploadFile", function(up, file) {
$('#' + file.id).addClass('plupload_current_file');
});
uploader.bind('Init', function(up, res) {
// Enable rename support
if (!settings.unique_names && settings.rename) {
target.on('click', '#' + id + '_filelist div.plupload_file_name span', function(e) {
var targetSpan = $(e.target), file, parts, name, ext = "";
var fileContainer = targetSpan.closest('li');
if (!fileContainer.hasClass('plupload_delete')) {
return;
}
// Get file name and split out name and extension
file = up.getFile(targetSpan.parents('li')[0].id);
name = file.name;
parts = /^(.+)(\.[^.]+)$/.exec(name);
if (parts) {
name = parts[1];
ext = parts[2];
}
// Display input element
targetSpan.hide().after('<input type="text" />');
targetSpan.next().val(name).focus().blur(function() {
targetSpan.show().next().remove();
}).keydown(function(e) {
var targetInput = $(this);
if (e.keyCode == 13) {
e.preventDefault();
// Rename file and glue extension back on
file.name = targetInput.val() + ext;
targetSpan.html(file.name);
targetInput.blur();
}
});
});
}
$('#' + id + '_container').attr('title', 'Using runtime: ' + res.runtime);
$('a.plupload_start', target).click(function(e) {
if (!$(this).hasClass('plupload_disabled')) {
uploader.start();
}
e.preventDefault();
});
$('a.plupload_stop', target).click(function(e) {
e.preventDefault();
uploader.stop();
});
$('a.plupload_start', target).addClass('plupload_disabled');
});
uploader.bind("Error", function(up, err) {
var file = err.file, message;
if (file) {
message = err.message;
if (err.details) {
message += " (" + err.details + ")";
}
if (err.code == plupload.FILE_SIZE_ERROR) {
alert(_("Error: File too large:") + " " + file.name);
}
if (err.code == plupload.FILE_EXTENSION_ERROR) {
alert(_("Error: Invalid file extension:") + " " + file.name);
}
file.hint = message;
$('#' + file.id).attr('class', 'plupload_failed').find('a').css('display', 'block').attr('title', message);
}
if (err.code === plupload.INIT_ERROR) {
setTimeout(function() {
destroy();
}, 1);
}
});
uploader.bind("PostInit", function(up) {
// features are populated only after input components are fully instantiated
if (up.settings.dragdrop && up.features.dragdrop) {
$('#' + id + '_filelist').append('<li class="plupload_droptext">' + _("Drag files here.") + '</li>');
}
});
uploader.init();
uploader.bind('StateChanged', function() {
if (uploader.state === plupload.STARTED) {
$('li.plupload_delete a,div.plupload_buttons', target).hide();
uploader.disableBrowse(true);
$('span.plupload_upload_status,div.plupload_progress,a.plupload_stop', target).css('display', 'block');
$('span.plupload_upload_status', target).html('Uploaded ' + uploader.total.uploaded + '/' + uploader.files.length + ' files');
if (settings.multiple_queues) {
$('span.plupload_total_status,span.plupload_total_file_size', target).show();
}
} else {
updateList();
$('a.plupload_stop,div.plupload_progress', target).hide();
$('a.plupload_delete', target).css('display', 'block');
if (settings.multiple_queues && uploader.total.uploaded + uploader.total.failed == uploader.files.length) {
$(".plupload_buttons,.plupload_upload_status", target).css("display", "inline");
uploader.disableBrowse(false);
$(".plupload_start", target).addClass("plupload_disabled");
$('span.plupload_total_status,span.plupload_total_file_size', target).hide();
}
}
});
uploader.bind('FilesAdded', updateList);
uploader.bind('FilesRemoved', function() {
// since the whole file list is redrawn for every change in the queue
// we need to scroll back to the file removal point to avoid annoying
// scrolling to the bottom bug (see #926)
var scrollTop = $('#' + id + '_filelist').scrollTop();
updateList();
$('#' + id + '_filelist').scrollTop(scrollTop);
});
uploader.bind('FileUploaded', function(up, file) {
handleStatus(file);
});
uploader.bind("UploadProgress", function(up, file) {
// Set file specific progress
$('#' + file.id + ' div.plupload_file_status', target).html(file.percent + '%');
handleStatus(file);
updateTotalProgress();
});
// Call setup function
if (settings.setup) {
settings.setup(uploader);
}
});
return this;
} else {
// Get uploader instance for specified element
return uploaders[$(this[0]).attr('id')];
}
};
})(jQuery, plupload);
!function(e,t){function i(e){return t.translate(e)||e}function s(t,s){s.contents().each(function(t,i){i=e(i),i.is(".plupload")||i.remove()}),s.prepend('<div class="plupload_wrapper plupload_scroll"><div id="'+t+'_container" class="plupload_container">'+'<div class="plupload">'+'<div class="plupload_header">'+'<div class="plupload_header_content">'+'<div class="plupload_header_title">'+i("Select files")+"</div>"+'<div class="plupload_header_text">'+i("Add files to the upload queue and click the start button.")+"</div>"+"</div>"+"</div>"+'<div class="plupload_content">'+'<div class="plupload_filelist_header">'+'<div class="plupload_file_name">'+i("Filename")+"</div>"+'<div class="plupload_file_action">&nbsp;</div>'+'<div class="plupload_file_status"><span>'+i("Status")+"</span></div>"+'<div class="plupload_file_size">'+i("Size")+"</div>"+'<div class="plupload_clearer">&nbsp;</div>'+"</div>"+'<ul id="'+t+'_filelist" class="plupload_filelist"></ul>'+'<div class="plupload_filelist_footer">'+'<div class="plupload_file_name">'+'<div class="plupload_buttons">'+'<a href="#" class="plupload_button plupload_add" id="'+t+'_browse">'+i("Add Files")+"</a>"+'<a href="#" class="plupload_button plupload_start">'+i("Start Upload")+"</a>"+"</div>"+'<span class="plupload_upload_status"></span>'+"</div>"+'<div class="plupload_file_action"></div>'+'<div class="plupload_file_status"><span class="plupload_total_status">0%</span></div>'+'<div class="plupload_file_size"><span class="plupload_total_file_size">0 b</span></div>'+'<div class="plupload_progress">'+'<div class="plupload_progress_container">'+'<div class="plupload_progress_bar"></div>'+"</div>"+"</div>"+'<div class="plupload_clearer">&nbsp;</div>'+"</div>"+"</div>"+"</div>"+"</div>"+'<input type="hidden" id="'+t+'_count" name="'+t+'_count" value="0" />'+"</div>")}var l={};e.fn.pluploadQueue=function(a){return a?(this.each(function(){function n(i){var s;i.status==t.DONE&&(s="plupload_done"),i.status==t.FAILED&&(s="plupload_failed"),i.status==t.QUEUED&&(s="plupload_delete"),i.status==t.UPLOADING&&(s="plupload_uploading");var l=e("#"+i.id).attr("class",s).find("a").css("display","block");i.hint&&l.attr("title",i.hint)}function o(){e("span.plupload_total_status",p).html(u.total.percent+"%"),e("div.plupload_progress_bar",p).css("width",u.total.percent+"%"),e("span.plupload_upload_status",p).html(t.sprintf(i("Uploaded %d/%d files"),u.total.uploaded,u.files.length))}function r(){var s,l=e("ul.plupload_filelist",p).html(""),a=0;e.each(u.files,function(i,o){s="",o.status==t.DONE&&(o.target_name&&(s+='<input type="hidden" name="'+c+"_"+a+'_tmpname" value="'+t.xmlEncode(o.target_name)+'" />'),s+='<input type="hidden" name="'+c+"_"+a+'_name" value="'+t.xmlEncode(o.name)+'" />',s+='<input type="hidden" name="'+c+"_"+a+'_status" value="'+(o.status==t.DONE?"done":"failed")+'" />',a++,e("#"+c+"_count").val(a)),l.append('<li id="'+o.id+'">'+'<div class="plupload_file_name"><span>'+o.name+"</span></div>"+'<div class="plupload_file_action"><a href="#"></a></div>'+'<div class="plupload_file_status">'+o.percent+"%</div>"+'<div class="plupload_file_size">'+t.formatSize(o.size)+"</div>"+'<div class="plupload_clearer">&nbsp;</div>'+s+"</li>"),n(o),e("#"+o.id+".plupload_delete a").click(function(t){e("#"+o.id).remove(),u.removeFile(o),t.preventDefault()})}),e("span.plupload_total_file_size",p).html(t.formatSize(u.total.size)),0===u.total.queued?e("span.plupload_add_text",p).html(i("Add Files")):e("span.plupload_add_text",p).html(t.sprintf(i("%d files queued"),u.total.queued)),e("a.plupload_start",p).toggleClass("plupload_disabled",u.files.length==u.total.uploaded+u.total.failed),l[0].scrollTop=l[0].scrollHeight,o(),!u.files.length&&u.features.dragdrop&&u.settings.dragdrop&&e("#"+c+"_filelist").append('<li class="plupload_droptext">'+i("Drag files here.")+"</li>")}function d(){delete l[c],u.destroy(),p.html(_),u=p=_=null}var u,p,c,_;p=e(this),c=p.attr("id"),c||(c=t.guid(),p.attr("id",c)),_=p.html(),s(c,p),a=e.extend({dragdrop:!0,browse_button:c+"_browse",container:c},a),a.dragdrop&&(a.drop_element=c+"_filelist"),u=new t.Uploader(a),l[c]=u,u.bind("UploadFile",function(t,i){e("#"+i.id).addClass("plupload_current_file")}),u.bind("Init",function(t,i){!a.unique_names&&a.rename&&p.on("click","#"+c+"_filelist div.plupload_file_name span",function(i){var s,l,a,n=e(i.target),o="",r=n.closest("li");r.hasClass("plupload_delete")&&(s=t.getFile(n.parents("li")[0].id),a=s.name,l=/^(.+)(\.[^.]+)$/.exec(a),l&&(a=l[1],o=l[2]),n.hide().after('<input type="text" />'),n.next().val(a).focus().blur(function(){n.show().next().remove()}).keydown(function(t){var i=e(this);13==t.keyCode&&(t.preventDefault(),s.name=i.val()+o,n.html(s.name),i.blur())}))}),e("#"+c+"_container").attr("title","Using runtime: "+i.runtime),e("a.plupload_start",p).click(function(t){e(this).hasClass("plupload_disabled")||u.start(),t.preventDefault()}),e("a.plupload_stop",p).click(function(e){e.preventDefault(),u.stop()}),e("a.plupload_start",p).addClass("plupload_disabled")}),u.bind("Error",function(s,l){var a,n=l.file;n&&(a=l.message,l.details&&(a+=" ("+l.details+")"),l.code==t.FILE_SIZE_ERROR&&alert(i("Error: File too large:")+" "+n.name),l.code==t.FILE_EXTENSION_ERROR&&alert(i("Error: Invalid file extension:")+" "+n.name),n.hint=a,e("#"+n.id).attr("class","plupload_failed").find("a").css("display","block").attr("title",a)),l.code===t.INIT_ERROR&&setTimeout(function(){d()},1)}),u.bind("PostInit",function(t){t.settings.dragdrop&&t.features.dragdrop&&e("#"+c+"_filelist").append('<li class="plupload_droptext">'+i("Drag files here.")+"</li>")}),u.init(),u.bind("StateChanged",function(){u.state===t.STARTED?(e("li.plupload_delete a,div.plupload_buttons",p).hide(),u.disableBrowse(!0),e("span.plupload_upload_status,div.plupload_progress,a.plupload_stop",p).css("display","block"),e("span.plupload_upload_status",p).html("Uploaded "+u.total.uploaded+"/"+u.files.length+" files"),a.multiple_queues&&e("span.plupload_total_status,span.plupload_total_file_size",p).show()):(r(),e("a.plupload_stop,div.plupload_progress",p).hide(),e("a.plupload_delete",p).css("display","block"),a.multiple_queues&&u.total.uploaded+u.total.failed==u.files.length&&(e(".plupload_buttons,.plupload_upload_status",p).css("display","inline"),u.disableBrowse(!1),e(".plupload_start",p).addClass("plupload_disabled"),e("span.plupload_total_status,span.plupload_total_file_size",p).hide()))}),u.bind("FilesAdded",r),u.bind("FilesRemoved",function(){var t=e("#"+c+"_filelist").scrollTop();r(),e("#"+c+"_filelist").scrollTop(t)}),u.bind("FileUploaded",function(e,t){n(t)}),u.bind("UploadProgress",function(t,i){e("#"+i.id+" div.plupload_file_status",p).html(i.percent+"%"),n(i),o()}),a.setup&&a.setup(u)}),this):l[e(this[0]).attr("id")]}}(jQuery,plupload);
\ No newline at end of file
/*
Plupload
------------------------------------------------------------------- */
.plupload_wrapper * {
box-sizing: content-box;
}
.plupload_button {
cursor: pointer;
outline: none;
}
.plupload_wrapper {
font: normal 11px Verdana,sans-serif;
width: 100%;
min-width: 520px;
line-height: 12px;
}
.plupload_container {
_height: 300px;
min-height: 300px;
position: relative;
}
.plupload_filelist_footer {border-width: 1px 0 0 0}
.plupload_file {border-width: 0 0 1px 0}
.plupload_container .plupload_header {border-width: 0 0 1px 0; position: relative;}
.plupload_delete .ui-icon,
.plupload_done .ui-icon,
.plupload_failed .ui-icon {
cursor:pointer;
}
.plupload_header_content {
height: 56px;
padding: 0 160px 0 60px;
position: relative;
}
.plupload_logo {
width: 40px;
height: 40px;
background: url('../img/plupload.png') no-repeat 0 0;
position: absolute;
top: 8px;
left: 8px;
}
.plupload_header_content_bw .plupload_logo {
background-position: -40px 0;
}
.plupload_header_title {
font: normal 18px sans-serif;
line-height: 19px;
padding: 6px 0 3px;
}
.plupload_header_text {
font: normal 12px sans-serif;
}
.plupload_view_switch {
position: absolute;
right: 16px;
bottom: 8px;
margin: 0;
display: none;
}
.plupload_view_switch .ui-button {
margin-right: -0.31em;
}
.plupload_content {
position: absolute;
top: 86px;
bottom: 44px;
left: 0;
right: 0;
overflow-y: auto;
width: 100%;
}
.plupload_filelist {
border-collapse: collapse;
border-left: none;
border-right: none;
margin: 0;
padding: 0;
width: 100%;
-moz-user-select: none;
-webkit-user-select: none;
user-select: none;
}
.plupload_filelist_content {
padding: 0;
margin: 0;
}
.plupload_cell {padding: 8px 6px;}
.plupload_file {
list-style: none;
display: block;
position: relative;
overflow: hidden;
line-height: 12px;
}
.plupload_file_thumb {
position: relative;
background-image: none;
background-color: #eee;
}
.plupload_thumb_loading {
background: #eee url(../img/loading.gif) center no-repeat;
}
.plupload_thumb_loading .plupload_file_dummy,
.plupload_thumb_embedded .plupload_file_dummy {
display: none;
}
.plupload_file_name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.plupload_filelist_header {
border-top: none;
}
.plupload_filelist_footer {
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
.plupload_buttons {
position: relative;
}
/* list view */
.plupload_view_list .plupload_file {
border-left: none;
border-right: none;
border-top: none;
height: 29px;
width: 100% !important;
/* fix IE6 vertical white-space bug */
_float: left;
_clear: left;
}
.plupload_view_list div.plupload_file_size,
.plupload_view_list div.plupload_file_status,
.plupload_view_list div.plupload_file_action {
padding: 8px 6px;
position: absolute;
top: 0;
right: 0;
}
.plupload_view_list div.plupload_file_name {
margin-right: 156px;
padding: 8px 6px;
_width: 75%;
}
.plupload_view_list div.plupload_file_size {
right: 28px;
}
.plupload_view_list div.plupload_file_status {
right: 82px;
}
.plupload_view_list .plupload_file_rename {
margin-left: -2px;
}
.plupload_view_list .plupload_file_size,
.plupload_view_list .plupload_file_status,
.plupload_filelist_footer .plupload_file_size,
.plupload_filelist_footer .plupload_file_status {
text-align: right;
width: 52px;
}
.plupload_view_list .plupload_file_thumb {
position: absolute;
top: -999px;
}
.plupload_view_list .plupload_file_progress {
display: none;
}
/* thumbs view */
.plupload_view_thumbs .plupload_content {
top: 57px;
}
.plupload_view_thumbs .plupload_filelist_header {
display: none;
}
.plupload_view_thumbs .plupload_file {
padding: 6px;
margin: 10px;
border: 1px solid #fff;
float: left;
}
.plupload_view_thumbs .plupload_file_thumb,
.plupload_view_thumbs .plupload_file_dummy {
text-align: center;
overflow: hidden;
}
.plupload_view_thumbs .plupload_file_dummy {
font-size: 21px;
font-weight: bold;
text-transform: lowercase;
overflow: hidden;
border: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.plupload_view_thumbs div.plupload_file_action {
position: absolute;
top: 0;
right: 0;
}
.plupload_view_thumbs div.plupload_file_name {
padding: 0;
font-weight: bold;
}
.plupload_view_thumbs .plupload_file_rename {
padding: 1px 0;
width: 100% !important;
}
.plupload_view_thumbs div.plupload_file_size {
font-size: 0.8em;
font-weight: normal;
}
.plupload_view_thumbs div.plupload_file_status {
position: relative;
height: 3px;
overflow: hidden;
text-indent: -999px;
margin-bottom: 3px;
}
.plupload_view_thumbs div.plupload_file_progress {
border: none;
height: 100%;
}
.plupload .ui-sortable-helper,
.plupload .ui-sortable .plupload_file {
cursor:move;
}
.plupload_file_action {width: 16px;}
.plupload_file_name {
overflow: hidden;
padding-left: 10px;
}
.plupload_file_rename {
border: none;
font: normal 11px Verdana, sans-serif;
padding: 1px 2px;
line-height: 11px;
height: 11px;
}
.plupload_progress {width: 60px;}
.plupload_progress_container {padding: 1px;}
/* Floats */
.plupload_right {float: right;}
.plupload_left {float: left;}
.plupload_clear,.plupload_clearer {clear: both;}
.plupload_clearer, .plupload_progress_bar {
display: block;
font-size: 0;
line-height: 0;
}
.plupload_clearer {height: 0;}
/* Misc */
.plupload_hidden {display: none !important;}
.plupload_droptext {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: transparent;
text-align: center;
vertical-align: middle;
border: 0;
line-height: 160px;
display: none;
}
.plupload_dropbox .plupload_droptext {
display: block;
}
.plupload_files_queued .plupload_droptext {
display: none;
}
.plupload_buttons, .plupload_upload_status {float: left}
.plupload_message {
position: absolute;
top: -1px;
left: -1px;
height: 100%;
width: 100%;
}
.plupload_message p {
padding:0.7em;
margin:0;
}
.plupload_message strong {
font-weight: bold;
}
.plupload_message i {
font-style: italic;
}
.plupload_message p span.ui-icon {
float: left;
margin-right: 0.3em;
}
.plupload_header_content .ui-state-error,
.plupload_header_content .ui-state-highlight {
border:none;
}
.plupload_message_close {
position:absolute;
top:5px;
right:5px;
cursor:pointer;
}
.plupload .ui-sortable-placeholder {
height:35px;
}
/**
* jquery.ui.plupload.js
*
* Copyright 2013, Moxiecode Systems AB
* Released under GPL License.
*
* License: http://www.plupload.com/license
* Contributing: http://www.plupload.com/contributing
*
* Depends:
* jquery.ui.core.js
* jquery.ui.widget.js
* jquery.ui.button.js
* jquery.ui.progressbar.js
*
* Optionally:
* jquery.ui.sortable.js
*/
/* global jQuery:true */
/**
jQuery UI based implementation of the Plupload API - multi-runtime file uploading API.
To use the widget you must include _jQuery_ and _jQuery UI_ bundle (including `ui.core`, `ui.widget`, `ui.button`,
`ui.progressbar` and `ui.sortable`).
In general the widget is designed the way that you do not usually need to do anything to it after you instantiate it.
But! You still can intervenue, to some extent, in case you need to. Although, due to the fact that widget is based on
_jQuery UI_ widget factory, there are some specifics. See examples below for more details.
@example
<!-- Instantiating: -->
<div id="uploader">
<p>Your browser doesn't have Flash, Silverlight or HTML5 support.</p>
</div>
<script>
$('#uploader').plupload({
url : '../upload.php',
filters : [
{title : "Image files", extensions : "jpg,gif,png"}
],
rename: true,
sortable: true,
flash_swf_url : '../../js/Moxie.swf',
silverlight_xap_url : '../../js/Moxie.xap',
});
</script>
@example
// Invoking methods:
$('#uploader').plupload(options);
// Display welcome message in the notification area
$('#uploader').plupload('notify', 'info', "This might be obvious, but you need to click 'Add Files' to add some files.");
@example
// Subscribing to the events...
// ... on initialization:
$('#uploader').plupload({
...
viewchanged: function(event, args) {
// stuff ...
}
});
// ... or after initialization
$('#uploader').on("viewchanged", function(event, args) {
// stuff ...
});
@class UI.Plupload
@constructor
@param {Object} settings For detailed information about each option check documentation.
@param {String} settings.url URL of the server-side upload handler.
@param {Number|String} [settings.chunk_size=0] Chunk size in bytes to slice the file into. Shorcuts with b, kb, mb, gb, tb suffixes also supported. `e.g. 204800 or "204800b" or "200kb"`. By default - disabled.
@param {String} [settings.file_data_name="file"] Name for the file field in Multipart formated message.
@param {Object} [settings.filters={}] Set of file type filters.
@param {Array} [settings.filters.mime_types=[]] List of file types to accept, each one defined by title and list of extensions. `e.g. {title : "Image files", extensions : "jpg,jpeg,gif,png"}`. Dispatches `plupload.FILE_EXTENSION_ERROR`
@param {String|Number} [settings.filters.max_file_size=0] Maximum file size that the user can pick, in bytes. Optionally supports b, kb, mb, gb, tb suffixes. `e.g. "10mb" or "1gb"`. By default - not set. Dispatches `plupload.FILE_SIZE_ERROR`.
@param {Boolean} [settings.filters.prevent_duplicates=false] Do not let duplicates into the queue. Dispatches `plupload.FILE_DUPLICATE_ERROR`.
@param {Number} [settings.filters.max_file_count=0] Limit the number of files that can reside in the queue at the same time (default is 0 - no limit).
@param {String} [settings.flash_swf_url] URL of the Flash swf.
@param {Object} [settings.headers] Custom headers to send with the upload. Hash of name/value pairs.
@param {Number|String} [settings.max_file_size] Maximum file size that the user can pick, in bytes. Optionally supports b, kb, mb, gb, tb suffixes. `e.g. "10mb" or "1gb"`. By default - not set. Dispatches `plupload.FILE_SIZE_ERROR`.
@param {Number} [settings.max_retries=0] How many times to retry the chunk or file, before triggering Error event.
@param {Boolean} [settings.multipart=true] Whether to send file and additional parameters as Multipart formated message.
@param {Object} [settings.multipart_params] Hash of key/value pairs to send with every file upload.
@param {Boolean} [settings.multi_selection=true] Enable ability to select multiple files at once in file dialog.
@param {Boolean} [settings.prevent_duplicates=false] Do not let duplicates into the queue. Dispatches `plupload.FILE_DUPLICATE_ERROR`.
@param {String|Object} [settings.required_features] Either comma-separated list or hash of required features that chosen runtime should absolutely possess.
@param {Object} [settings.resize] Enable resizng of images on client-side. Applies to `image/jpeg` and `image/png` only. `e.g. {width : 200, height : 200, quality : 90, crop: true}`
@param {Number} [settings.resize.width] If image is bigger, it will be resized.
@param {Number} [settings.resize.height] If image is bigger, it will be resized.
@param {Number} [settings.resize.quality=90] Compression quality for jpegs (1-100).
@param {Boolean} [settings.resize.crop=false] Whether to crop images to exact dimensions. By default they will be resized proportionally.
@param {String} [settings.runtimes="html5,flash,silverlight,html4"] Comma separated list of runtimes, that Plupload will try in turn, moving to the next if previous fails.
@param {String} [settings.silverlight_xap_url] URL of the Silverlight xap.
@param {Boolean} [settings.unique_names=false] If true will generate unique filenames for uploaded files.
@param {Boolean} [settings.autostart=false] Whether to auto start uploading right after file selection.
@param {Boolean} [settings.dragdrop=true] Enable ability to add file to the queue by drag'n'dropping them from the desktop.
@param {Boolean} [settings.rename=false] Enable ability to rename files in the queue.
@param {Boolean} [settings.sortable=false] Enable ability to sort files in the queue, changing their uploading priority.
@param {Object} [settings.buttons] Control the visibility of functional buttons.
@param {Boolean} [settings.buttons.browse=true] Display browse button.
@param {Boolean} [settings.buttons.start=true] Display start button.
@param {Boolean} [settings.buttons.stop=true] Display stop button.
@param {Object} [settings.views] Control various views of the file queue.
@param {Boolean} [settings.views.list=true] Enable list view.
@param {Boolean} [settings.views.thumbs=false] Enable thumbs view.
@param {String} [settings.views.default='list'] Default view.
@param {Boolean} [settings.views.remember=true] Whether to remember the current view (requires jQuery Cookie plugin).
@param {Boolean} [settings.multiple_queues=true] Re-activate the widget after each upload procedure.
*/
;(function(window, document, plupload, o, $) {
/**
Dispatched when the widget is initialized and ready.
@event ready
@param {plupload.Uploader} uploader Uploader instance sending the event.
*/
/**
Dispatched when file dialog is closed.
@event selected
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {Array} files Array of selected files represented by plupload.File objects
*/
/**
Dispatched when file dialog is closed.
@event removed
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {Array} files Array of removed files represented by plupload.File objects
*/
/**
Dispatched when upload is started.
@event started
@param {plupload.Uploader} uploader Uploader instance sending the event.
*/
/**
Dispatched when upload is stopped.
@event stopped
@param {plupload.Uploader} uploader Uploader instance sending the event.
*/
/**
Dispatched during the upload process.
@event progress
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {plupload.File} file File that is being uploaded (includes loaded and percent properties among others).
@param {Number} size Total file size in bytes.
@param {Number} loaded Number of bytes uploaded of the files total size.
@param {Number} percent Number of percentage uploaded of the file.
*/
/**
Dispatched when file is uploaded.
@event uploaded
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {plupload.File} file File that was uploaded.
@param {Enum} status Status constant matching the plupload states QUEUED, UPLOADING, FAILED, DONE.
*/
/**
Dispatched when upload of the whole queue is complete.
@event complete
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {Array} files Array of uploaded files represented by plupload.File objects
*/
/**
Dispatched when the view is changed, e.g. from `list` to `thumbs` or vice versa.
@event viewchanged
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {String} type Current view type.
*/
/**
Dispatched when error of some kind is detected.
@event error
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {String} error Error message.
@param {plupload.File} file File that was uploaded.
@param {Enum} status Status constant matching the plupload states QUEUED, UPLOADING, FAILED, DONE.
*/
var uploaders = {};
function _(str) {
return plupload.translate(str) || str;
}
function renderUI(obj) {
obj.id = obj.attr('id');
obj.html(
'<div class="plupload_wrapper">' +
'<div class="ui-widget-content plupload_container">' +
'<div class="ui-state-default ui-widget-header plupload_header">' +
'<div class="plupload_header_content">' +
'<div class="plupload_logo"> </div>' +
'<div class="plupload_header_title">' + _("Select files") + '</div>' +
'<div class="plupload_header_text">' + _("Add files to the upload queue and click the start button.") + '</div>' +
'<div class="plupload_view_switch">' +
'<input type="radio" id="'+obj.id+'_view_list" name="view_mode_'+obj.id+'" checked="checked" /><label class="plupload_button" for="'+obj.id+'_view_list" data-view="list">' + _('List') + '</label>' +
'<input type="radio" id="'+obj.id+'_view_thumbs" name="view_mode_'+obj.id+'" /><label class="plupload_button" for="'+obj.id+'_view_thumbs" data-view="thumbs">' + _('Thumbnails') + '</label>' +
'</div>' +
'</div>' +
'</div>' +
'<table class="plupload_filelist plupload_filelist_header ui-widget-header">' +
'<tr>' +
'<td class="plupload_cell plupload_file_name">' + _('Filename') + '</td>' +
'<td class="plupload_cell plupload_file_status">' + _('Status') + '</td>' +
'<td class="plupload_cell plupload_file_size">' + _('Size') + '</td>' +
'<td class="plupload_cell plupload_file_action">&nbsp;</td>' +
'</tr>' +
'</table>' +
'<div class="plupload_content">' +
'<div class="plupload_droptext">' + _("Drag files here.") + '</div>' +
'<ul class="plupload_filelist_content"> </ul>' +
'<div class="plupload_clearer">&nbsp;</div>' +
'</div>' +
'<table class="plupload_filelist plupload_filelist_footer ui-widget-header">' +
'<tr>' +
'<td class="plupload_cell plupload_file_name">' +
'<div class="plupload_buttons"><!-- Visible -->' +
'<a class="plupload_button plupload_add">' + _("Add Files") + '</a>&nbsp;' +
'<a class="plupload_button plupload_start">' + _("Start Upload") + '</a>&nbsp;' +
'<a class="plupload_button plupload_stop plupload_hidden">'+_("Stop Upload") + '</a>&nbsp;' +
'</div>' +
'<div class="plupload_started plupload_hidden"><!-- Hidden -->' +
'<div class="plupload_progress plupload_right">' +
'<div class="plupload_progress_container"></div>' +
'</div>' +
'<div class="plupload_cell plupload_upload_status"></div>' +
'<div class="plupload_clearer">&nbsp;</div>' +
'</div>' +
'</td>' +
'<td class="plupload_file_status"><span class="plupload_total_status">0%</span></td>' +
'<td class="plupload_file_size"><span class="plupload_total_file_size">0 kb</span></td>' +
'<td class="plupload_file_action"></td>' +
'</tr>' +
'</table>' +
'</div>' +
'<input class="plupload_count" value="0" type="hidden">' +
'</div>'
);
}
$.widget("ui.plupload", {
widgetEventPrefix: '',
contents_bak: '',
options: {
browse_button_hover: 'ui-state-hover',
browse_button_active: 'ui-state-active',
filters: {},
// widget specific
buttons: {
browse: true,
start: true,
stop: true
},
views: {
list: true,
thumbs: false,
active: 'list',
remember: true // requires: https://github.com/carhartl/jquery-cookie, otherwise disabled even if set to true
},
thumb_width: 100,
thumb_height: 60,
multiple_queues: true, // re-use widget by default
dragdrop : true,
autostart: false,
sortable: false,
rename: false
},
FILE_COUNT_ERROR: -9001,
_create: function() {
var id = this.element.attr('id');
if (!id) {
id = plupload.guid();
this.element.attr('id', id);
}
this.id = id;
// backup the elements initial state
this.contents_bak = this.element.html();
renderUI(this.element);
// container, just in case
this.container = $('.plupload_container', this.element).attr('id', id + '_container');
this.content = $('.plupload_content', this.element);
if ($.fn.resizable) {
this.container.resizable({
handles: 's',
minHeight: 300
});
}
// list of files, may become sortable
this.filelist = $('.plupload_filelist_content', this.container)
.attr({
id: id + '_filelist',
unselectable: 'on'
});
// buttons
this.browse_button = $('.plupload_add', this.container).attr('id', id + '_browse');
this.start_button = $('.plupload_start', this.container).attr('id', id + '_start');
this.stop_button = $('.plupload_stop', this.container).attr('id', id + '_stop');
this.thumbs_switcher = $('#' + id + '_view_thumbs');
this.list_switcher = $('#' + id + '_view_list');
if ($.ui.button) {
this.browse_button.button({
icons: { primary: 'ui-icon-circle-plus' },
disabled: true
});
this.start_button.button({
icons: { primary: 'ui-icon-circle-arrow-e' },
disabled: true
});
this.stop_button.button({
icons: { primary: 'ui-icon-circle-close' }
});
this.list_switcher.button({
text: false,
icons: { secondary: "ui-icon-grip-dotted-horizontal" }
});
this.thumbs_switcher.button({
text: false,
icons: { secondary: "ui-icon-image" }
});
}
// progressbar
this.progressbar = $('.plupload_progress_container', this.container);
if ($.ui.progressbar) {
this.progressbar.progressbar();
}
// counter
this.counter = $('.plupload_count', this.element)
.attr({
id: id + '_count',
name: id + '_count'
});
// initialize uploader instance
this._initUploader();
},
_initUploader: function() {
var self = this
, id = this.id
, uploader
, options = {
container: id + '_buttons',
browse_button: id + '_browse'
}
;
$('.plupload_buttons', this.element).attr('id', id + '_buttons');
if (self.options.dragdrop) {
this.filelist.parent().attr('id', this.id + '_dropbox');
options.drop_element = this.id + '_dropbox';
}
this.filelist.on('click', function(e) {
var me = $(e.target), fileContainer;
if (me.hasClass('plupload_action_icon')) {
fileContainer = me.closest('.plupload_file');
if (fileContainer.hasClass('plupload_delete')) {
self.removeFile(fileContainer.attr('id'));
e.preventDefault();
}
}
});
uploader = this.uploader = uploaders[id] = new plupload.Uploader($.extend(this.options, options));
// retrieve full normalized set of options
this.options = uploader.getOption();
if (self.options.views.thumbs) {
uploader.settings.required_features.display_media = true;
}
// for backward compatibility
if (self.options.max_file_count) {
plupload.extend(uploader.getOption('filters'), {
max_file_count: self.options.max_file_count
});
}
plupload.addFileFilter('max_file_count', function(maxCount, file, cb) {
if (maxCount <= this.files.length - (this.total.uploaded + this.total.failed)) {
self.browse_button.button('disable');
this.disableBrowse();
this.trigger('Error', {
code : self.FILE_COUNT_ERROR,
message : _("File count error."),
file : file
});
cb(false);
} else {
cb(true);
}
});
uploader.bind('Error', function(up, err) {
var message, details = "";
message = '<strong>' + err.message + '</strong>';
switch (err.code) {
case plupload.FILE_EXTENSION_ERROR:
details = plupload.sprintf(_("File: %s"), err.file.name);
break;
case plupload.FILE_SIZE_ERROR:
details = plupload.sprintf(_("File: %s, size: %d, max file size: %d"), err.file.name, plupload.formatSize(err.file.size), plupload.formatSize(plupload.parseSize(up.getOption('filters').max_file_size)));
break;
case plupload.FILE_DUPLICATE_ERROR:
details = plupload.sprintf(_("%s already present in the queue."), err.file.name);
break;
case self.FILE_COUNT_ERROR:
details = plupload.sprintf(_("Upload element accepts only %d file(s) at a time. Extra files were stripped."), up.getOption('filters').max_file_count || 0);
break;
case plupload.IMAGE_FORMAT_ERROR :
details = _("Image format either wrong or not supported.");
break;
case plupload.IMAGE_MEMORY_ERROR :
details = _("Runtime ran out of available memory.");
break;
/* // This needs a review
case plupload.IMAGE_DIMENSIONS_ERROR :
details = plupload.sprintf(_('Resoultion out of boundaries! <b>%s</b> runtime supports images only up to %wx%hpx.'), up.runtime, up.features.maxWidth, up.features.maxHeight);
break; */
case plupload.HTTP_ERROR:
details = _("Upload URL might be wrong or doesn't exist.");
break;
}
message += " <br /><i>" + details + "</i>";
self._trigger('error', null, { up: up, error: err } );
// do not show UI if no runtime can be initialized
if (err.code === plupload.INIT_ERROR) {
setTimeout(function() {
self.destroy();
}, 1);
} else {
self.notify('error', message);
}
});
uploader.bind('PostInit', function(up) {
// all buttons are optional, so they can be disabled and hidden
if (!self.options.buttons.browse) {
self.browse_button.button('disable').hide();
up.disableBrowse(true);
} else {
self.browse_button.button('enable');
}
if (!self.options.buttons.start) {
self.start_button.button('disable').hide();
}
if (!self.options.buttons.stop) {
self.stop_button.button('disable').hide();
}
if (!self.options.unique_names && self.options.rename) {
self._enableRenaming();
}
if (self.options.dragdrop && up.features.dragdrop) {
self.filelist.parent().addClass('plupload_dropbox');
}
self._enableViewSwitcher();
self.start_button.click(function(e) {
if (!$(this).button('option', 'disabled')) {
self.start();
}
e.preventDefault();
});
self.stop_button.click(function(e) {
self.stop();
e.preventDefault();
});
self._trigger('ready', null, { up: up });
});
// uploader internal events must run first
uploader.init();
uploader.bind('FileFiltered', function(up, file) {
self._addFiles(file);
});
uploader.bind('FilesAdded', function(up, files) {
self._trigger('selected', null, { up: up, files: files } );
// re-enable sortable
if (self.options.sortable && $.ui.sortable) {
self._enableSortingList();
}
self._trigger('updatelist', null, { filelist: self.filelist });
if (self.options.autostart) {
// set a little delay to make sure that QueueChanged triggered by the core has time to complete
setTimeout(function() {
self.start();
}, 10);
}
});
uploader.bind('FilesRemoved', function(up, files) {
// destroy sortable if enabled
if ($.ui.sortable && self.options.sortable) {
$('tbody', self.filelist).sortable('destroy');
}
$.each(files, function(i, file) {
$('#' + file.id).toggle("highlight", function() {
$(this).remove();
});
});
if (up.files.length) {
// re-initialize sortable
if (self.options.sortable && $.ui.sortable) {
self._enableSortingList();
}
}
self._trigger('updatelist', null, { filelist: self.filelist });
self._trigger('removed', null, { up: up, files: files } );
});
uploader.bind('QueueChanged', function() {
self._handleState();
});
uploader.bind('StateChanged', function(up) {
self._handleState();
if (plupload.STARTED === up.state) {
self._trigger('started', null, { up: this.uploader });
} else if (plupload.STOPPED === up.state) {
self._trigger('stopped', null, { up: this.uploader });
}
});
uploader.bind('UploadFile', function(up, file) {
self._handleFileStatus(file);
});
uploader.bind('FileUploaded', function(up, file, result) {
self._handleFileStatus(file);
self._trigger('uploaded', null, { up: up, file: file, result: result } );
});
uploader.bind('UploadProgress', function(up, file) {
self._handleFileStatus(file);
self._updateTotalProgress();
self._trigger('progress', null, { up: up, file: file } );
});
uploader.bind('UploadComplete', function(up, files) {
self._addFormFields();
self._trigger('complete', null, { up: up, files: files } );
});
},
_setOption: function(key, value) {
var self = this;
if (key == 'buttons' && typeof(value) == 'object') {
value = $.extend(self.options.buttons, value);
if (!value.browse) {
self.browse_button.button('disable').hide();
self.uploader.disableBrowse(true);
} else {
self.browse_button.button('enable').show();
self.uploader.disableBrowse(false);
}
if (!value.start) {
self.start_button.button('disable').hide();
} else {
self.start_button.button('enable').show();
}
if (!value.stop) {
self.stop_button.button('disable').hide();
} else {
self.start_button.button('enable').show();
}
}
self.uploader.setOption(key, value);
},
/**
Start upload. Triggers `start` event.
@method start
*/
start: function() {
this.uploader.start();
},
/**
Stop upload. Triggers `stop` event.
@method stop
*/
stop: function() {
this.uploader.stop();
},
/**
Enable browse button.
@method enable
*/
enable: function() {
this.browse_button.button('enable');
this.uploader.disableBrowse(false);
},
/**
Disable browse button.
@method disable
*/
disable: function() {
this.browse_button.button('disable');
this.uploader.disableBrowse(true);
},
/**
Retrieve file by its unique id.
@method getFile
@param {String} id Unique id of the file
@return {plupload.File}
*/
getFile: function(id) {
var file;
if (typeof id === 'number') {
file = this.uploader.files[id];
} else {
file = this.uploader.getFile(id);
}
return file;
},
/**
Return array of files currently in the queue.
@method getFiles
@return {Array} Array of files in the queue represented by plupload.File objects
*/
getFiles: function() {
return this.uploader.files;
},
/**
Remove the file from the queue.
@method removeFile
@param {plupload.File|String} file File to remove, might be specified directly or by its unique id
*/
removeFile: function(file) {
if (plupload.typeOf(file) === 'string') {
file = this.getFile(file);
}
this.uploader.removeFile(file);
},
/**
Clear the file queue.
@method clearQueue
*/
clearQueue: function() {
this.uploader.splice();
},
/**
Retrieve internal plupload.Uploader object (usually not required).
@method getUploader
@return {plupload.Uploader}
*/
getUploader: function() {
return this.uploader;
},
/**
Trigger refresh procedure, specifically browse_button re-measure and re-position operations.
Might get handy, when UI Widget is placed within the popup, that is constantly hidden and shown
again - without calling this method after each show operation, dialog trigger might get displaced
and disfunctional.
@method refresh
*/
refresh: function() {
this.uploader.refresh();
},
/**
Display a message in notification area.
@method notify
@param {Enum} type Type of the message, either `error` or `info`
@param {String} message The text message to display.
*/
notify: function(type, message) {
var popup = $(
'<div class="plupload_message">' +
'<span class="plupload_message_close ui-icon ui-icon-circle-close" title="'+_('Close')+'"></span>' +
'<p><span class="ui-icon"></span>' + message + '</p>' +
'</div>'
);
popup
.addClass('ui-state-' + (type === 'error' ? 'error' : 'highlight'))
.find('p .ui-icon')
.addClass('ui-icon-' + (type === 'error' ? 'alert' : 'info'))
.end()
.find('.plupload_message_close')
.click(function() {
popup.remove();
})
.end();
$('.plupload_header', this.container).append(popup);
},
/**
Destroy the widget, the uploader, free associated resources and bring back original html.
@method destroy
*/
destroy: function() {
// destroy uploader instance
this.uploader.destroy();
// unbind all button events
$('.plupload_button', this.element).unbind();
// destroy buttons
if ($.ui.button) {
$('.plupload_add, .plupload_start, .plupload_stop', this.container)
.button('destroy');
}
// destroy progressbar
if ($.ui.progressbar) {
this.progressbar.progressbar('destroy');
}
// destroy sortable behavior
if ($.ui.sortable && this.options.sortable) {
$('tbody', this.filelist).sortable('destroy');
}
// restore the elements initial state
this.element
.empty()
.html(this.contents_bak);
this.contents_bak = '';
$.Widget.prototype.destroy.apply(this);
},
_handleState: function() {
var up = this.uploader
, filesPending = up.files.length - (up.total.uploaded + up.total.failed)
, maxCount = up.getOption('filters').max_file_count || 0
;
if (plupload.STARTED === up.state) {
$([])
.add(this.stop_button)
.add('.plupload_started')
.removeClass('plupload_hidden');
this.start_button.button('disable');
if (!this.options.multiple_queues) {
this.browse_button.button('disable');
up.disableBrowse();
}
$('.plupload_upload_status', this.element).html(plupload.sprintf(_('Uploaded %d/%d files'), up.total.uploaded, up.files.length));
$('.plupload_header_content', this.element).addClass('plupload_header_content_bw');
}
else if (plupload.STOPPED === up.state) {
$([])
.add(this.stop_button)
.add('.plupload_started')
.addClass('plupload_hidden');
if (filesPending) {
this.start_button.button('enable');
} else {
this.start_button.button('disable');
}
if (this.options.multiple_queues) {
$('.plupload_header_content', this.element).removeClass('plupload_header_content_bw');
}
// if max_file_count defined, only that many files can be queued at once
if (this.options.multiple_queues && maxCount && maxCount > filesPending) {
this.browse_button.button('enable');
up.disableBrowse(false);
}
this._updateTotalProgress();
}
if (up.total.queued === 0) {
$('.ui-button-text', this.browse_button).html(_('Add Files'));
} else {
$('.ui-button-text', this.browse_button).html(plupload.sprintf(_('%d files queued'), up.total.queued));
}
// have a helper class on a container expressing whether it has files queued or not
this.container.toggleClass('plupload_files_queued', up.files.length);
up.refresh();
},
_handleFileStatus: function(file) {
var $file = $('#' + file.id), actionClass, iconClass;
// since this method might be called asynchronously, file row might not yet be rendered
if (!$file.length) {
return;
}
switch (file.status) {
case plupload.DONE:
actionClass = 'plupload_done';
iconClass = 'plupload_action_icon ui-icon ui-icon-circle-check';
break;
case plupload.FAILED:
actionClass = 'ui-state-error plupload_failed';
iconClass = 'plupload_action_icon ui-icon ui-icon-alert';
break;
case plupload.QUEUED:
actionClass = 'plupload_delete';
iconClass = 'plupload_action_icon ui-icon ui-icon-circle-minus';
break;
case plupload.UPLOADING:
actionClass = 'ui-state-highlight plupload_uploading';
iconClass = 'plupload_action_icon ui-icon ui-icon-circle-arrow-w';
// scroll uploading file into the view if its bottom boundary is out of it
var scroller = $('.plupload_scroll', this.container)
, scrollTop = scroller.scrollTop()
, scrollerHeight = scroller.height()
, rowOffset = $file.position().top + $file.height()
;
if (scrollerHeight < rowOffset) {
scroller.scrollTop(scrollTop + rowOffset - scrollerHeight);
}
// Set file specific progress
$file
.find('.plupload_file_percent')
.html(file.percent + '%')
.end()
.find('.plupload_file_progress')
.css('width', file.percent + '%')
.end()
.find('.plupload_file_size')
.html(plupload.formatSize(file.size));
break;
}
actionClass += ' ui-state-default plupload_file';
$file
.attr('class', actionClass)
.find('.plupload_action_icon')
.attr('class', iconClass);
},
_updateTotalProgress: function() {
var up = this.uploader;
// Scroll to end of file list
this.filelist[0].scrollTop = this.filelist[0].scrollHeight;
this.progressbar.progressbar('value', up.total.percent);
this.element
.find('.plupload_total_status')
.html(up.total.percent + '%')
.end()
.find('.plupload_total_file_size')
.html(plupload.formatSize(up.total.size))
.end()
.find('.plupload_upload_status')
.html(plupload.sprintf(_('Uploaded %d/%d files'), up.total.uploaded, up.files.length));
},
_displayThumbs: function() {
var self = this
, tw, th // thumb width/height
, cols
, num = 0 // number of simultaneously visible thumbs
, thumbs = [] // array of thumbs to preload at any given moment
, loading = false
;
if (!this.options.views.thumbs) {
return;
}
function onLast(el, eventName, cb) {
var timer;
el.on(eventName, function() {
clearTimeout(timer);
timer = setTimeout(function() {
clearTimeout(timer);
cb();
}, 300);
});
}
// calculate number of simultaneously visible thumbs
function measure() {
if (!tw || !th) {
var wrapper = $('.plupload_file:eq(0)', self.filelist);
tw = wrapper.outerWidth(true);
th = wrapper.outerHeight(true);
}
var aw = self.content.width(), ah = self.content.height();
cols = Math.floor(aw / tw);
num = cols * (Math.ceil(ah / th) + 1);
}
function pickThumbsToLoad() {
// calculate index of virst visible thumb
var startIdx = Math.floor(self.content.scrollTop() / th) * cols;
// get potentially visible thumbs that are not yet visible
thumbs = $('.plupload_file .plupload_file_thumb', self.filelist)
.slice(startIdx, startIdx + num)
.filter('.plupload_thumb_toload')
.get();
}
function init() {
function mpl() { // measure, pick, load
if (self.view_mode !== 'thumbs') {
return;
}
measure();
pickThumbsToLoad();
lazyLoad();
}
if ($.fn.resizable) {
onLast(self.container, 'resize', mpl);
}
onLast(self.window, 'resize', mpl);
onLast(self.content, 'scroll', mpl);
self.element.on('viewchanged selected', mpl);
mpl();
}
function preloadThumb(file, cb) {
var img = new o.image.Image();
var resolveUrl = o.core.utils.Url.resolveUrl;
img.onload = function() {
var thumb = $('#' + file.id + ' .plupload_file_thumb', self.filelist);
this.embed(thumb[0], {
width: self.options.thumb_width,
height: self.options.thumb_height,
crop: true,
fit: true,
preserveHeaders: false,
swf_url: resolveUrl(self.options.flash_swf_url),
xap_url: resolveUrl(self.options.silverlight_xap_url)
});
};
img.bind("embedded error", function(e) {
$('#' + file.id, self.filelist)
.find('.plupload_file_thumb')
.removeClass('plupload_thumb_loading')
.addClass('plupload_thumb_' + e.type)
;
this.destroy();
setTimeout(cb, 1); // detach, otherwise ui might hang (in SilverLight for example)
});
$('#' + file.id, self.filelist)
.find('.plupload_file_thumb')
.removeClass('plupload_thumb_toload')
.addClass('plupload_thumb_loading')
;
img.load(file.getSource());
}
function lazyLoad() {
if (self.view_mode !== 'thumbs' || loading) {
return;
}
pickThumbsToLoad();
if (!thumbs.length) {
return;
}
loading = true;
preloadThumb(self.getFile($(thumbs.shift()).closest('.plupload_file').attr('id')), function() {
loading = false;
lazyLoad();
});
}
// this has to run only once to measure structures and bind listeners
this.element.on('selected', function onselected() {
self.element.off('selected', onselected);
init();
});
},
_addFiles: function(files) {
var self = this, file_html, html = '';
file_html = '<li class="plupload_file ui-state-default plupload_delete" id="{id}" style="width:{thumb_width}px;">' +
'<div class="plupload_file_thumb plupload_thumb_toload" style="width: {thumb_width}px; height: {thumb_height}px;">' +
'<div class="plupload_file_dummy ui-widget-content" style="line-height: {thumb_height}px;"><span class="ui-state-disabled">{ext} </span></div>' +
'</div>' +
'<div class="plupload_file_status">' +
'<div class="plupload_file_progress ui-widget-header" style="width: 0%"> </div>' +
'<span class="plupload_file_percent">{percent} </span>' +
'</div>' +
'<div class="plupload_file_name" title="{name}">' +
'<span class="plupload_file_name_wrapper">{name} </span>' +
'</div>' +
'<div class="plupload_file_action">' +
'<div class="plupload_action_icon ui-icon ui-icon-circle-minus"> </div>' +
'</div>' +
'<div class="plupload_file_size">{size} </div>' +
'<div class="plupload_file_fields"> </div>' +
'</li>';
if (plupload.typeOf(files) !== 'array') {
files = [files];
}
$.each(files, function(i, file) {
var ext = o.core.utils.Mime.getFileExtension(file.name) || 'none';
html += file_html.replace(/\{(\w+)\}/g, function($0, $1) {
switch ($1) {
case 'thumb_width':
case 'thumb_height':
return self.options[$1];
case 'size':
return plupload.formatSize(file.size);
case 'ext':
return ext;
default:
return file[$1] || '';
}
});
});
self.filelist.append(html);
},
_addFormFields: function() {
var self = this;
// re-add from fresh
$('.plupload_file_fields', this.filelist).html('');
plupload.each(this.uploader.files, function(file, count) {
var fields = ''
, id = self.id + '_' + count
;
if (file.target_name) {
fields += '<input type="hidden" name="' + id + '_tmpname" value="'+plupload.xmlEncode(file.target_name)+'" />';
}
fields += '<input type="hidden" name="' + id + '_name" value="'+plupload.xmlEncode(file.name)+'" />';
fields += '<input type="hidden" name="' + id + '_status" value="' + (file.status === plupload.DONE ? 'done' : 'failed') + '" />';
$('#' + file.id).find('.plupload_file_fields').html(fields);
});
this.counter.val(this.uploader.files.length);
},
_viewChanged: function(view) {
// update or write a new cookie
if (this.options.views.remember && $.cookie) {
$.cookie('plupload_ui_view', view, { expires: 7, path: '/' });
}
// ugly fix for IE6 - make content area stretchable
if (plupload.ua.browser === 'IE' && plupload.ua.version < 7) {
this.content.attr('style', 'height:expression(document.getElementById("' + this.id + '_container' + '").clientHeight - ' + (view === 'list' ? 132 : 102) + ')');
}
this.container.removeClass('plupload_view_list plupload_view_thumbs').addClass('plupload_view_' + view);
this.view_mode = view;
this._trigger('viewchanged', null, { view: view });
},
_enableViewSwitcher: function() {
var self = this
, view
, switcher = $('.plupload_view_switch', this.container)
, buttons
, button
;
plupload.each(['list', 'thumbs'], function(view) {
if (!self.options.views[view]) {
switcher.find('[for="' + self.id + '_view_' + view + '"], #'+ self.id +'_view_' + view).remove();
}
});
// check if any visible left
buttons = switcher.find('.plupload_button');
if (buttons.length === 1) {
switcher.hide();
view = buttons.eq(0).data('view');
this._viewChanged(view);
} else if ($.ui.button && buttons.length > 1) {
if (this.options.views.remember && $.cookie) {
view = $.cookie('plupload_ui_view');
}
// if wierd case, bail out to default
if (!~plupload.inArray(view, ['list', 'thumbs'])) {
view = this.options.views.active;
}
switcher
.show()
.buttonset()
.find('.ui-button')
.click(function(e) {
view = $(this).data('view');
self._viewChanged(view);
e.preventDefault(); // avoid auto scrolling to widget in IE and FF (see #850)
});
// if view not active - happens when switcher wasn't clicked manually
button = switcher.find('[for="' + self.id + '_view_'+view+'"]');
if (button.length) {
button.trigger('click');
}
} else {
switcher.show();
this._viewChanged(this.options.views.active);
}
// initialize thumb viewer if requested
if (this.options.views.thumbs) {
this._displayThumbs();
}
},
_enableRenaming: function() {
var self = this;
this.filelist.dblclick(function(e) {
var nameInput, fileContainer, file, parts, name, ext = "";
var nameSpan = $(e.target);
if (!nameSpan.hasClass('plupload_file_name_wrapper')) {
return;
}
fileContainer = nameSpan.closest('.plupload_file');
if (!fileContainer.hasClass('plupload_delete')) {
return;
}
// Get file name and split out name and extension
file = self.uploader.getFile(fileContainer[0].id);
name = file.name;
parts = /^(.+)(\.[^.]+)$/.exec(name);
if (parts) {
name = parts[1];
ext = parts[2];
}
// Display input element
nameInput = $('<input class="plupload_file_rename" type="text" />').width(nameSpan.width()).insertAfter(nameSpan.hide());
nameInput.val(name).blur(function() {
nameSpan.show().parent().scrollLeft(0).end().next().remove();
}).keydown(function(e) {
var nameInput = $(this);
if ($.inArray(e.keyCode, [13, 27]) !== -1) {
e.preventDefault();
// Rename file and glue extension back on
if (e.keyCode === 13) {
file.name = nameInput.val() + ext;
nameSpan.html(file.name);
}
nameInput.blur();
}
})[0].focus();
});
},
_enableSortingList: function() {
var self = this;
if ($('.plupload_file', this.filelist).length < 2) {
return;
}
// destroy sortable if enabled
$('tbody', this.filelist).sortable('destroy');
// enable
this.filelist.sortable({
items: '.plupload_delete',
cancel: 'object, .plupload_clearer',
stop: function() {
var files = [];
$.each($(this).sortable('toArray'), function(i, id) {
files[files.length] = self.uploader.getFile(id);
});
files.unshift(files.length);
files.unshift(0);
// re-populate files array
Array.prototype.splice.apply(self.uploader.files, files);
}
});
}
});
} (window, document, plupload, moxie, jQuery));
!function(e,t,i,s,n){function l(e){return i.translate(e)||e}function o(e){e.id=e.attr("id"),e.html('<div class="plupload_wrapper"><div class="ui-widget-content plupload_container"><div class="ui-state-default ui-widget-header plupload_header"><div class="plupload_header_content"><div class="plupload_logo"> </div><div class="plupload_header_title">'+l("Select files")+"</div>"+'<div class="plupload_header_text">'+l("Add files to the upload queue and click the start button.")+"</div>"+'<div class="plupload_view_switch">'+'<input type="radio" id="'+e.id+'_view_list" name="view_mode_'+e.id+'" checked="checked" /><label class="plupload_button" for="'+e.id+'_view_list" data-view="list">'+l("List")+"</label>"+'<input type="radio" id="'+e.id+'_view_thumbs" name="view_mode_'+e.id+'" /><label class="plupload_button" for="'+e.id+'_view_thumbs" data-view="thumbs">'+l("Thumbnails")+"</label>"+"</div>"+"</div>"+"</div>"+'<table class="plupload_filelist plupload_filelist_header ui-widget-header">'+"<tr>"+'<td class="plupload_cell plupload_file_name">'+l("Filename")+"</td>"+'<td class="plupload_cell plupload_file_status">'+l("Status")+"</td>"+'<td class="plupload_cell plupload_file_size">'+l("Size")+"</td>"+'<td class="plupload_cell plupload_file_action">&nbsp;</td>'+"</tr>"+"</table>"+'<div class="plupload_content">'+'<div class="plupload_droptext">'+l("Drag files here.")+"</div>"+'<ul class="plupload_filelist_content"> </ul>'+'<div class="plupload_clearer">&nbsp;</div>'+"</div>"+'<table class="plupload_filelist plupload_filelist_footer ui-widget-header">'+"<tr>"+'<td class="plupload_cell plupload_file_name">'+'<div class="plupload_buttons"><!-- Visible -->'+'<a class="plupload_button plupload_add">'+l("Add Files")+"</a>&nbsp;"+'<a class="plupload_button plupload_start">'+l("Start Upload")+"</a>&nbsp;"+'<a class="plupload_button plupload_stop plupload_hidden">'+l("Stop Upload")+"</a>&nbsp;"+"</div>"+'<div class="plupload_started plupload_hidden"><!-- Hidden -->'+'<div class="plupload_progress plupload_right">'+'<div class="plupload_progress_container"></div>'+"</div>"+'<div class="plupload_cell plupload_upload_status"></div>'+'<div class="plupload_clearer">&nbsp;</div>'+"</div>"+"</td>"+'<td class="plupload_file_status"><span class="plupload_total_status">0%</span></td>'+'<td class="plupload_file_size"><span class="plupload_total_file_size">0 kb</span></td>'+'<td class="plupload_file_action"></td>'+"</tr>"+"</table>"+"</div>"+'<input class="plupload_count" value="0" type="hidden">'+"</div>")}var a={};n.widget("ui.plupload",{widgetEventPrefix:"",contents_bak:"",options:{browse_button_hover:"ui-state-hover",browse_button_active:"ui-state-active",filters:{},buttons:{browse:!0,start:!0,stop:!0},views:{list:!0,thumbs:!1,active:"list",remember:!0},thumb_width:100,thumb_height:60,multiple_queues:!0,dragdrop:!0,autostart:!1,sortable:!1,rename:!1},FILE_COUNT_ERROR:-9001,_create:function(){var e=this.element.attr("id");e||(e=i.guid(),this.element.attr("id",e)),this.id=e,this.contents_bak=this.element.html(),o(this.element),this.container=n(".plupload_container",this.element).attr("id",e+"_container"),this.content=n(".plupload_content",this.element),n.fn.resizable&&this.container.resizable({handles:"s",minHeight:300}),this.filelist=n(".plupload_filelist_content",this.container).attr({id:e+"_filelist",unselectable:"on"}),this.browse_button=n(".plupload_add",this.container).attr("id",e+"_browse"),this.start_button=n(".plupload_start",this.container).attr("id",e+"_start"),this.stop_button=n(".plupload_stop",this.container).attr("id",e+"_stop"),this.thumbs_switcher=n("#"+e+"_view_thumbs"),this.list_switcher=n("#"+e+"_view_list"),n.ui.button&&(this.browse_button.button({icons:{primary:"ui-icon-circle-plus"},disabled:!0}),this.start_button.button({icons:{primary:"ui-icon-circle-arrow-e"},disabled:!0}),this.stop_button.button({icons:{primary:"ui-icon-circle-close"}}),this.list_switcher.button({text:!1,icons:{secondary:"ui-icon-grip-dotted-horizontal"}}),this.thumbs_switcher.button({text:!1,icons:{secondary:"ui-icon-image"}})),this.progressbar=n(".plupload_progress_container",this.container),n.ui.progressbar&&this.progressbar.progressbar(),this.counter=n(".plupload_count",this.element).attr({id:e+"_count",name:e+"_count"}),this._initUploader()},_initUploader:function(){var e,t=this,s=this.id,o={container:s+"_buttons",browse_button:s+"_browse"};n(".plupload_buttons",this.element).attr("id",s+"_buttons"),t.options.dragdrop&&(this.filelist.parent().attr("id",this.id+"_dropbox"),o.drop_element=this.id+"_dropbox"),this.filelist.on("click",function(e){var i,s=n(e.target);s.hasClass("plupload_action_icon")&&(i=s.closest(".plupload_file"),i.hasClass("plupload_delete")&&(t.removeFile(i.attr("id")),e.preventDefault()))}),e=this.uploader=a[s]=new i.Uploader(n.extend(this.options,o)),this.options=e.getOption(),t.options.views.thumbs&&(e.settings.required_features.display_media=!0),t.options.max_file_count&&i.extend(e.getOption("filters"),{max_file_count:t.options.max_file_count}),i.addFileFilter("max_file_count",function(e,i,s){e<=this.files.length-(this.total.uploaded+this.total.failed)?(t.browse_button.button("disable"),this.disableBrowse(),this.trigger("Error",{code:t.FILE_COUNT_ERROR,message:l("File count error."),file:i}),s(!1)):s(!0)}),e.bind("Error",function(e,s){var n,o="";switch(n="<strong>"+s.message+"</strong>",s.code){case i.FILE_EXTENSION_ERROR:o=i.sprintf(l("File: %s"),s.file.name);break;case i.FILE_SIZE_ERROR:o=i.sprintf(l("File: %s, size: %d, max file size: %d"),s.file.name,i.formatSize(s.file.size),i.formatSize(i.parseSize(e.getOption("filters").max_file_size)));break;case i.FILE_DUPLICATE_ERROR:o=i.sprintf(l("%s already present in the queue."),s.file.name);break;case t.FILE_COUNT_ERROR:o=i.sprintf(l("Upload element accepts only %d file(s) at a time. Extra files were stripped."),e.getOption("filters").max_file_count||0);break;case i.IMAGE_FORMAT_ERROR:o=l("Image format either wrong or not supported.");break;case i.IMAGE_MEMORY_ERROR:o=l("Runtime ran out of available memory.");break;case i.HTTP_ERROR:o=l("Upload URL might be wrong or doesn't exist.")}n+=" <br /><i>"+o+"</i>",t._trigger("error",null,{up:e,error:s}),s.code===i.INIT_ERROR?setTimeout(function(){t.destroy()},1):t.notify("error",n)}),e.bind("PostInit",function(e){t.options.buttons.browse?t.browse_button.button("enable"):(t.browse_button.button("disable").hide(),e.disableBrowse(!0)),t.options.buttons.start||t.start_button.button("disable").hide(),t.options.buttons.stop||t.stop_button.button("disable").hide(),!t.options.unique_names&&t.options.rename&&t._enableRenaming(),t.options.dragdrop&&e.features.dragdrop&&t.filelist.parent().addClass("plupload_dropbox"),t._enableViewSwitcher(),t.start_button.click(function(e){n(this).button("option","disabled")||t.start(),e.preventDefault()}),t.stop_button.click(function(e){t.stop(),e.preventDefault()}),t._trigger("ready",null,{up:e})}),e.init(),e.bind("FileFiltered",function(e,i){t._addFiles(i)}),e.bind("FilesAdded",function(e,i){t._trigger("selected",null,{up:e,files:i}),t.options.sortable&&n.ui.sortable&&t._enableSortingList(),t._trigger("updatelist",null,{filelist:t.filelist}),t.options.autostart&&setTimeout(function(){t.start()},10)}),e.bind("FilesRemoved",function(e,i){n.ui.sortable&&t.options.sortable&&n("tbody",t.filelist).sortable("destroy"),n.each(i,function(e,t){n("#"+t.id).toggle("highlight",function(){n(this).remove()})}),e.files.length&&t.options.sortable&&n.ui.sortable&&t._enableSortingList(),t._trigger("updatelist",null,{filelist:t.filelist}),t._trigger("removed",null,{up:e,files:i})}),e.bind("QueueChanged",function(){t._handleState()}),e.bind("StateChanged",function(e){t._handleState(),i.STARTED===e.state?t._trigger("started",null,{up:this.uploader}):i.STOPPED===e.state&&t._trigger("stopped",null,{up:this.uploader})}),e.bind("UploadFile",function(e,i){t._handleFileStatus(i)}),e.bind("FileUploaded",function(e,i,s){t._handleFileStatus(i),t._trigger("uploaded",null,{up:e,file:i,result:s})}),e.bind("UploadProgress",function(e,i){t._handleFileStatus(i),t._updateTotalProgress(),t._trigger("progress",null,{up:e,file:i})}),e.bind("UploadComplete",function(e,i){t._addFormFields(),t._trigger("complete",null,{up:e,files:i})})},_setOption:function(e,t){var i=this;"buttons"==e&&"object"==typeof t&&(t=n.extend(i.options.buttons,t),t.browse?(i.browse_button.button("enable").show(),i.uploader.disableBrowse(!1)):(i.browse_button.button("disable").hide(),i.uploader.disableBrowse(!0)),t.start?i.start_button.button("enable").show():i.start_button.button("disable").hide(),t.stop?i.start_button.button("enable").show():i.stop_button.button("disable").hide()),i.uploader.setOption(e,t)},start:function(){this.uploader.start()},stop:function(){this.uploader.stop()},enable:function(){this.browse_button.button("enable"),this.uploader.disableBrowse(!1)},disable:function(){this.browse_button.button("disable"),this.uploader.disableBrowse(!0)},getFile:function(e){var t;return t="number"==typeof e?this.uploader.files[e]:this.uploader.getFile(e)},getFiles:function(){return this.uploader.files},removeFile:function(e){"string"===i.typeOf(e)&&(e=this.getFile(e)),this.uploader.removeFile(e)},clearQueue:function(){this.uploader.splice()},getUploader:function(){return this.uploader},refresh:function(){this.uploader.refresh()},notify:function(e,t){var i=n('<div class="plupload_message"><span class="plupload_message_close ui-icon ui-icon-circle-close" title="'+l("Close")+'"></span>'+'<p><span class="ui-icon"></span>'+t+"</p>"+"</div>");i.addClass("ui-state-"+("error"===e?"error":"highlight")).find("p .ui-icon").addClass("ui-icon-"+("error"===e?"alert":"info")).end().find(".plupload_message_close").click(function(){i.remove()}).end(),n(".plupload_header",this.container).append(i)},destroy:function(){this.uploader.destroy(),n(".plupload_button",this.element).unbind(),n.ui.button&&n(".plupload_add, .plupload_start, .plupload_stop",this.container).button("destroy"),n.ui.progressbar&&this.progressbar.progressbar("destroy"),n.ui.sortable&&this.options.sortable&&n("tbody",this.filelist).sortable("destroy"),this.element.empty().html(this.contents_bak),this.contents_bak="",n.Widget.prototype.destroy.apply(this)},_handleState:function(){var e=this.uploader,t=e.files.length-(e.total.uploaded+e.total.failed),s=e.getOption("filters").max_file_count||0;i.STARTED===e.state?(n([]).add(this.stop_button).add(".plupload_started").removeClass("plupload_hidden"),this.start_button.button("disable"),this.options.multiple_queues||(this.browse_button.button("disable"),e.disableBrowse()),n(".plupload_upload_status",this.element).html(i.sprintf(l("Uploaded %d/%d files"),e.total.uploaded,e.files.length)),n(".plupload_header_content",this.element).addClass("plupload_header_content_bw")):i.STOPPED===e.state&&(n([]).add(this.stop_button).add(".plupload_started").addClass("plupload_hidden"),t?this.start_button.button("enable"):this.start_button.button("disable"),this.options.multiple_queues&&n(".plupload_header_content",this.element).removeClass("plupload_header_content_bw"),this.options.multiple_queues&&s&&s>t&&(this.browse_button.button("enable"),e.disableBrowse(!1)),this._updateTotalProgress()),0===e.total.queued?n(".ui-button-text",this.browse_button).html(l("Add Files")):n(".ui-button-text",this.browse_button).html(i.sprintf(l("%d files queued"),e.total.queued)),this.container.toggleClass("plupload_files_queued",e.files.length),e.refresh()},_handleFileStatus:function(e){var t,s,l=n("#"+e.id);if(l.length){switch(e.status){case i.DONE:t="plupload_done",s="plupload_action_icon ui-icon ui-icon-circle-check";break;case i.FAILED:t="ui-state-error plupload_failed",s="plupload_action_icon ui-icon ui-icon-alert";break;case i.QUEUED:t="plupload_delete",s="plupload_action_icon ui-icon ui-icon-circle-minus";break;case i.UPLOADING:t="ui-state-highlight plupload_uploading",s="plupload_action_icon ui-icon ui-icon-circle-arrow-w";var o=n(".plupload_scroll",this.container),a=o.scrollTop(),r=o.height(),d=l.position().top+l.height();d>r&&o.scrollTop(a+d-r),l.find(".plupload_file_percent").html(e.percent+"%").end().find(".plupload_file_progress").css("width",e.percent+"%").end().find(".plupload_file_size").html(i.formatSize(e.size))}t+=" ui-state-default plupload_file",l.attr("class",t).find(".plupload_action_icon").attr("class",s)}},_updateTotalProgress:function(){var e=this.uploader;this.filelist[0].scrollTop=this.filelist[0].scrollHeight,this.progressbar.progressbar("value",e.total.percent),this.element.find(".plupload_total_status").html(e.total.percent+"%").end().find(".plupload_total_file_size").html(i.formatSize(e.total.size)).end().find(".plupload_upload_status").html(i.sprintf(l("Uploaded %d/%d files"),e.total.uploaded,e.files.length))},_displayThumbs:function(){function e(e,t,i){var s;e.on(t,function(){clearTimeout(s),s=setTimeout(function(){clearTimeout(s),i()},300)})}function t(){if(!r||!d){var e=n(".plupload_file:eq(0)",p.filelist);r=e.outerWidth(!0),d=e.outerHeight(!0)}var t=p.content.width(),i=p.content.height();u=Math.floor(t/r),c=u*(Math.ceil(i/d)+1)}function i(){var e=Math.floor(p.content.scrollTop()/d)*u;_=n(".plupload_file .plupload_file_thumb",p.filelist).slice(e,e+c).filter(".plupload_thumb_toload").get()}function l(){function s(){"thumbs"===p.view_mode&&(t(),i(),a())}n.fn.resizable&&e(p.container,"resize",s),e(p.window,"resize",s),e(p.content,"scroll",s),p.element.on("viewchanged selected",s),s()}function o(e,t){var i=new s.image.Image,l=s.core.utils.Url.resolveUrl;i.onload=function(){var t=n("#"+e.id+" .plupload_file_thumb",p.filelist);this.embed(t[0],{width:p.options.thumb_width,height:p.options.thumb_height,crop:!0,fit:!0,preserveHeaders:!1,swf_url:l(p.options.flash_swf_url),xap_url:l(p.options.silverlight_xap_url)})},i.bind("embedded error",function(i){n("#"+e.id,p.filelist).find(".plupload_file_thumb").removeClass("plupload_thumb_loading").addClass("plupload_thumb_"+i.type),this.destroy(),setTimeout(t,1)}),n("#"+e.id,p.filelist).find(".plupload_file_thumb").removeClass("plupload_thumb_toload").addClass("plupload_thumb_loading"),i.load(e.getSource())}function a(){"thumbs"!==p.view_mode||h||(i(),_.length&&(h=!0,o(p.getFile(n(_.shift()).closest(".plupload_file").attr("id")),function(){h=!1,a()})))}var r,d,u,p=this,c=0,_=[],h=!1;this.options.views.thumbs&&this.element.on("selected",function f(){p.element.off("selected",f),l()})},_addFiles:function(e){var t,l=this,o="";t='<li class="plupload_file ui-state-default plupload_delete" id="{id}" style="width:{thumb_width}px;"><div class="plupload_file_thumb plupload_thumb_toload" style="width: {thumb_width}px; height: {thumb_height}px;"><div class="plupload_file_dummy ui-widget-content" style="line-height: {thumb_height}px;"><span class="ui-state-disabled">{ext} </span></div></div><div class="plupload_file_status"><div class="plupload_file_progress ui-widget-header" style="width: 0%"> </div><span class="plupload_file_percent">{percent} </span></div><div class="plupload_file_name" title="{name}"><span class="plupload_file_name_wrapper">{name} </span></div><div class="plupload_file_action"><div class="plupload_action_icon ui-icon ui-icon-circle-minus"> </div></div><div class="plupload_file_size">{size} </div><div class="plupload_file_fields"> </div></li>',"array"!==i.typeOf(e)&&(e=[e]),n.each(e,function(e,n){var a=s.core.utils.Mime.getFileExtension(n.name)||"none";o+=t.replace(/\{(\w+)\}/g,function(e,t){switch(t){case"thumb_width":case"thumb_height":return l.options[t];case"size":return i.formatSize(n.size);case"ext":return a;default:return n[t]||""}})}),l.filelist.append(o)},_addFormFields:function(){var e=this;n(".plupload_file_fields",this.filelist).html(""),i.each(this.uploader.files,function(t,s){var l="",o=e.id+"_"+s;t.target_name&&(l+='<input type="hidden" name="'+o+'_tmpname" value="'+i.xmlEncode(t.target_name)+'" />'),l+='<input type="hidden" name="'+o+'_name" value="'+i.xmlEncode(t.name)+'" />',l+='<input type="hidden" name="'+o+'_status" value="'+(t.status===i.DONE?"done":"failed")+'" />',n("#"+t.id).find(".plupload_file_fields").html(l)}),this.counter.val(this.uploader.files.length)},_viewChanged:function(e){this.options.views.remember&&n.cookie&&n.cookie("plupload_ui_view",e,{expires:7,path:"/"}),"IE"===i.ua.browser&&i.ua.version<7&&this.content.attr("style",'height:expression(document.getElementById("'+this.id+"_container"+'").clientHeight - '+("list"===e?132:102)+")"),this.container.removeClass("plupload_view_list plupload_view_thumbs").addClass("plupload_view_"+e),this.view_mode=e,this._trigger("viewchanged",null,{view:e})},_enableViewSwitcher:function(){var e,t,s,l=this,o=n(".plupload_view_switch",this.container);i.each(["list","thumbs"],function(e){l.options.views[e]||o.find('[for="'+l.id+"_view_"+e+'"], #'+l.id+"_view_"+e).remove()}),t=o.find(".plupload_button"),1===t.length?(o.hide(),e=t.eq(0).data("view"),this._viewChanged(e)):n.ui.button&&t.length>1?(this.options.views.remember&&n.cookie&&(e=n.cookie("plupload_ui_view")),~i.inArray(e,["list","thumbs"])||(e=this.options.views.active),o.show().buttonset().find(".ui-button").click(function(t){e=n(this).data("view"),l._viewChanged(e),t.preventDefault()}),s=o.find('[for="'+l.id+"_view_"+e+'"]'),s.length&&s.trigger("click")):(o.show(),this._viewChanged(this.options.views.active)),this.options.views.thumbs&&this._displayThumbs()},_enableRenaming:function(){var e=this;this.filelist.dblclick(function(t){var i,s,l,o,a,r="",d=n(t.target);d.hasClass("plupload_file_name_wrapper")&&(s=d.closest(".plupload_file"),s.hasClass("plupload_delete")&&(l=e.uploader.getFile(s[0].id),a=l.name,o=/^(.+)(\.[^.]+)$/.exec(a),o&&(a=o[1],r=o[2]),i=n('<input class="plupload_file_rename" type="text" />').width(d.width()).insertAfter(d.hide()),i.val(a).blur(function(){d.show().parent().scrollLeft(0).end().next().remove()}).keydown(function(e){var t=n(this);-1!==n.inArray(e.keyCode,[13,27])&&(e.preventDefault(),13===e.keyCode&&(l.name=t.val()+r,d.html(l.name)),t.blur())})[0].focus()))})},_enableSortingList:function(){var e=this;n(".plupload_file",this.filelist).length<2||(n("tbody",this.filelist).sortable("destroy"),this.filelist.sortable({items:".plupload_delete",cancel:"object, .plupload_clearer",stop:function(){var t=[];n.each(n(this).sortable("toArray"),function(i,s){t[t.length]=e.uploader.getFile(s)}),t.unshift(t.length),t.unshift(0),Array.prototype.splice.apply(e.uploader.files,t)}}))}})}(window,document,plupload,moxie,jQuery);
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
/**
* Plupload - multi-runtime File Uploader
* v2.3.6
*
* Copyright 2013, Moxiecode Systems AB
* Released under GPL License.
*
* License: http://www.plupload.com/license
* Contributing: http://www.plupload.com/contributing
*
* Date: 2017-11-03
*/
;(function (global, factory) {
var extract = function() {
var ctx = {};
factory.apply(ctx, arguments);
return ctx.plupload;
};
if (typeof define === "function" && define.amd) {
define("plupload", ['./moxie'], extract);
} else if (typeof module === "object" && module.exports) {
module.exports = extract(require('./moxie'));
} else {
global.plupload = extract(global.moxie);
}
}(this || window, function(moxie) {
/**
* Plupload.js
*
* Copyright 2013, Moxiecode Systems AB
* Released under GPL License.
*
* License: http://www.plupload.com/license
* Contributing: http://www.plupload.com/contributing
*/
;(function(exports, o, undef) {
var delay = window.setTimeout;
var fileFilters = {};
var u = o.core.utils;
var Runtime = o.runtime.Runtime;
// convert plupload features to caps acceptable by mOxie
function normalizeCaps(settings) {
var features = settings.required_features, caps = {};
function resolve(feature, value, strict) {
// Feature notation is deprecated, use caps (this thing here is required for backward compatibility)
var map = {
chunks: 'slice_blob',
jpgresize: 'send_binary_string',
pngresize: 'send_binary_string',
progress: 'report_upload_progress',
multi_selection: 'select_multiple',
dragdrop: 'drag_and_drop',
drop_element: 'drag_and_drop',
headers: 'send_custom_headers',
urlstream_upload: 'send_binary_string',
canSendBinary: 'send_binary',
triggerDialog: 'summon_file_dialog'
};
if (map[feature]) {
caps[map[feature]] = value;
} else if (!strict) {
caps[feature] = value;
}
}
if (typeof(features) === 'string') {
plupload.each(features.split(/\s*,\s*/), function(feature) {
resolve(feature, true);
});
} else if (typeof(features) === 'object') {
plupload.each(features, function(value, feature) {
resolve(feature, value);
});
} else if (features === true) {
// check settings for required features
if (settings.chunk_size && settings.chunk_size > 0) {
caps.slice_blob = true;
}
if (!plupload.isEmptyObj(settings.resize) || settings.multipart === false) {
caps.send_binary_string = true;
}
if (settings.http_method) {
caps.use_http_method = settings.http_method;
}
plupload.each(settings, function(value, feature) {
resolve(feature, !!value, true); // strict check
});
}
return caps;
}
/**
* @module plupload
* @static
*/
var plupload = {
/**
* Plupload version will be replaced on build.
*
* @property VERSION
* @for Plupload
* @static
* @final
*/
VERSION : '2.3.6',
/**
* The state of the queue before it has started and after it has finished
*
* @property STOPPED
* @static
* @final
*/
STOPPED : 1,
/**
* Upload process is running
*
* @property STARTED
* @static
* @final
*/
STARTED : 2,
/**
* File is queued for upload
*
* @property QUEUED
* @static
* @final
*/
QUEUED : 1,
/**
* File is being uploaded
*
* @property UPLOADING
* @static
* @final
*/
UPLOADING : 2,
/**
* File has failed to be uploaded
*
* @property FAILED
* @static
* @final
*/
FAILED : 4,
/**
* File has been uploaded successfully
*
* @property DONE
* @static
* @final
*/
DONE : 5,
// Error constants used by the Error event
/**
* Generic error for example if an exception is thrown inside Silverlight.
*
* @property GENERIC_ERROR
* @static
* @final
*/
GENERIC_ERROR : -100,
/**
* HTTP transport error. For example if the server produces a HTTP status other than 200.
*
* @property HTTP_ERROR
* @static
* @final
*/
HTTP_ERROR : -200,
/**
* Generic I/O error. For example if it wasn't possible to open the file stream on local machine.
*
* @property IO_ERROR
* @static
* @final
*/
IO_ERROR : -300,
/**
* @property SECURITY_ERROR
* @static
* @final
*/
SECURITY_ERROR : -400,
/**
* Initialization error. Will be triggered if no runtime was initialized.
*
* @property INIT_ERROR
* @static
* @final
*/
INIT_ERROR : -500,
/**
* File size error. If the user selects a file that is too large or is empty it will be blocked and
* an error of this type will be triggered.
*
* @property FILE_SIZE_ERROR
* @static
* @final
*/
FILE_SIZE_ERROR : -600,
/**
* File extension error. If the user selects a file that isn't valid according to the filters setting.
*
* @property FILE_EXTENSION_ERROR
* @static
* @final
*/
FILE_EXTENSION_ERROR : -601,
/**
* Duplicate file error. If prevent_duplicates is set to true and user selects the same file again.
*
* @property FILE_DUPLICATE_ERROR
* @static
* @final
*/
FILE_DUPLICATE_ERROR : -602,
/**
* Runtime will try to detect if image is proper one. Otherwise will throw this error.
*
* @property IMAGE_FORMAT_ERROR
* @static
* @final
*/
IMAGE_FORMAT_ERROR : -700,
/**
* While working on files runtime may run out of memory and will throw this error.
*
* @since 2.1.2
* @property MEMORY_ERROR
* @static
* @final
*/
MEMORY_ERROR : -701,
/**
* Each runtime has an upper limit on a dimension of the image it can handle. If bigger, will throw this error.
*
* @property IMAGE_DIMENSIONS_ERROR
* @static
* @final
*/
IMAGE_DIMENSIONS_ERROR : -702,
/**
* Expose whole moxie (#1469).
*
* @property moxie
* @type Object
* @final
*/
moxie: o,
/**
* Mime type lookup table.
*
* @property mimeTypes
* @type Object
* @final
*/
mimeTypes : u.Mime.mimes,
/**
* In some cases sniffing is the only way around :(
*/
ua: u.Env,
/**
* Gets the true type of the built-in object (better version of typeof).
* @credits Angus Croll (http://javascriptweblog.wordpress.com/)
*
* @method typeOf
* @static
* @param {Object} o Object to check.
* @return {String} Object [[Class]]
*/
typeOf: u.Basic.typeOf,
/**
* Extends the specified object with another object.
*
* @method extend
* @static
* @param {Object} target Object to extend.
* @param {Object..} obj Multiple objects to extend with.
* @return {Object} Same as target, the extended object.
*/
extend : u.Basic.extend,
/**
* Generates an unique ID. This is 99.99% unique since it takes the current time and 5 random numbers.
* The only way a user would be able to get the same ID is if the two persons at the same exact millisecond manages
* to get 5 the same random numbers between 0-65535 it also uses a counter so each call will be guaranteed to be page unique.
* It's more probable for the earth to be hit with an asteriod. You can also if you want to be 100% sure set the plupload.guidPrefix property
* to an user unique key.
*
* @method guid
* @static
* @return {String} Virtually unique id.
*/
guid : u.Basic.guid,
/**
* Get array of DOM Elements by their ids.
*
* @method get
* @param {String} id Identifier of the DOM Element
* @return {Array}
*/
getAll : function get(ids) {
var els = [], el;
if (plupload.typeOf(ids) !== 'array') {
ids = [ids];
}
var i = ids.length;
while (i--) {
el = plupload.get(ids[i]);
if (el) {
els.push(el);
}
}
return els.length ? els : null;
},
/**
Get DOM element by id
@method get
@param {String} id Identifier of the DOM Element
@return {Node}
*/
get: u.Dom.get,
/**
* Executes the callback function for each item in array/object. If you return false in the
* callback it will break the loop.
*
* @method each
* @static
* @param {Object} obj Object to iterate.
* @param {function} callback Callback function to execute for each item.
*/
each : u.Basic.each,
/**
* Returns the absolute x, y position of an Element. The position will be returned in a object with x, y fields.
*
* @method getPos
* @static
* @param {Element} node HTML element or element id to get x, y position from.
* @param {Element} root Optional root element to stop calculations at.
* @return {object} Absolute position of the specified element object with x, y fields.
*/
getPos : u.Dom.getPos,
/**
* Returns the size of the specified node in pixels.
*
* @method getSize
* @static
* @param {Node} node Node to get the size of.
* @return {Object} Object with a w and h property.
*/
getSize : u.Dom.getSize,
/**
* Encodes the specified string.
*
* @method xmlEncode
* @static
* @param {String} s String to encode.
* @return {String} Encoded string.
*/
xmlEncode : function(str) {
var xmlEncodeChars = {'<' : 'lt', '>' : 'gt', '&' : 'amp', '"' : 'quot', '\'' : '#39'}, xmlEncodeRegExp = /[<>&\"\']/g;
return str ? ('' + str).replace(xmlEncodeRegExp, function(chr) {
return xmlEncodeChars[chr] ? '&' + xmlEncodeChars[chr] + ';' : chr;
}) : str;
},
/**
* Forces anything into an array.
*
* @method toArray
* @static
* @param {Object} obj Object with length field.
* @return {Array} Array object containing all items.
*/
toArray : u.Basic.toArray,
/**
* Find an element in array and return its index if present, otherwise return -1.
*
* @method inArray
* @static
* @param {mixed} needle Element to find
* @param {Array} array
* @return {Int} Index of the element, or -1 if not found
*/
inArray : u.Basic.inArray,
/**
Recieve an array of functions (usually async) to call in sequence, each function
receives a callback as first argument that it should call, when it completes. Finally,
after everything is complete, main callback is called. Passing truthy value to the
callback as a first argument will interrupt the sequence and invoke main callback
immediately.
@method inSeries
@static
@param {Array} queue Array of functions to call in sequence
@param {Function} cb Main callback that is called in the end, or in case of error
*/
inSeries: u.Basic.inSeries,
/**
* Extends the language pack object with new items.
*
* @method addI18n
* @static
* @param {Object} pack Language pack items to add.
* @return {Object} Extended language pack object.
*/
addI18n : o.core.I18n.addI18n,
/**
* Translates the specified string by checking for the english string in the language pack lookup.
*
* @method translate
* @static
* @param {String} str String to look for.
* @return {String} Translated string or the input string if it wasn't found.
*/
translate : o.core.I18n.translate,
/**
* Pseudo sprintf implementation - simple way to replace tokens with specified values.
*
* @param {String} str String with tokens
* @return {String} String with replaced tokens
*/
sprintf : u.Basic.sprintf,
/**
* Checks if object is empty.
*
* @method isEmptyObj
* @static
* @param {Object} obj Object to check.
* @return {Boolean}
*/
isEmptyObj : u.Basic.isEmptyObj,
/**
* Checks if specified DOM element has specified class.
*
* @method hasClass
* @static
* @param {Object} obj DOM element like object to add handler to.
* @param {String} name Class name
*/
hasClass : u.Dom.hasClass,
/**
* Adds specified className to specified DOM element.
*
* @method addClass
* @static
* @param {Object} obj DOM element like object to add handler to.
* @param {String} name Class name
*/
addClass : u.Dom.addClass,
/**
* Removes specified className from specified DOM element.
*
* @method removeClass
* @static
* @param {Object} obj DOM element like object to add handler to.
* @param {String} name Class name
*/
removeClass : u.Dom.removeClass,
/**
* Returns a given computed style of a DOM element.
*
* @method getStyle
* @static
* @param {Object} obj DOM element like object.
* @param {String} name Style you want to get from the DOM element
*/
getStyle : u.Dom.getStyle,
/**
* Adds an event handler to the specified object and store reference to the handler
* in objects internal Plupload registry (@see removeEvent).
*
* @method addEvent
* @static
* @param {Object} obj DOM element like object to add handler to.
* @param {String} name Name to add event listener to.
* @param {Function} callback Function to call when event occurs.
* @param {String} (optional) key that might be used to add specifity to the event record.
*/
addEvent : u.Events.addEvent,
/**
* Remove event handler from the specified object. If third argument (callback)
* is not specified remove all events with the specified name.
*
* @method removeEvent
* @static
* @param {Object} obj DOM element to remove event listener(s) from.
* @param {String} name Name of event listener to remove.
* @param {Function|String} (optional) might be a callback or unique key to match.
*/
removeEvent: u.Events.removeEvent,
/**
* Remove all kind of events from the specified object
*
* @method removeAllEvents
* @static
* @param {Object} obj DOM element to remove event listeners from.
* @param {String} (optional) unique key to match, when removing events.
*/
removeAllEvents: u.Events.removeAllEvents,
/**
* Cleans the specified name from national characters (diacritics). The result will be a name with only a-z, 0-9 and _.
*
* @method cleanName
* @static
* @param {String} s String to clean up.
* @return {String} Cleaned string.
*/
cleanName : function(name) {
var i, lookup;
// Replace diacritics
lookup = [
/[\300-\306]/g, 'A', /[\340-\346]/g, 'a',
/\307/g, 'C', /\347/g, 'c',
/[\310-\313]/g, 'E', /[\350-\353]/g, 'e',
/[\314-\317]/g, 'I', /[\354-\357]/g, 'i',
/\321/g, 'N', /\361/g, 'n',
/[\322-\330]/g, 'O', /[\362-\370]/g, 'o',
/[\331-\334]/g, 'U', /[\371-\374]/g, 'u'
];
for (i = 0; i < lookup.length; i += 2) {
name = name.replace(lookup[i], lookup[i + 1]);
}
// Replace whitespace
name = name.replace(/\s+/g, '_');
// Remove anything else
name = name.replace(/[^a-z0-9_\-\.]+/gi, '');
return name;
},
/**
* Builds a full url out of a base URL and an object with items to append as query string items.
*
* @method buildUrl
* @static
* @param {String} url Base URL to append query string items to.
* @param {Object} items Name/value object to serialize as a querystring.
* @return {String} String with url + serialized query string items.
*/
buildUrl: function(url, items) {
var query = '';
plupload.each(items, function(value, name) {
query += (query ? '&' : '') + encodeURIComponent(name) + '=' + encodeURIComponent(value);
});
if (query) {
url += (url.indexOf('?') > 0 ? '&' : '?') + query;
}
return url;
},
/**
* Formats the specified number as a size string for example 1024 becomes 1 KB.
*
* @method formatSize
* @static
* @param {Number} size Size to format as string.
* @return {String} Formatted size string.
*/
formatSize : function(size) {
if (size === undef || /\D/.test(size)) {
return plupload.translate('N/A');
}
function round(num, precision) {
return Math.round(num * Math.pow(10, precision)) / Math.pow(10, precision);
}
var boundary = Math.pow(1024, 4);
// TB
if (size > boundary) {
return round(size / boundary, 1) + " " + plupload.translate('tb');
}
// GB
if (size > (boundary/=1024)) {
return round(size / boundary, 1) + " " + plupload.translate('gb');
}
// MB
if (size > (boundary/=1024)) {
return round(size / boundary, 1) + " " + plupload.translate('mb');
}
// KB
if (size > 1024) {
return Math.round(size / 1024) + " " + plupload.translate('kb');
}
return size + " " + plupload.translate('b');
},
/**
* Parses the specified size string into a byte value. For example 10kb becomes 10240.
*
* @method parseSize
* @static
* @param {String|Number} size String to parse or number to just pass through.
* @return {Number} Size in bytes.
*/
parseSize : u.Basic.parseSizeStr,
/**
* A way to predict what runtime will be choosen in the current environment with the
* specified settings.
*
* @method predictRuntime
* @static
* @param {Object|String} config Plupload settings to check
* @param {String} [runtimes] Comma-separated list of runtimes to check against
* @return {String} Type of compatible runtime
*/
predictRuntime : function(config, runtimes) {
var up, runtime;
up = new plupload.Uploader(config);
runtime = Runtime.thatCan(up.getOption().required_features, runtimes || config.runtimes);
up.destroy();
return runtime;
},
/**
* Registers a filter that will be executed for each file added to the queue.
* If callback returns false, file will not be added.
*
* Callback receives two arguments: a value for the filter as it was specified in settings.filters
* and a file to be filtered. Callback is executed in the context of uploader instance.
*
* @method addFileFilter
* @static
* @param {String} name Name of the filter by which it can be referenced in settings.filters
* @param {String} cb Callback - the actual routine that every added file must pass
*/
addFileFilter: function(name, cb) {
fileFilters[name] = cb;
}
};
plupload.addFileFilter('mime_types', function(filters, file, cb) {
if (filters.length && !filters.regexp.test(file.name)) {
this.trigger('Error', {
code : plupload.FILE_EXTENSION_ERROR,
message : plupload.translate('File extension error.'),
file : file
});
cb(false);
} else {
cb(true);
}
});
plupload.addFileFilter('max_file_size', function(maxSize, file, cb) {
var undef;
maxSize = plupload.parseSize(maxSize);
// Invalid file size
if (file.size !== undef && maxSize && file.size > maxSize) {
this.trigger('Error', {
code : plupload.FILE_SIZE_ERROR,
message : plupload.translate('File size error.'),
file : file
});
cb(false);
} else {
cb(true);
}
});
plupload.addFileFilter('prevent_duplicates', function(value, file, cb) {
if (value) {
var ii = this.files.length;
while (ii--) {
// Compare by name and size (size might be 0 or undefined, but still equivalent for both)
if (file.name === this.files[ii].name && file.size === this.files[ii].size) {
this.trigger('Error', {
code : plupload.FILE_DUPLICATE_ERROR,
message : plupload.translate('Duplicate file error.'),
file : file
});
cb(false);
return;
}
}
}
cb(true);
});
plupload.addFileFilter('prevent_empty', function(value, file, cb) {
if (value && !file.size && file.size !== undef) {
this.trigger('Error', {
code : plupload.FILE_SIZE_ERROR,
message : plupload.translate('File size error.'),
file : file
});
cb(false);
} else {
cb(true);
}
});
/**
@class Uploader
@constructor
@param {Object} settings For detailed information about each option check documentation.
@param {String|DOMElement} settings.browse_button id of the DOM element or DOM element itself to use as file dialog trigger.
@param {Number|String} [settings.chunk_size=0] Chunk size in bytes to slice the file into. Shorcuts with b, kb, mb, gb, tb suffixes also supported. `e.g. 204800 or "204800b" or "200kb"`. By default - disabled.
@param {String|DOMElement} [settings.container] id of the DOM element or DOM element itself that will be used to wrap uploader structures. Defaults to immediate parent of the `browse_button` element.
@param {String|DOMElement} [settings.drop_element] id of the DOM element or DOM element itself to use as a drop zone for Drag-n-Drop.
@param {String} [settings.file_data_name="file"] Name for the file field in Multipart formated message.
@param {Object} [settings.filters={}] Set of file type filters.
@param {String|Number} [settings.filters.max_file_size=0] Maximum file size that the user can pick, in bytes. Optionally supports b, kb, mb, gb, tb suffixes. `e.g. "10mb" or "1gb"`. By default - not set. Dispatches `plupload.FILE_SIZE_ERROR`.
@param {Array} [settings.filters.mime_types=[]] List of file types to accept, each one defined by title and list of extensions. `e.g. {title : "Image files", extensions : "jpg,jpeg,gif,png"}`. Dispatches `plupload.FILE_EXTENSION_ERROR`
@param {Boolean} [settings.filters.prevent_duplicates=false] Do not let duplicates into the queue. Dispatches `plupload.FILE_DUPLICATE_ERROR`.
@param {Boolean} [settings.filters.prevent_empty=true] Do not let empty files into the queue (IE10 is known to hang for example when trying to upload such). Dispatches `plupload.FILE_SIZE_ERROR`.
@param {String} [settings.flash_swf_url] URL of the Flash swf.
@param {Object} [settings.headers] Custom headers to send with the upload. Hash of name/value pairs.
@param {String} [settings.http_method="POST"] HTTP method to use during upload (only PUT or POST allowed).
@param {Number} [settings.max_retries=0] How many times to retry the chunk or file, before triggering Error event.
@param {Boolean} [settings.multipart=true] Whether to send file and additional parameters as Multipart formated message.
@param {Object} [settings.multipart_params] Hash of key/value pairs to send with every file upload.
@param {Boolean} [settings.multi_selection=true] Enable ability to select multiple files at once in file dialog.
@param {String|Object} [settings.required_features] Either comma-separated list or hash of required features that chosen runtime should absolutely possess.
@param {Object} [settings.resize] Enable resizng of images on client-side. Applies to `image/jpeg` and `image/png` only. `e.g. {width : 200, height : 200, quality : 90, crop: true}`
@param {Number} [settings.resize.width] If image is bigger, it will be resized.
@param {Number} [settings.resize.height] If image is bigger, it will be resized.
@param {Number} [settings.resize.quality=90] Compression quality for jpegs (1-100).
@param {Boolean} [settings.resize.crop=false] Whether to crop images to exact dimensions. By default they will be resized proportionally.
@param {String} [settings.runtimes="html5,flash,silverlight,html4"] Comma separated list of runtimes, that Plupload will try in turn, moving to the next if previous fails.
@param {String} [settings.silverlight_xap_url] URL of the Silverlight xap.
@param {Boolean} [settings.send_chunk_number=true] Whether to send chunks and chunk numbers, or total and offset bytes.
@param {Boolean} [settings.send_file_name=true] Whether to send file name as additional argument - 'name' (required for chunked uploads and some other cases where file name cannot be sent via normal ways).
@param {String} settings.url URL of the server-side upload handler.
@param {Boolean} [settings.unique_names=false] If true will generate unique filenames for uploaded files.
*/
plupload.Uploader = function(options) {
/**
Fires when the current RunTime has been initialized.
@event Init
@param {plupload.Uploader} uploader Uploader instance sending the event.
*/
/**
Fires after the init event incase you need to perform actions there.
@event PostInit
@param {plupload.Uploader} uploader Uploader instance sending the event.
*/
/**
Fires when the option is changed in via uploader.setOption().
@event OptionChanged
@since 2.1
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {String} name Name of the option that was changed
@param {Mixed} value New value for the specified option
@param {Mixed} oldValue Previous value of the option
*/
/**
Fires when the silverlight/flash or other shim needs to move.
@event Refresh
@param {plupload.Uploader} uploader Uploader instance sending the event.
*/
/**
Fires when the overall state is being changed for the upload queue.
@event StateChanged
@param {plupload.Uploader} uploader Uploader instance sending the event.
*/
/**
Fires when browse_button is clicked and browse dialog shows.
@event Browse
@since 2.1.2
@param {plupload.Uploader} uploader Uploader instance sending the event.
*/
/**
Fires for every filtered file before it is added to the queue.
@event FileFiltered
@since 2.1
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {plupload.File} file Another file that has to be added to the queue.
*/
/**
Fires when the file queue is changed. In other words when files are added/removed to the files array of the uploader instance.
@event QueueChanged
@param {plupload.Uploader} uploader Uploader instance sending the event.
*/
/**
Fires after files were filtered and added to the queue.
@event FilesAdded
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {Array} files Array of file objects that were added to queue by the user.
*/
/**
Fires when file is removed from the queue.
@event FilesRemoved
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {Array} files Array of files that got removed.
*/
/**
Fires just before a file is uploaded. Can be used to cancel the upload for the specified file
by returning false from the handler.
@event BeforeUpload
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {plupload.File} file File to be uploaded.
*/
/**
Fires when a file is to be uploaded by the runtime.
@event UploadFile
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {plupload.File} file File to be uploaded.
*/
/**
Fires while a file is being uploaded. Use this event to update the current file upload progress.
@event UploadProgress
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {plupload.File} file File that is currently being uploaded.
*/
/**
* Fires just before a chunk is uploaded. This event enables you to override settings
* on the uploader instance before the chunk is uploaded.
*
* @event BeforeChunkUpload
* @param {plupload.Uploader} uploader Uploader instance sending the event.
* @param {plupload.File} file File to be uploaded.
* @param {Object} args POST params to be sent.
* @param {Blob} chunkBlob Current blob.
* @param {offset} offset Current offset.
*/
/**
Fires when file chunk is uploaded.
@event ChunkUploaded
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {plupload.File} file File that the chunk was uploaded for.
@param {Object} result Object with response properties.
@param {Number} result.offset The amount of bytes the server has received so far, including this chunk.
@param {Number} result.total The size of the file.
@param {String} result.response The response body sent by the server.
@param {Number} result.status The HTTP status code sent by the server.
@param {String} result.responseHeaders All the response headers as a single string.
*/
/**
Fires when a file is successfully uploaded.
@event FileUploaded
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {plupload.File} file File that was uploaded.
@param {Object} result Object with response properties.
@param {String} result.response The response body sent by the server.
@param {Number} result.status The HTTP status code sent by the server.
@param {String} result.responseHeaders All the response headers as a single string.
*/
/**
Fires when all files in a queue are uploaded.
@event UploadComplete
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {Array} files Array of file objects that was added to queue/selected by the user.
*/
/**
Fires when a error occurs.
@event Error
@param {plupload.Uploader} uploader Uploader instance sending the event.
@param {Object} error Contains code, message and sometimes file and other details.
@param {Number} error.code The plupload error code.
@param {String} error.message Description of the error (uses i18n).
*/
/**
Fires when destroy method is called.
@event Destroy
@param {plupload.Uploader} uploader Uploader instance sending the event.
*/
var uid = plupload.guid()
, settings
, files = []
, preferred_caps = {}
, fileInputs = []
, fileDrops = []
, startTime
, total
, disabled = false
, xhr
;
// Private methods
function uploadNext() {
var file, count = 0, i;
if (this.state == plupload.STARTED) {
// Find first QUEUED file
for (i = 0; i < files.length; i++) {
if (!file && files[i].status == plupload.QUEUED) {
file = files[i];
if (this.trigger("BeforeUpload", file)) {
file.status = plupload.UPLOADING;
this.trigger("UploadFile", file);
}
} else {
count++;
}
}
// All files are DONE or FAILED
if (count == files.length) {
if (this.state !== plupload.STOPPED) {
this.state = plupload.STOPPED;
this.trigger("StateChanged");
}
this.trigger("UploadComplete", files);
}
}
}
function calcFile(file) {
file.percent = file.size > 0 ? Math.ceil(file.loaded / file.size * 100) : 100;
calc();
}
function calc() {
var i, file;
var loaded;
var loadedDuringCurrentSession = 0;
// Reset stats
total.reset();
// Check status, size, loaded etc on all files
for (i = 0; i < files.length; i++) {
file = files[i];
if (file.size !== undef) {
// We calculate totals based on original file size
total.size += file.origSize;
// Since we cannot predict file size after resize, we do opposite and
// interpolate loaded amount to match magnitude of total
loaded = file.loaded * file.origSize / file.size;
if (!file.completeTimestamp || file.completeTimestamp > startTime) {
loadedDuringCurrentSession += loaded;
}
total.loaded += loaded;
} else {
total.size = undef;
}
if (file.status == plupload.DONE) {
total.uploaded++;
} else if (file.status == plupload.FAILED) {
total.failed++;
} else {
total.queued++;
}
}
// If we couldn't calculate a total file size then use the number of files to calc percent
if (total.size === undef) {
total.percent = files.length > 0 ? Math.ceil(total.uploaded / files.length * 100) : 0;
} else {
total.bytesPerSec = Math.ceil(loadedDuringCurrentSession / ((+new Date() - startTime || 1) / 1000.0));
total.percent = total.size > 0 ? Math.ceil(total.loaded / total.size * 100) : 0;
}
}
function getRUID() {
var ctrl = fileInputs[0] || fileDrops[0];
if (ctrl) {
return ctrl.getRuntime().uid;
}
return false;
}
function bindEventListeners() {
this.bind('FilesAdded FilesRemoved', function(up) {
up.trigger('QueueChanged');
up.refresh();
});
this.bind('CancelUpload', onCancelUpload);
this.bind('BeforeUpload', onBeforeUpload);
this.bind('UploadFile', onUploadFile);
this.bind('UploadProgress', onUploadProgress);
this.bind('StateChanged', onStateChanged);
this.bind('QueueChanged', calc);
this.bind('Error', onError);
this.bind('FileUploaded', onFileUploaded);
this.bind('Destroy', onDestroy);
}
function initControls(settings, cb) {
var self = this, inited = 0, queue = [];
// common settings
var options = {
runtime_order: settings.runtimes,
required_caps: settings.required_features,
preferred_caps: preferred_caps,
swf_url: settings.flash_swf_url,
xap_url: settings.silverlight_xap_url
};
// add runtime specific options if any
plupload.each(settings.runtimes.split(/\s*,\s*/), function(runtime) {
if (settings[runtime]) {
options[runtime] = settings[runtime];
}
});
// initialize file pickers - there can be many
if (settings.browse_button) {
plupload.each(settings.browse_button, function(el) {
queue.push(function(cb) {
var fileInput = new o.file.FileInput(plupload.extend({}, options, {
accept: settings.filters.mime_types,
name: settings.file_data_name,
multiple: settings.multi_selection,
container: settings.container,
browse_button: el
}));
fileInput.onready = function() {
var info = Runtime.getInfo(this.ruid);
// for backward compatibility
plupload.extend(self.features, {
chunks: info.can('slice_blob'),
multipart: info.can('send_multipart'),
multi_selection: info.can('select_multiple')
});
inited++;
fileInputs.push(this);
cb();
};
fileInput.onchange = function() {
self.addFile(this.files);
};
fileInput.bind('mouseenter mouseleave mousedown mouseup', function(e) {
if (!disabled) {
if (settings.browse_button_hover) {
if ('mouseenter' === e.type) {
plupload.addClass(el, settings.browse_button_hover);
} else if ('mouseleave' === e.type) {
plupload.removeClass(el, settings.browse_button_hover);
}
}
if (settings.browse_button_active) {
if ('mousedown' === e.type) {
plupload.addClass(el, settings.browse_button_active);
} else if ('mouseup' === e.type) {
plupload.removeClass(el, settings.browse_button_active);
}
}
}
});
fileInput.bind('mousedown', function() {
self.trigger('Browse');
});
fileInput.bind('error runtimeerror', function() {
fileInput = null;
cb();
});
fileInput.init();
});
});
}
// initialize drop zones
if (settings.drop_element) {
plupload.each(settings.drop_element, function(el) {
queue.push(function(cb) {
var fileDrop = new o.file.FileDrop(plupload.extend({}, options, {
drop_zone: el
}));
fileDrop.onready = function() {
var info = Runtime.getInfo(this.ruid);
// for backward compatibility
plupload.extend(self.features, {
chunks: info.can('slice_blob'),
multipart: info.can('send_multipart'),
dragdrop: info.can('drag_and_drop')
});
inited++;
fileDrops.push(this);
cb();
};
fileDrop.ondrop = function() {
self.addFile(this.files);
};
fileDrop.bind('error runtimeerror', function() {
fileDrop = null;
cb();
});
fileDrop.init();
});
});
}
plupload.inSeries(queue, function() {
if (typeof(cb) === 'function') {
cb(inited);
}
});
}
function resizeImage(blob, params, runtimeOptions, cb) {
var img = new o.image.Image();
try {
img.onload = function() {
// no manipulation required if...
if (params.width > this.width &&
params.height > this.height &&
params.quality === undef &&
params.preserve_headers &&
!params.crop
) {
this.destroy();
cb(blob);
} else {
// otherwise downsize
img.downsize(params.width, params.height, params.crop, params.preserve_headers);
}
};
img.onresize = function() {
var resizedBlob = this.getAsBlob(blob.type, params.quality);
this.destroy();
cb(resizedBlob);
};
img.bind('error runtimeerror', function() {
this.destroy();
cb(blob);
});
img.load(blob, runtimeOptions);
} catch(ex) {
cb(blob);
}
}
function setOption(option, value, init) {
var self = this, reinitRequired = false;
function _setOption(option, value, init) {
var oldValue = settings[option];
switch (option) {
case 'max_file_size':
if (option === 'max_file_size') {
settings.max_file_size = settings.filters.max_file_size = value;
}
break;
case 'chunk_size':
if (value = plupload.parseSize(value)) {
settings[option] = value;
settings.send_file_name = true;
}
break;
case 'multipart':
settings[option] = value;
if (!value) {
settings.send_file_name = true;
}
break;
case 'http_method':
settings[option] = value.toUpperCase() === 'PUT' ? 'PUT' : 'POST';
break;
case 'unique_names':
settings[option] = value;
if (value) {
settings.send_file_name = true;
}
break;
case 'filters':
// for sake of backward compatibility
if (plupload.typeOf(value) === 'array') {
value = {
mime_types: value
};
}
if (init) {
plupload.extend(settings.filters, value);
} else {
settings.filters = value;
}
// if file format filters are being updated, regenerate the matching expressions
if (value.mime_types) {
if (plupload.typeOf(value.mime_types) === 'string') {
value.mime_types = o.core.utils.Mime.mimes2extList(value.mime_types);
}
value.mime_types.regexp = (function(filters) {
var extensionsRegExp = [];
plupload.each(filters, function(filter) {
plupload.each(filter.extensions.split(/,/), function(ext) {
if (/^\s*\*\s*$/.test(ext)) {
extensionsRegExp.push('\\.*');
} else {
extensionsRegExp.push('\\.' + ext.replace(new RegExp('[' + ('/^$.*+?|()[]{}\\'.replace(/./g, '\\$&')) + ']', 'g'), '\\$&'));
}
});
});
return new RegExp('(' + extensionsRegExp.join('|') + ')$', 'i');
}(value.mime_types));
settings.filters.mime_types = value.mime_types;
}
break;
case 'resize':
if (value) {
settings.resize = plupload.extend({
preserve_headers: true,
crop: false
}, value);
} else {
settings.resize = false;
}
break;
case 'prevent_duplicates':
settings.prevent_duplicates = settings.filters.prevent_duplicates = !!value;
break;
// options that require reinitialisation
case 'container':
case 'browse_button':
case 'drop_element':
value = 'container' === option
? plupload.get(value)
: plupload.getAll(value)
;
case 'runtimes':
case 'multi_selection':
case 'flash_swf_url':
case 'silverlight_xap_url':
settings[option] = value;
if (!init) {
reinitRequired = true;
}
break;
default:
settings[option] = value;
}
if (!init) {
self.trigger('OptionChanged', option, value, oldValue);
}
}
if (typeof(option) === 'object') {
plupload.each(option, function(value, option) {
_setOption(option, value, init);
});
} else {
_setOption(option, value, init);
}
if (init) {
// Normalize the list of required capabilities
settings.required_features = normalizeCaps(plupload.extend({}, settings));
// Come up with the list of capabilities that can affect default mode in a multi-mode runtimes
preferred_caps = normalizeCaps(plupload.extend({}, settings, {
required_features: true
}));
} else if (reinitRequired) {
self.trigger('Destroy');
initControls.call(self, settings, function(inited) {
if (inited) {
self.runtime = Runtime.getInfo(getRUID()).type;
self.trigger('Init', { runtime: self.runtime });
self.trigger('PostInit');
} else {
self.trigger('Error', {
code : plupload.INIT_ERROR,
message : plupload.translate('Init error.')
});
}
});
}
}
// Internal event handlers
function onBeforeUpload(up, file) {
// Generate unique target filenames
if (up.settings.unique_names) {
var matches = file.name.match(/\.([^.]+)$/), ext = "part";
if (matches) {
ext = matches[1];
}
file.target_name = file.id + '.' + ext;
}
}
function onUploadFile(up, file) {
var url = up.settings.url;
var chunkSize = up.settings.chunk_size;
var retries = up.settings.max_retries;
var features = up.features;
var offset = 0;
var blob;
var runtimeOptions = {
runtime_order: up.settings.runtimes,
required_caps: up.settings.required_features,
preferred_caps: preferred_caps,
swf_url: up.settings.flash_swf_url,
xap_url: up.settings.silverlight_xap_url
};
// make sure we start at a predictable offset
if (file.loaded) {
offset = file.loaded = chunkSize ? chunkSize * Math.floor(file.loaded / chunkSize) : 0;
}
function handleError() {
if (retries-- > 0) {
delay(uploadNextChunk, 1000);
} else {
file.loaded = offset; // reset all progress
up.trigger('Error', {
code : plupload.HTTP_ERROR,
message : plupload.translate('HTTP Error.'),
file : file,
response : xhr.responseText,
status : xhr.status,
responseHeaders: xhr.getAllResponseHeaders()
});
}
}
function uploadNextChunk() {
var chunkBlob, args = {}, curChunkSize;
// make sure that file wasn't cancelled and upload is not stopped in general
if (file.status !== plupload.UPLOADING || up.state === plupload.STOPPED) {
return;
}
// send additional 'name' parameter only if required
if (up.settings.send_file_name) {
args.name = file.target_name || file.name;
}
if (chunkSize && features.chunks && blob.size > chunkSize) { // blob will be of type string if it was loaded in memory
curChunkSize = Math.min(chunkSize, blob.size - offset);
chunkBlob = blob.slice(offset, offset + curChunkSize);
} else {
curChunkSize = blob.size;
chunkBlob = blob;
}
// If chunking is enabled add corresponding args, no matter if file is bigger than chunk or smaller
if (chunkSize && features.chunks) {
// Setup query string arguments
if (up.settings.send_chunk_number) {
args.chunk = Math.ceil(offset / chunkSize);
args.chunks = Math.ceil(blob.size / chunkSize);
} else { // keep support for experimental chunk format, just in case
args.offset = offset;
args.total = blob.size;
}
}
if (up.trigger('BeforeChunkUpload', file, args, chunkBlob, offset)) {
uploadChunk(args, chunkBlob, curChunkSize);
}
}
function uploadChunk(args, chunkBlob, curChunkSize) {
var formData;
xhr = new o.xhr.XMLHttpRequest();
// Do we have upload progress support
if (xhr.upload) {
xhr.upload.onprogress = function(e) {
file.loaded = Math.min(file.size, offset + e.loaded);
up.trigger('UploadProgress', file);
};
}
xhr.onload = function() {
// check if upload made itself through
if (xhr.status < 200 || xhr.status >= 400) {
handleError();
return;
}
retries = up.settings.max_retries; // reset the counter
// Handle chunk response
if (curChunkSize < blob.size) {
chunkBlob.destroy();
offset += curChunkSize;
file.loaded = Math.min(offset, blob.size);
up.trigger('ChunkUploaded', file, {
offset : file.loaded,
total : blob.size,
response : xhr.responseText,
status : xhr.status,
responseHeaders: xhr.getAllResponseHeaders()
});
// stock Android browser doesn't fire upload progress events, but in chunking mode we can fake them
if (plupload.ua.browser === 'Android Browser') {
// doesn't harm in general, but is not required anywhere else
up.trigger('UploadProgress', file);
}
} else {
file.loaded = file.size;
}
chunkBlob = formData = null; // Free memory
// Check if file is uploaded
if (!offset || offset >= blob.size) {
// If file was modified, destory the copy
if (file.size != file.origSize) {
blob.destroy();
blob = null;
}
up.trigger('UploadProgress', file);
file.status = plupload.DONE;
file.completeTimestamp = +new Date();
up.trigger('FileUploaded', file, {
response : xhr.responseText,
status : xhr.status,
responseHeaders: xhr.getAllResponseHeaders()
});
} else {
// Still chunks left
delay(uploadNextChunk, 1); // run detached, otherwise event handlers interfere
}
};
xhr.onerror = function() {
handleError();
};
xhr.onloadend = function() {
this.destroy();
};
// Build multipart request
if (up.settings.multipart && features.multipart) {
xhr.open(up.settings.http_method, url, true);
// Set custom headers
plupload.each(up.settings.headers, function(value, name) {
xhr.setRequestHeader(name, value);
});
formData = new o.xhr.FormData();
// Add multipart params
plupload.each(plupload.extend(args, up.settings.multipart_params), function(value, name) {
formData.append(name, value);
});
// Add file and send it
formData.append(up.settings.file_data_name, chunkBlob);
xhr.send(formData, runtimeOptions);
} else {
// if no multipart, send as binary stream
url = plupload.buildUrl(up.settings.url, plupload.extend(args, up.settings.multipart_params));
xhr.open(up.settings.http_method, url, true);
// Set custom headers
plupload.each(up.settings.headers, function(value, name) {
xhr.setRequestHeader(name, value);
});
// do not set Content-Type, if it was defined previously (see #1203)
if (!xhr.hasRequestHeader('Content-Type')) {
xhr.setRequestHeader('Content-Type', 'application/octet-stream'); // Binary stream header
}
xhr.send(chunkBlob, runtimeOptions);
}
}
blob = file.getSource();
// Start uploading chunks
if (!plupload.isEmptyObj(up.settings.resize) && plupload.inArray(blob.type, ['image/jpeg', 'image/png']) !== -1) {
// Resize if required
resizeImage(blob, up.settings.resize, runtimeOptions, function(resizedBlob) {
blob = resizedBlob;
file.size = resizedBlob.size;
uploadNextChunk();
});
} else {
uploadNextChunk();
}
}
function onUploadProgress(up, file) {
calcFile(file);
}
function onStateChanged(up) {
if (up.state == plupload.STARTED) {
// Get start time to calculate bps
startTime = (+new Date());
} else if (up.state == plupload.STOPPED) {
// Reset currently uploading files
for (var i = up.files.length - 1; i >= 0; i--) {
if (up.files[i].status == plupload.UPLOADING) {
up.files[i].status = plupload.QUEUED;
calc();
}
}
}
}
function onCancelUpload() {
if (xhr) {
xhr.abort();
}
}
function onFileUploaded(up) {
calc();
// Upload next file but detach it from the error event
// since other custom listeners might want to stop the queue
delay(function() {
uploadNext.call(up);
}, 1);
}
function onError(up, err) {
if (err.code === plupload.INIT_ERROR) {
up.destroy();
}
// Set failed status if an error occured on a file
else if (err.code === plupload.HTTP_ERROR) {
err.file.status = plupload.FAILED;
err.file.completeTimestamp = +new Date();
calcFile(err.file);
// Upload next file but detach it from the error event
// since other custom listeners might want to stop the queue
if (up.state == plupload.STARTED) { // upload in progress
up.trigger('CancelUpload');
delay(function() {
uploadNext.call(up);
}, 1);
}
}
}
function onDestroy(up) {
up.stop();
// Purge the queue
plupload.each(files, function(file) {
file.destroy();
});
files = [];
if (fileInputs.length) {
plupload.each(fileInputs, function(fileInput) {
fileInput.destroy();
});
fileInputs = [];
}
if (fileDrops.length) {
plupload.each(fileDrops, function(fileDrop) {
fileDrop.destroy();
});
fileDrops = [];
}
preferred_caps = {};
disabled = false;
startTime = xhr = null;
total.reset();
}
// Default settings
settings = {
chunk_size: 0,
file_data_name: 'file',
filters: {
mime_types: [],
max_file_size: 0,
prevent_duplicates: false,
prevent_empty: true
},
flash_swf_url: 'js/Moxie.swf',
http_method: 'POST',
max_retries: 0,
multipart: true,
multi_selection: true,
resize: false,
runtimes: Runtime.order,
send_file_name: true,
send_chunk_number: true,
silverlight_xap_url: 'js/Moxie.xap'
};
setOption.call(this, options, null, true);
// Inital total state
total = new plupload.QueueProgress();
// Add public methods
plupload.extend(this, {
/**
* Unique id for the Uploader instance.
*
* @property id
* @type String
*/
id : uid,
uid : uid, // mOxie uses this to differentiate between event targets
/**
* Current state of the total uploading progress. This one can either be plupload.STARTED or plupload.STOPPED.
* These states are controlled by the stop/start methods. The default value is STOPPED.
*
* @property state
* @type Number
*/
state : plupload.STOPPED,
/**
* Map of features that are available for the uploader runtime. Features will be filled
* before the init event is called, these features can then be used to alter the UI for the end user.
* Some of the current features that might be in this map is: dragdrop, chunks, jpgresize, pngresize.
*
* @property features
* @type Object
*/
features : {},
/**
* Current runtime name.
*
* @property runtime
* @type String
*/
runtime : null,
/**
* Current upload queue, an array of File instances.
*
* @property files
* @type Array
* @see plupload.File
*/
files : files,
/**
* Object with name/value settings.
*
* @property settings
* @type Object
*/
settings : settings,
/**
* Total progess information. How many files has been uploaded, total percent etc.
*
* @property total
* @type plupload.QueueProgress
*/
total : total,
/**
* Initializes the Uploader instance and adds internal event listeners.
*
* @method init
*/
init : function() {
var self = this, opt, preinitOpt, err;
preinitOpt = self.getOption('preinit');
if (typeof(preinitOpt) == "function") {
preinitOpt(self);
} else {
plupload.each(preinitOpt, function(func, name) {
self.bind(name, func);
});
}
bindEventListeners.call(self);
// Check for required options
plupload.each(['container', 'browse_button', 'drop_element'], function(el) {
if (self.getOption(el) === null) {
err = {
code : plupload.INIT_ERROR,
message : plupload.sprintf(plupload.translate("%s specified, but cannot be found."), el)
}
return false;
}
});
if (err) {
return self.trigger('Error', err);
}
if (!settings.browse_button && !settings.drop_element) {
return self.trigger('Error', {
code : plupload.INIT_ERROR,
message : plupload.translate("You must specify either browse_button or drop_element.")
});
}
initControls.call(self, settings, function(inited) {
var initOpt = self.getOption('init');
if (typeof(initOpt) == "function") {
initOpt(self);
} else {
plupload.each(initOpt, function(func, name) {
self.bind(name, func);
});
}
if (inited) {
self.runtime = Runtime.getInfo(getRUID()).type;
self.trigger('Init', { runtime: self.runtime });
self.trigger('PostInit');
} else {
self.trigger('Error', {
code : plupload.INIT_ERROR,
message : plupload.translate('Init error.')
});
}
});
},
/**
* Set the value for the specified option(s).
*
* @method setOption
* @since 2.1
* @param {String|Object} option Name of the option to change or the set of key/value pairs
* @param {Mixed} [value] Value for the option (is ignored, if first argument is object)
*/
setOption: function(option, value) {
setOption.call(this, option, value, !this.runtime); // until runtime not set we do not need to reinitialize
},
/**
* Get the value for the specified option or the whole configuration, if not specified.
*
* @method getOption
* @since 2.1
* @param {String} [option] Name of the option to get
* @return {Mixed} Value for the option or the whole set
*/
getOption: function(option) {
if (!option) {
return settings;
}
return settings[option];
},
/**
* Refreshes the upload instance by dispatching out a refresh event to all runtimes.
* This would for example reposition flash/silverlight shims on the page.
*
* @method refresh
*/
refresh : function() {
if (fileInputs.length) {
plupload.each(fileInputs, function(fileInput) {
fileInput.trigger('Refresh');
});
}
this.trigger('Refresh');
},
/**
* Starts uploading the queued files.
*
* @method start
*/
start : function() {
if (this.state != plupload.STARTED) {
this.state = plupload.STARTED;
this.trigger('StateChanged');
uploadNext.call(this);
}
},
/**
* Stops the upload of the queued files.
*
* @method stop
*/
stop : function() {
if (this.state != plupload.STOPPED) {
this.state = plupload.STOPPED;
this.trigger('StateChanged');
this.trigger('CancelUpload');
}
},
/**
* Disables/enables browse button on request.
*
* @method disableBrowse
* @param {Boolean} disable Whether to disable or enable (default: true)
*/
disableBrowse : function() {
disabled = arguments[0] !== undef ? arguments[0] : true;
if (fileInputs.length) {
plupload.each(fileInputs, function(fileInput) {
fileInput.disable(disabled);
});
}
this.trigger('DisableBrowse', disabled);
},
/**
* Returns the specified file object by id.
*
* @method getFile
* @param {String} id File id to look for.
* @return {plupload.File} File object or undefined if it wasn't found;
*/
getFile : function(id) {
var i;
for (i = files.length - 1; i >= 0; i--) {
if (files[i].id === id) {
return files[i];
}
}
},
/**
* Adds file to the queue programmatically. Can be native file, instance of Plupload.File,
* instance of mOxie.File, input[type="file"] element, or array of these. Fires FilesAdded,
* if any files were added to the queue. Otherwise nothing happens.
*
* @method addFile
* @since 2.0
* @param {plupload.File|mOxie.File|File|Node|Array} file File or files to add to the queue.
* @param {String} [fileName] If specified, will be used as a name for the file
*/
addFile : function(file, fileName) {
var self = this
, queue = []
, filesAdded = []
, ruid
;
function filterFile(file, cb) {
var queue = [];
plupload.each(self.settings.filters, function(rule, name) {
if (fileFilters[name]) {
queue.push(function(cb) {
fileFilters[name].call(self, rule, file, function(res) {
cb(!res);
});
});
}
});
plupload.inSeries(queue, cb);
}
/**
* @method resolveFile
* @private
* @param {moxie.file.File|moxie.file.Blob|plupload.File|File|Blob|input[type="file"]} file
*/
function resolveFile(file) {
var type = plupload.typeOf(file);
// moxie.file.File
if (file instanceof o.file.File) {
if (!file.ruid && !file.isDetached()) {
if (!ruid) { // weird case
return false;
}
file.ruid = ruid;
file.connectRuntime(ruid);
}
resolveFile(new plupload.File(file));
}
// moxie.file.Blob
else if (file instanceof o.file.Blob) {
resolveFile(file.getSource());
file.destroy();
}
// plupload.File - final step for other branches
else if (file instanceof plupload.File) {
if (fileName) {
file.name = fileName;
}
queue.push(function(cb) {
// run through the internal and user-defined filters, if any
filterFile(file, function(err) {
if (!err) {
// make files available for the filters by updating the main queue directly
files.push(file);
// collect the files that will be passed to FilesAdded event
filesAdded.push(file);
self.trigger("FileFiltered", file);
}
delay(cb, 1); // do not build up recursions or eventually we might hit the limits
});
});
}
// native File or blob
else if (plupload.inArray(type, ['file', 'blob']) !== -1) {
resolveFile(new o.file.File(null, file));
}
// input[type="file"]
else if (type === 'node' && plupload.typeOf(file.files) === 'filelist') {
// if we are dealing with input[type="file"]
plupload.each(file.files, resolveFile);
}
// mixed array of any supported types (see above)
else if (type === 'array') {
fileName = null; // should never happen, but unset anyway to avoid funny situations
plupload.each(file, resolveFile);
}
}
ruid = getRUID();
resolveFile(file);
if (queue.length) {
plupload.inSeries(queue, function() {
// if any files left after filtration, trigger FilesAdded
if (filesAdded.length) {
self.trigger("FilesAdded", filesAdded);
}
});
}
},
/**
* Removes a specific file.
*
* @method removeFile
* @param {plupload.File|String} file File to remove from queue.
*/
removeFile : function(file) {
var id = typeof(file) === 'string' ? file : file.id;
for (var i = files.length - 1; i >= 0; i--) {
if (files[i].id === id) {
return this.splice(i, 1)[0];
}
}
},
/**
* Removes part of the queue and returns the files removed. This will also trigger the
* FilesRemoved and QueueChanged events.
*
* @method splice
* @param {Number} [start=0] Start index to remove from.
* @param {Number} [length] Number of files to remove (defaults to number of files in the queue).
* @return {Array} Array of files that was removed.
*/
splice : function(start, length) {
// Splice and trigger events
var removed = files.splice(start === undef ? 0 : start, length === undef ? files.length : length);
// if upload is in progress we need to stop it and restart after files are removed
var restartRequired = false;
if (this.state == plupload.STARTED) { // upload in progress
plupload.each(removed, function(file) {
if (file.status === plupload.UPLOADING) {
restartRequired = true; // do not restart, unless file that is being removed is uploading
return false;
}
});
if (restartRequired) {
this.stop();
}
}
this.trigger("FilesRemoved", removed);
// Dispose any resources allocated by those files
plupload.each(removed, function(file) {
file.destroy();
});
if (restartRequired) {
this.start();
}
return removed;
},
/**
Dispatches the specified event name and its arguments to all listeners.
@method trigger
@param {String} name Event name to fire.
@param {Object..} Multiple arguments to pass along to the listener functions.
*/
// override the parent method to match Plupload-like event logic
dispatchEvent: function(type) {
var list, args, result;
type = type.toLowerCase();
list = this.hasEventListener(type);
if (list) {
// sort event list by priority
list.sort(function(a, b) { return b.priority - a.priority; });
// first argument should be current plupload.Uploader instance
args = [].slice.call(arguments);
args.shift();
args.unshift(this);
for (var i = 0; i < list.length; i++) {
// Fire event, break chain if false is returned
if (list[i].fn.apply(list[i].scope, args) === false) {
return false;
}
}
}
return true;
},
/**
Check whether uploader has any listeners to the specified event.
@method hasEventListener
@param {String} name Event name to check for.
*/
/**
Adds an event listener by name.
@method bind
@param {String} name Event name to listen for.
@param {function} fn Function to call ones the event gets fired.
@param {Object} [scope] Optional scope to execute the specified function in.
@param {Number} [priority=0] Priority of the event handler - handlers with higher priorities will be called first
*/
bind: function(name, fn, scope, priority) {
// adapt moxie EventTarget style to Plupload-like
plupload.Uploader.prototype.bind.call(this, name, fn, priority, scope);
},
/**
Removes the specified event listener.
@method unbind
@param {String} name Name of event to remove.
@param {function} fn Function to remove from listener.
*/
/**
Removes all event listeners.
@method unbindAll
*/
/**
* Destroys Plupload instance and cleans after itself.
*
* @method destroy
*/
destroy : function() {
this.trigger('Destroy');
settings = total = null; // purge these exclusively
this.unbindAll();
}
});
};
plupload.Uploader.prototype = o.core.EventTarget.instance;
/**
* Constructs a new file instance.
*
* @class File
* @constructor
*
* @param {Object} file Object containing file properties
* @param {String} file.name Name of the file.
* @param {Number} file.size File size.
*/
plupload.File = (function() {
var filepool = {};
function PluploadFile(file) {
plupload.extend(this, {
/**
* File id this is a globally unique id for the specific file.
*
* @property id
* @type String
*/
id: plupload.guid(),
/**
* File name for example "myfile.gif".
*
* @property name
* @type String
*/
name: file.name || file.fileName,
/**
* File type, `e.g image/jpeg`
*
* @property type
* @type String
*/
type: file.type || '',
/**
* Relative path to the file inside a directory
*
* @property relativePath
* @type String
* @default ''
*/
relativePath: file.relativePath || '',
/**
* File size in bytes (may change after client-side manupilation).
*
* @property size
* @type Number
*/
size: file.fileSize || file.size,
/**
* Original file size in bytes.
*
* @property origSize
* @type Number
*/
origSize: file.fileSize || file.size,
/**
* Number of bytes uploaded of the files total size.
*
* @property loaded
* @type Number
*/
loaded: 0,
/**
* Number of percentage uploaded of the file.
*
* @property percent
* @type Number
*/
percent: 0,
/**
* Status constant matching the plupload states QUEUED, UPLOADING, FAILED, DONE.
*
* @property status
* @type Number
* @see plupload
*/
status: plupload.QUEUED,
/**
* Date of last modification.
*
* @property lastModifiedDate
* @type {String}
*/
lastModifiedDate: file.lastModifiedDate || (new Date()).toLocaleString(), // Thu Aug 23 2012 19:40:00 GMT+0400 (GET)
/**
* Set when file becomes plupload.DONE or plupload.FAILED. Is used to calculate proper plupload.QueueProgress.bytesPerSec.
* @private
* @property completeTimestamp
* @type {Number}
*/
completeTimestamp: 0,
/**
* Returns native window.File object, when it's available.
*
* @method getNative
* @return {window.File} or null, if plupload.File is of different origin
*/
getNative: function() {
var file = this.getSource().getSource();
return plupload.inArray(plupload.typeOf(file), ['blob', 'file']) !== -1 ? file : null;
},
/**
* Returns mOxie.File - unified wrapper object that can be used across runtimes.
*
* @method getSource
* @return {mOxie.File} or null
*/
getSource: function() {
if (!filepool[this.id]) {
return null;
}
return filepool[this.id];
},
/**
* Destroys plupload.File object.
*
* @method destroy
*/
destroy: function() {
var src = this.getSource();
if (src) {
src.destroy();
delete filepool[this.id];
}
}
});
filepool[this.id] = file;
}
return PluploadFile;
}());
/**
* Constructs a queue progress.
*
* @class QueueProgress
* @constructor
*/
plupload.QueueProgress = function() {
var self = this; // Setup alias for self to reduce code size when it's compressed
/**
* Total queue file size.
*
* @property size
* @type Number
*/
self.size = 0;
/**
* Total bytes uploaded.
*
* @property loaded
* @type Number
*/
self.loaded = 0;
/**
* Number of files uploaded.
*
* @property uploaded
* @type Number
*/
self.uploaded = 0;
/**
* Number of files failed to upload.
*
* @property failed
* @type Number
*/
self.failed = 0;
/**
* Number of files yet to be uploaded.
*
* @property queued
* @type Number
*/
self.queued = 0;
/**
* Total percent of the uploaded bytes.
*
* @property percent
* @type Number
*/
self.percent = 0;
/**
* Bytes uploaded per second.
*
* @property bytesPerSec
* @type Number
*/
self.bytesPerSec = 0;
/**
* Resets the progress to its initial values.
*
* @method reset
*/
self.reset = function() {
self.size = self.loaded = self.uploaded = self.failed = self.queued = self.percent = self.bytesPerSec = 0;
};
};
exports.plupload = plupload;
}(this, moxie));
}));
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
/**
* Plupload - multi-runtime File Uploader
* v2.3.6
*
* Copyright 2013, Moxiecode Systems AB
* Released under GPL License.
*
* License: http://www.plupload.com/license
* Contributing: http://www.plupload.com/contributing
*
* Date: 2017-11-03
*/
!function(e,t){var i=function(){var e={};return t.apply(e,arguments),e.plupload};"function"==typeof define&&define.amd?define("plupload",["./moxie"],i):"object"==typeof module&&module.exports?module.exports=i(require("./moxie")):e.plupload=i(e.moxie)}(this||window,function(e){!function(e,t,i){function n(e){function t(e,t,i){var r={chunks:"slice_blob",jpgresize:"send_binary_string",pngresize:"send_binary_string",progress:"report_upload_progress",multi_selection:"select_multiple",dragdrop:"drag_and_drop",drop_element:"drag_and_drop",headers:"send_custom_headers",urlstream_upload:"send_binary_string",canSendBinary:"send_binary",triggerDialog:"summon_file_dialog"};r[e]?n[r[e]]=t:i||(n[e]=t)}var i=e.required_features,n={};return"string"==typeof i?l.each(i.split(/\s*,\s*/),function(e){t(e,!0)}):"object"==typeof i?l.each(i,function(e,i){t(i,e)}):i===!0&&(e.chunk_size&&e.chunk_size>0&&(n.slice_blob=!0),l.isEmptyObj(e.resize)&&e.multipart!==!1||(n.send_binary_string=!0),e.http_method&&(n.use_http_method=e.http_method),l.each(e,function(e,i){t(i,!!e,!0)})),n}var r=window.setTimeout,s={},a=t.core.utils,o=t.runtime.Runtime,l={VERSION:"2.3.6",STOPPED:1,STARTED:2,QUEUED:1,UPLOADING:2,FAILED:4,DONE:5,GENERIC_ERROR:-100,HTTP_ERROR:-200,IO_ERROR:-300,SECURITY_ERROR:-400,INIT_ERROR:-500,FILE_SIZE_ERROR:-600,FILE_EXTENSION_ERROR:-601,FILE_DUPLICATE_ERROR:-602,IMAGE_FORMAT_ERROR:-700,MEMORY_ERROR:-701,IMAGE_DIMENSIONS_ERROR:-702,moxie:t,mimeTypes:a.Mime.mimes,ua:a.Env,typeOf:a.Basic.typeOf,extend:a.Basic.extend,guid:a.Basic.guid,getAll:function(e){var t,i=[];"array"!==l.typeOf(e)&&(e=[e]);for(var n=e.length;n--;)t=l.get(e[n]),t&&i.push(t);return i.length?i:null},get:a.Dom.get,each:a.Basic.each,getPos:a.Dom.getPos,getSize:a.Dom.getSize,xmlEncode:function(e){var t={"<":"lt",">":"gt","&":"amp",'"':"quot","'":"#39"},i=/[<>&\"\']/g;return e?(""+e).replace(i,function(e){return t[e]?"&"+t[e]+";":e}):e},toArray:a.Basic.toArray,inArray:a.Basic.inArray,inSeries:a.Basic.inSeries,addI18n:t.core.I18n.addI18n,translate:t.core.I18n.translate,sprintf:a.Basic.sprintf,isEmptyObj:a.Basic.isEmptyObj,hasClass:a.Dom.hasClass,addClass:a.Dom.addClass,removeClass:a.Dom.removeClass,getStyle:a.Dom.getStyle,addEvent:a.Events.addEvent,removeEvent:a.Events.removeEvent,removeAllEvents:a.Events.removeAllEvents,cleanName:function(e){var t,i;for(i=[/[\300-\306]/g,"A",/[\340-\346]/g,"a",/\307/g,"C",/\347/g,"c",/[\310-\313]/g,"E",/[\350-\353]/g,"e",/[\314-\317]/g,"I",/[\354-\357]/g,"i",/\321/g,"N",/\361/g,"n",/[\322-\330]/g,"O",/[\362-\370]/g,"o",/[\331-\334]/g,"U",/[\371-\374]/g,"u"],t=0;t<i.length;t+=2)e=e.replace(i[t],i[t+1]);return e=e.replace(/\s+/g,"_"),e=e.replace(/[^a-z0-9_\-\.]+/gi,"")},buildUrl:function(e,t){var i="";return l.each(t,function(e,t){i+=(i?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(e)}),i&&(e+=(e.indexOf("?")>0?"&":"?")+i),e},formatSize:function(e){function t(e,t){return Math.round(e*Math.pow(10,t))/Math.pow(10,t)}if(e===i||/\D/.test(e))return l.translate("N/A");var n=Math.pow(1024,4);return e>n?t(e/n,1)+" "+l.translate("tb"):e>(n/=1024)?t(e/n,1)+" "+l.translate("gb"):e>(n/=1024)?t(e/n,1)+" "+l.translate("mb"):e>1024?Math.round(e/1024)+" "+l.translate("kb"):e+" "+l.translate("b")},parseSize:a.Basic.parseSizeStr,predictRuntime:function(e,t){var i,n;return i=new l.Uploader(e),n=o.thatCan(i.getOption().required_features,t||e.runtimes),i.destroy(),n},addFileFilter:function(e,t){s[e]=t}};l.addFileFilter("mime_types",function(e,t,i){e.length&&!e.regexp.test(t.name)?(this.trigger("Error",{code:l.FILE_EXTENSION_ERROR,message:l.translate("File extension error."),file:t}),i(!1)):i(!0)}),l.addFileFilter("max_file_size",function(e,t,i){var n;e=l.parseSize(e),t.size!==n&&e&&t.size>e?(this.trigger("Error",{code:l.FILE_SIZE_ERROR,message:l.translate("File size error."),file:t}),i(!1)):i(!0)}),l.addFileFilter("prevent_duplicates",function(e,t,i){if(e)for(var n=this.files.length;n--;)if(t.name===this.files[n].name&&t.size===this.files[n].size)return this.trigger("Error",{code:l.FILE_DUPLICATE_ERROR,message:l.translate("Duplicate file error."),file:t}),i(!1),void 0;i(!0)}),l.addFileFilter("prevent_empty",function(e,t,n){e&&!t.size&&t.size!==i?(this.trigger("Error",{code:l.FILE_SIZE_ERROR,message:l.translate("File size error."),file:t}),n(!1)):n(!0)}),l.Uploader=function(e){function a(){var e,t,i=0;if(this.state==l.STARTED){for(t=0;t<D.length;t++)e||D[t].status!=l.QUEUED?i++:(e=D[t],this.trigger("BeforeUpload",e)&&(e.status=l.UPLOADING,this.trigger("UploadFile",e)));i==D.length&&(this.state!==l.STOPPED&&(this.state=l.STOPPED,this.trigger("StateChanged")),this.trigger("UploadComplete",D))}}function u(e){e.percent=e.size>0?Math.ceil(100*(e.loaded/e.size)):100,d()}function d(){var e,t,n,r=0;for(I.reset(),e=0;e<D.length;e++)t=D[e],t.size!==i?(I.size+=t.origSize,n=t.loaded*t.origSize/t.size,(!t.completeTimestamp||t.completeTimestamp>S)&&(r+=n),I.loaded+=n):I.size=i,t.status==l.DONE?I.uploaded++:t.status==l.FAILED?I.failed++:I.queued++;I.size===i?I.percent=D.length>0?Math.ceil(100*(I.uploaded/D.length)):0:(I.bytesPerSec=Math.ceil(r/((+new Date-S||1)/1e3)),I.percent=I.size>0?Math.ceil(100*(I.loaded/I.size)):0)}function c(){var e=F[0]||P[0];return e?e.getRuntime().uid:!1}function f(){this.bind("FilesAdded FilesRemoved",function(e){e.trigger("QueueChanged"),e.refresh()}),this.bind("CancelUpload",b),this.bind("BeforeUpload",m),this.bind("UploadFile",_),this.bind("UploadProgress",E),this.bind("StateChanged",v),this.bind("QueueChanged",d),this.bind("Error",R),this.bind("FileUploaded",y),this.bind("Destroy",z)}function p(e,i){var n=this,r=0,s=[],a={runtime_order:e.runtimes,required_caps:e.required_features,preferred_caps:x,swf_url:e.flash_swf_url,xap_url:e.silverlight_xap_url};l.each(e.runtimes.split(/\s*,\s*/),function(t){e[t]&&(a[t]=e[t])}),e.browse_button&&l.each(e.browse_button,function(i){s.push(function(s){var u=new t.file.FileInput(l.extend({},a,{accept:e.filters.mime_types,name:e.file_data_name,multiple:e.multi_selection,container:e.container,browse_button:i}));u.onready=function(){var e=o.getInfo(this.ruid);l.extend(n.features,{chunks:e.can("slice_blob"),multipart:e.can("send_multipart"),multi_selection:e.can("select_multiple")}),r++,F.push(this),s()},u.onchange=function(){n.addFile(this.files)},u.bind("mouseenter mouseleave mousedown mouseup",function(t){U||(e.browse_button_hover&&("mouseenter"===t.type?l.addClass(i,e.browse_button_hover):"mouseleave"===t.type&&l.removeClass(i,e.browse_button_hover)),e.browse_button_active&&("mousedown"===t.type?l.addClass(i,e.browse_button_active):"mouseup"===t.type&&l.removeClass(i,e.browse_button_active)))}),u.bind("mousedown",function(){n.trigger("Browse")}),u.bind("error runtimeerror",function(){u=null,s()}),u.init()})}),e.drop_element&&l.each(e.drop_element,function(e){s.push(function(i){var s=new t.file.FileDrop(l.extend({},a,{drop_zone:e}));s.onready=function(){var e=o.getInfo(this.ruid);l.extend(n.features,{chunks:e.can("slice_blob"),multipart:e.can("send_multipart"),dragdrop:e.can("drag_and_drop")}),r++,P.push(this),i()},s.ondrop=function(){n.addFile(this.files)},s.bind("error runtimeerror",function(){s=null,i()}),s.init()})}),l.inSeries(s,function(){"function"==typeof i&&i(r)})}function g(e,n,r,s){var a=new t.image.Image;try{a.onload=function(){n.width>this.width&&n.height>this.height&&n.quality===i&&n.preserve_headers&&!n.crop?(this.destroy(),s(e)):a.downsize(n.width,n.height,n.crop,n.preserve_headers)},a.onresize=function(){var t=this.getAsBlob(e.type,n.quality);this.destroy(),s(t)},a.bind("error runtimeerror",function(){this.destroy(),s(e)}),a.load(e,r)}catch(o){s(e)}}function h(e,i,r){function s(e,i,n){var r=O[e];switch(e){case"max_file_size":"max_file_size"===e&&(O.max_file_size=O.filters.max_file_size=i);break;case"chunk_size":(i=l.parseSize(i))&&(O[e]=i,O.send_file_name=!0);break;case"multipart":O[e]=i,i||(O.send_file_name=!0);break;case"http_method":O[e]="PUT"===i.toUpperCase()?"PUT":"POST";break;case"unique_names":O[e]=i,i&&(O.send_file_name=!0);break;case"filters":"array"===l.typeOf(i)&&(i={mime_types:i}),n?l.extend(O.filters,i):O.filters=i,i.mime_types&&("string"===l.typeOf(i.mime_types)&&(i.mime_types=t.core.utils.Mime.mimes2extList(i.mime_types)),i.mime_types.regexp=function(e){var t=[];return l.each(e,function(e){l.each(e.extensions.split(/,/),function(e){/^\s*\*\s*$/.test(e)?t.push("\\.*"):t.push("\\."+e.replace(new RegExp("["+"/^$.*+?|()[]{}\\".replace(/./g,"\\$&")+"]","g"),"\\$&"))})}),new RegExp("("+t.join("|")+")$","i")}(i.mime_types),O.filters.mime_types=i.mime_types);break;case"resize":O.resize=i?l.extend({preserve_headers:!0,crop:!1},i):!1;break;case"prevent_duplicates":O.prevent_duplicates=O.filters.prevent_duplicates=!!i;break;case"container":case"browse_button":case"drop_element":i="container"===e?l.get(i):l.getAll(i);case"runtimes":case"multi_selection":case"flash_swf_url":case"silverlight_xap_url":O[e]=i,n||(u=!0);break;default:O[e]=i}n||a.trigger("OptionChanged",e,i,r)}var a=this,u=!1;"object"==typeof e?l.each(e,function(e,t){s(t,e,r)}):s(e,i,r),r?(O.required_features=n(l.extend({},O)),x=n(l.extend({},O,{required_features:!0}))):u&&(a.trigger("Destroy"),p.call(a,O,function(e){e?(a.runtime=o.getInfo(c()).type,a.trigger("Init",{runtime:a.runtime}),a.trigger("PostInit")):a.trigger("Error",{code:l.INIT_ERROR,message:l.translate("Init error.")})}))}function m(e,t){if(e.settings.unique_names){var i=t.name.match(/\.([^.]+)$/),n="part";i&&(n=i[1]),t.target_name=t.id+"."+n}}function _(e,i){function n(){c-->0?r(s,1e3):(i.loaded=p,e.trigger("Error",{code:l.HTTP_ERROR,message:l.translate("HTTP Error."),file:i,response:T.responseText,status:T.status,responseHeaders:T.getAllResponseHeaders()}))}function s(){var t,n,r={};i.status===l.UPLOADING&&e.state!==l.STOPPED&&(e.settings.send_file_name&&(r.name=i.target_name||i.name),d&&f.chunks&&o.size>d?(n=Math.min(d,o.size-p),t=o.slice(p,p+n)):(n=o.size,t=o),d&&f.chunks&&(e.settings.send_chunk_number?(r.chunk=Math.ceil(p/d),r.chunks=Math.ceil(o.size/d)):(r.offset=p,r.total=o.size)),e.trigger("BeforeChunkUpload",i,r,t,p)&&a(r,t,n))}function a(a,d,g){var m;T=new t.xhr.XMLHttpRequest,T.upload&&(T.upload.onprogress=function(t){i.loaded=Math.min(i.size,p+t.loaded),e.trigger("UploadProgress",i)}),T.onload=function(){return T.status<200||T.status>=400?(n(),void 0):(c=e.settings.max_retries,g<o.size?(d.destroy(),p+=g,i.loaded=Math.min(p,o.size),e.trigger("ChunkUploaded",i,{offset:i.loaded,total:o.size,response:T.responseText,status:T.status,responseHeaders:T.getAllResponseHeaders()}),"Android Browser"===l.ua.browser&&e.trigger("UploadProgress",i)):i.loaded=i.size,d=m=null,!p||p>=o.size?(i.size!=i.origSize&&(o.destroy(),o=null),e.trigger("UploadProgress",i),i.status=l.DONE,i.completeTimestamp=+new Date,e.trigger("FileUploaded",i,{response:T.responseText,status:T.status,responseHeaders:T.getAllResponseHeaders()})):r(s,1),void 0)},T.onerror=function(){n()},T.onloadend=function(){this.destroy()},e.settings.multipart&&f.multipart?(T.open(e.settings.http_method,u,!0),l.each(e.settings.headers,function(e,t){T.setRequestHeader(t,e)}),m=new t.xhr.FormData,l.each(l.extend(a,e.settings.multipart_params),function(e,t){m.append(t,e)}),m.append(e.settings.file_data_name,d),T.send(m,h)):(u=l.buildUrl(e.settings.url,l.extend(a,e.settings.multipart_params)),T.open(e.settings.http_method,u,!0),l.each(e.settings.headers,function(e,t){T.setRequestHeader(t,e)}),T.hasRequestHeader("Content-Type")||T.setRequestHeader("Content-Type","application/octet-stream"),T.send(d,h))}var o,u=e.settings.url,d=e.settings.chunk_size,c=e.settings.max_retries,f=e.features,p=0,h={runtime_order:e.settings.runtimes,required_caps:e.settings.required_features,preferred_caps:x,swf_url:e.settings.flash_swf_url,xap_url:e.settings.silverlight_xap_url};i.loaded&&(p=i.loaded=d?d*Math.floor(i.loaded/d):0),o=i.getSource(),l.isEmptyObj(e.settings.resize)||-1===l.inArray(o.type,["image/jpeg","image/png"])?s():g(o,e.settings.resize,h,function(e){o=e,i.size=e.size,s()})}function E(e,t){u(t)}function v(e){if(e.state==l.STARTED)S=+new Date;else if(e.state==l.STOPPED)for(var t=e.files.length-1;t>=0;t--)e.files[t].status==l.UPLOADING&&(e.files[t].status=l.QUEUED,d())}function b(){T&&T.abort()}function y(e){d(),r(function(){a.call(e)},1)}function R(e,t){t.code===l.INIT_ERROR?e.destroy():t.code===l.HTTP_ERROR&&(t.file.status=l.FAILED,t.file.completeTimestamp=+new Date,u(t.file),e.state==l.STARTED&&(e.trigger("CancelUpload"),r(function(){a.call(e)},1)))}function z(e){e.stop(),l.each(D,function(e){e.destroy()}),D=[],F.length&&(l.each(F,function(e){e.destroy()}),F=[]),P.length&&(l.each(P,function(e){e.destroy()}),P=[]),x={},U=!1,S=T=null,I.reset()}var O,S,I,T,w=l.guid(),D=[],x={},F=[],P=[],U=!1;O={chunk_size:0,file_data_name:"file",filters:{mime_types:[],max_file_size:0,prevent_duplicates:!1,prevent_empty:!0},flash_swf_url:"js/Moxie.swf",http_method:"POST",max_retries:0,multipart:!0,multi_selection:!0,resize:!1,runtimes:o.order,send_file_name:!0,send_chunk_number:!0,silverlight_xap_url:"js/Moxie.xap"},h.call(this,e,null,!0),I=new l.QueueProgress,l.extend(this,{id:w,uid:w,state:l.STOPPED,features:{},runtime:null,files:D,settings:O,total:I,init:function(){var e,t,i=this;return e=i.getOption("preinit"),"function"==typeof e?e(i):l.each(e,function(e,t){i.bind(t,e)}),f.call(i),l.each(["container","browse_button","drop_element"],function(e){return null===i.getOption(e)?(t={code:l.INIT_ERROR,message:l.sprintf(l.translate("%s specified, but cannot be found."),e)},!1):void 0}),t?i.trigger("Error",t):O.browse_button||O.drop_element?(p.call(i,O,function(e){var t=i.getOption("init");"function"==typeof t?t(i):l.each(t,function(e,t){i.bind(t,e)}),e?(i.runtime=o.getInfo(c()).type,i.trigger("Init",{runtime:i.runtime}),i.trigger("PostInit")):i.trigger("Error",{code:l.INIT_ERROR,message:l.translate("Init error.")})}),void 0):i.trigger("Error",{code:l.INIT_ERROR,message:l.translate("You must specify either browse_button or drop_element.")})},setOption:function(e,t){h.call(this,e,t,!this.runtime)},getOption:function(e){return e?O[e]:O},refresh:function(){F.length&&l.each(F,function(e){e.trigger("Refresh")}),this.trigger("Refresh")},start:function(){this.state!=l.STARTED&&(this.state=l.STARTED,this.trigger("StateChanged"),a.call(this))},stop:function(){this.state!=l.STOPPED&&(this.state=l.STOPPED,this.trigger("StateChanged"),this.trigger("CancelUpload"))},disableBrowse:function(){U=arguments[0]!==i?arguments[0]:!0,F.length&&l.each(F,function(e){e.disable(U)}),this.trigger("DisableBrowse",U)},getFile:function(e){var t;for(t=D.length-1;t>=0;t--)if(D[t].id===e)return D[t]},addFile:function(e,i){function n(e,t){var i=[];l.each(u.settings.filters,function(t,n){s[n]&&i.push(function(i){s[n].call(u,t,e,function(e){i(!e)})})}),l.inSeries(i,t)}function a(e){var s=l.typeOf(e);if(e instanceof t.file.File){if(!e.ruid&&!e.isDetached()){if(!o)return!1;e.ruid=o,e.connectRuntime(o)}a(new l.File(e))}else e instanceof t.file.Blob?(a(e.getSource()),e.destroy()):e instanceof l.File?(i&&(e.name=i),d.push(function(t){n(e,function(i){i||(D.push(e),f.push(e),u.trigger("FileFiltered",e)),r(t,1)})})):-1!==l.inArray(s,["file","blob"])?a(new t.file.File(null,e)):"node"===s&&"filelist"===l.typeOf(e.files)?l.each(e.files,a):"array"===s&&(i=null,l.each(e,a))}var o,u=this,d=[],f=[];o=c(),a(e),d.length&&l.inSeries(d,function(){f.length&&u.trigger("FilesAdded",f)})},removeFile:function(e){for(var t="string"==typeof e?e:e.id,i=D.length-1;i>=0;i--)if(D[i].id===t)return this.splice(i,1)[0]},splice:function(e,t){var n=D.splice(e===i?0:e,t===i?D.length:t),r=!1;return this.state==l.STARTED&&(l.each(n,function(e){return e.status===l.UPLOADING?(r=!0,!1):void 0}),r&&this.stop()),this.trigger("FilesRemoved",n),l.each(n,function(e){e.destroy()}),r&&this.start(),n},dispatchEvent:function(e){var t,i;if(e=e.toLowerCase(),t=this.hasEventListener(e)){t.sort(function(e,t){return t.priority-e.priority}),i=[].slice.call(arguments),i.shift(),i.unshift(this);for(var n=0;n<t.length;n++)if(t[n].fn.apply(t[n].scope,i)===!1)return!1}return!0},bind:function(e,t,i,n){l.Uploader.prototype.bind.call(this,e,t,n,i)},destroy:function(){this.trigger("Destroy"),O=I=null,this.unbindAll()}})},l.Uploader.prototype=t.core.EventTarget.instance,l.File=function(){function e(e){l.extend(this,{id:l.guid(),name:e.name||e.fileName,type:e.type||"",relativePath:e.relativePath||"",size:e.fileSize||e.size,origSize:e.fileSize||e.size,loaded:0,percent:0,status:l.QUEUED,lastModifiedDate:e.lastModifiedDate||(new Date).toLocaleString(),completeTimestamp:0,getNative:function(){var e=this.getSource().getSource();return-1!==l.inArray(l.typeOf(e),["blob","file"])?e:null},getSource:function(){return t[this.id]?t[this.id]:null},destroy:function(){var e=this.getSource();e&&(e.destroy(),delete t[this.id])}}),t[this.id]=e}var t={};return e}(),l.QueueProgress=function(){var e=this;e.size=0,e.loaded=0,e.uploaded=0,e.failed=0,e.queued=0,e.percent=0,e.bytesPerSec=0,e.reset=function(){e.size=e.loaded=e.uploaded=e.failed=e.queued=e.percent=e.bytesPerSec=0}},e.plupload=l}(this,e)});
\ No newline at end of file
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<http://www.gnu.org/licenses/>.
\ No newline at end of file
# Plupload
Plupload is a cross-browser multi-runtime file uploading API. Basically, a set of tools that will help you to
build a reliable and visually appealing file uploader in minutes.
Historically, Plupload comes from a dark and hostile age of no HTML5, hence all the alternative fallbacks,
like Flash, Silverlight and Java (still in development). It is meant to provide an API, that
will work anywhere and in any case, in one way or another. While having very solid fallbacks, Plupload
is built with the future of HTML5 in mind.
### Table of Contents
* [Backstory](#backstory)
* [Structure](#structure)
* [File API and XHR L2 pollyfills](https://github.com/moxiecode/moxie/blob/master/README.md)
* [Plupload API](https://github.com/moxiecode/plupload/wiki/API)
* [UI Widget](https://github.com/moxiecode/plupload/wiki/UI.Plupload)
* [Queue Widget](https://github.com/moxiecode/plupload/wiki/pluploadQueue)
* [Demos](https://github.com/jayarjo/plupload-demos/blob/master/README.md)
* [Building Instructions](#building-instructions)
* [Getting Started](https://github.com/moxiecode/plupload/wiki/Getting-Started)
* [Options](https://github.com/moxiecode/plupload/wiki/Options)
* [Events](https://github.com/moxiecode/plupload/wiki/Uploader#wiki-events)
* [Methods](https://github.com/moxiecode/plupload/wiki/Uploader#wiki-methods)
* [Plupload in Your Language](https://github.com/moxiecode/plupload/wiki/Plupload-in-Your-Language)
* [File Filters](https://github.com/moxiecode/plupload/wiki/File-Filters)
* [Image Resizing on Client-Side](https://github.com/moxiecode/plupload/wiki/Image-Resizing-on-Client-Side)
* [Chunking](https://github.com/moxiecode/plupload/wiki/Chunking)
* [Upload to Amazon S3](https://github.com/moxiecode/plupload/wiki/Upload-to-Amazon-S3)
* [FAQ](https://github.com/moxiecode/plupload/wiki/Frequently-Asked-Questions)
* [Support](#support)
* [Create a Fiddle](https://github.com/moxiecode/plupload/wiki/Create-a-Fiddle)
* [Contributing](#contributing)
* [License](#license)
* [Contact Us](http://www.moxiecode.com/contact.php)
### Backstory
Plupload started in a time when uploading a file in a responsive and customizable manner was a real pain.
Internally, browsers only had the `input[type="file"]` element. It was ugly and clunky at the same time.
One couldn't even change it's visuals, without hiding it and coding another one on top of it from scratch.
And then there was no progress indication for the upload process... Sounds pretty crazy today.
It was very logical for developers to look for alternatives and writing their own implementations, using
Flash and Java, in order to somehow extend limited browser capabilities. And so did we, in our search for
a reliable and flexible file uploader for
our [TinyMCE](http://www.tinymce.com/index.php)'s
[MCImageManager](http://www.tinymce.com/enterprise/mcimagemanager.php).
Quickly enough though, Plupload grew big. It easily split into a standalone project.
With major *version 2.0* it underwent another huge reconstruction, basically
[from the ground up](http://blog.moxiecode.com/2012/11/28/first-public-beta-plupload-2/),
as all the low-level runtime logic has been extracted into separate [File API](http://www.w3.org/TR/FileAPI/)
and [XHR L2](http://www.w3.org/TR/XMLHttpRequest/) pollyfills (currently known under combined name of [mOxie](https://github.com/moxiecode/moxie)),
giving Plupload a chance to evolve further.
### Structure
Currently, Plupload may be considered as consisting of three parts: low-level pollyfills,
Plupload API and Widgets (UI and Queue). Initially, Widgets were meant only to serve as examples
of the API, but quickly formed into fully-functional API implementations that now come bundled with
the Plupload API. This has been a source for multiple misconceptions about the API as Widgets were
easily mistaken for the Plupload itself. They are only implementations, such as any of you can
build by yourself out of the API.
* [Low-level pollyfills (mOxie)](https://github.com/moxiecode/moxie) - have their own [code base](https://github.com/moxiecode/moxie) and [documentation](https://github.com/moxiecode/moxie/wiki) on GitHub.
* [Plupload API](https://github.com/moxiecode/plupload/wiki/API)
* [UI Widget](https://github.com/moxiecode/plupload/wiki/UI.Plupload)
* [Queue Widget](https://github.com/moxiecode/plupload/wiki/pluploadQueue)
### Building instructions
Plupload depends on File API and XHR2 L2 pollyfills that currently have their
[own repository](https://github.com/moxiecode/moxie) on GitHub. However, in most cases you shouldn't
care as we bundle the latest build of mOxie, including full and minified JavaScript source and
pre-compiled `SWF` and `XAP` components, with [every release](https://github.com/moxiecode/plupload/releases). You can find everything you may need under `js/` folder.
There are cases where you might need a custom build, for example free of unnecessary runtimes, half the
original size, etc. The difficult part of this task comes from mOxie and its set of additional runtimes
that require special tools on your workstation in order to compile.
Consider [build instructions for mOxie](https://github.com/moxiecode/moxie#build-instructions) -
everything applies to Plupload as well.
First of all, if you want to build custom Plupload packages you will require [Node.js](http://nodejs.org/),
as this is our build environment of choice. Node.js binaries (as well as Source)
[are available](http://nodejs.org/download/) for all major operating systems.
Plupload includes _mOxie_ as a submodule, it also depends on some other repositories for building up it's dev
environment - to avoid necessity of downloading them one by one, we recommended you to simply clone Plupload
with [git](http://git-scm.com/) recursively (you will require git installed on your system for this operation
to succeed):
```
git clone --recursive https://github.com/moxiecode/plupload.git
```
And finalize the preparation stage with: `npm install` - this will install all additional modules, including those
required by dev and test environments. In case you would rather keep it minimal, add a `--production` flag.
*Note:* Currently, for an unknown reason, locally installed Node.js modules on Windows, may not be automatically
added to the system PATH. So, if `jake` commands below are not recognized you will need to add them manually:
```
set PATH=%PATH%;%CD%\node_modules\.bin\
```
### Support
We are actively standing behind the Plupload and now that we are done with major rewrites and refactoring,
the only real goal that we have ahead is making it as reliable and bulletproof as possible. We are open to
all the suggestions and feature requests. We ask you to file bug reports if you encounter any. We may not
react to them instantly, but we constantly bear them in my mind as we extend the code base.
In addition to dedicated support for those who dare to buy our OEM licenses, we got
[discussion boards](http://www.plupload.com/punbb/index.php), which is like an enormous FAQ,
covering every possible application case. Of course, you are welcome to file a bug report or feature request,
here on [GitHub](https://github.com/moxiecode/plupload/issues).
Sometimes it is easier to notice the problem when bug report is accompained by the actual code. Consider providing
[a Plupload fiddle](https://github.com/moxiecode/plupload/wiki/Create-a-Fiddle) for the troublesome code.
### Contributing
We are open to suggestions and code revisions, however there are some rules and limitations that you might
want to consider first.
* Code that you contribute will automatically be licensed under the AGPL, but will not be limited to AGPL.
* Although all contributors will get the credit for their work, copyright notices will be changed to [Moxiecode Systems AB](http://www.moxiecode.com/).
* Third party code will be reviewed, tested and possibly modified before being released.
These basic rules help us earn a living and ensure that code remains Open Source and compatible with AGPL license. All contributions will be added to the changelog and appear in every release and on the site.
An easy place to start is to [translate Plupload to your language](https://github.com/moxiecode/plupload/wiki/Plupload-in-Your-Language#contribute).
You can read more about how to contribute at: [http://www.plupload.com/contributing](http://www.plupload.com/contributing)
### License
Copyright 2016, [Ephox](http://www.ephox.com/).
Released under [AGPL-3.0 License](https://github.com/moxiecode/plupload/blob/master/license.txt).
We also provide [commercial license](http://www.plupload.com/commercial.php).
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment