diff --git a/.gitignore b/.gitignore index b43207d1..feefd2f9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,6 @@ node_modules -tests/files/BigJPG.jpg -tests/files/big.jpg dist/FileAPI.html5ok.js dist/FileAPI.html5ok.min.js dist/FileAPI.ok.js dist/FileAPI.ok.min.js .idea - diff --git a/.npmignore b/.npmignore new file mode 100644 index 00000000..191381ee --- /dev/null +++ b/.npmignore @@ -0,0 +1 @@ +.git \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 98f49b4b..1fdfc355 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: node_js node_js: - - 0.10 + - 4.5 before_script: - npm install -g grunt-cli diff --git a/Gruntfile.js b/Gruntfile.js index 5bf76923..9276a4b6 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -10,6 +10,7 @@ module.exports = function (grunt) { 'Gruntfile.js' , 'lib/**/*.js' , 'plugins/jquery.fileapi.js' + , 'node/**/*.js' ], options: { @@ -66,7 +67,7 @@ module.exports = function (grunt) { options: { timeout: 5 * 60 * 1000, // 5min files: { - '1px.gif': ['tests/files/1px.gif'] + '1px_gif': ['tests/files/1px.gif'] , 'big.jpg': ['tests/files/big.jpg'] , 'hello.txt': ['tests/files/hello.txt'] , 'image.jpg': ['tests/files/image.jpg'] @@ -84,7 +85,7 @@ module.exports = function (grunt) { ' * <%= pkg.description %>\n' + ' */\n\n', - footer: 'if( typeof define === "function" && define.amd ){ define("FileAPI", [], function (){ return FileAPI; }); }' + footer: 'if( typeof define === "function" && define.amd ){ define("<%= pkg.jam.name %>", [], function (){ return FileAPI; }); }' }, all: { @@ -130,7 +131,7 @@ module.exports = function (grunt) { mxmlc: { core: { options: { - rawConfig: '-static-link-runtime-shared-libraries=true -compiler.debug=true' + + rawConfig: '-target-player=10.1 -static-link-runtime-shared-libraries=true -compiler.debug=false' + ' -library-path+=flash/core/lib/blooddy_crypto.swc -library-path+=flash/core/lib/EnginesLibrary.swc' }, files: { @@ -139,7 +140,7 @@ module.exports = function (grunt) { }, image: { options: { - rawConfig: '-static-link-runtime-shared-libraries=true -compiler.debug=true' + + rawConfig: '-static-link-runtime-shared-libraries=true -compiler.debug=false' + ' -library-path+=flash/image/lib/blooddy_crypto.swc' }, files: { @@ -148,7 +149,7 @@ module.exports = function (grunt) { }, camera: { options: { - rawConfig: '-static-link-runtime-shared-libraries=true -compiler.debug=true' + rawConfig: '-static-link-runtime-shared-libraries=true -compiler.debug=false' }, files: { 'dist/<%= pkg.exportName %>.flash.camera.swf': ['flash/camera/src/FileAPI_flash_camera.as'] @@ -182,13 +183,23 @@ module.exports = function (grunt) { // "npm build" runs these tasks grunt.registerTask('prepare-test-files', function (){ - if (!grunt.file.exists('tests/files/big.jpg')) { + // big.jpg added to git + /*if (!grunt.file.exists('tests/files/big.jpg')) { grunt.task.run('curl'); - } + }*/ + }); + + grunt.registerTask('express', 'Start a custom web server.', function() { + var done = this.async(); + + require('./node/server.js').createServer(8000, function () { + done(); + }); }); - grunt.registerTask('dev', ['concat', 'watch']); - grunt.registerTask('tests', ['jshint', 'concat', 'connect:server','prepare-test-files', 'qunit']); + grunt.registerTask('server', ['connect:server', 'express']); + grunt.registerTask('dev', ['concat', 'server', 'watch']); + grunt.registerTask('tests', ['jshint', 'concat', 'server', 'prepare-test-files', 'qunit']); grunt.registerTask('build', ['version', 'concat', 'uglify']); grunt.registerTask('build-all', ['build', 'mxmlc']); grunt.registerTask('default', ['tests', 'build']); diff --git a/README.md b/README.md index 8746cc46..b5037a77 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@  ## FileAPI -A set of javascript tools for working with files. +A set of JavaScript tools for working with files. ### Get started @@ -371,6 +371,34 @@ var xhr = FileAPI.upload({ --- + +### uploadMethod`:String` +Request method, HTML5 only. + +```js +var xhr = FileAPI.upload({ + url: '...', + uploadMethod: 'PUT', + files: { .. }, +}); +``` + +--- + + +### uploadCredentials`:Boolean` +Pass credentials to upload request, HTML5 only. + +```js +var xhr = FileAPI.upload({ + url: '...', + uploadCredentials: false, + files: { .. }, +}); +``` + +--- + ### headers`:Object` Additional request headers, HTML5 only. @@ -385,6 +413,12 @@ var xhr = FileAPI.upload({ --- + +### cache`:Boolean` +Setting to true removes the default timestamp URL parameter. + +--- + ### files`:Object` Key-value object, `key` — post name, `value` — File or FileAPI.Image object. @@ -987,8 +1021,8 @@ FileAPI.Camera.publish(el, function (err, cam/**FileAPI.Camera*/){ --- - -## Сonstants + +## Constants ### FileAPI.KB`:Number` @@ -1013,7 +1047,7 @@ FileAPI.Camera.publish(el, function (err, cam/**FileAPI.Camera*/){ ### FileAPI.each(obj`:Object|Array`, callback`:Function`[, thisObject`:Mixed`])`:void` -Iterate over a object or array, executing a function for each matched element. +Iterate over an object or array, executing a function for each matched element. * obj — array or object * callback — a function to execute for each element. @@ -1058,7 +1092,7 @@ Creates a new array with all elements that pass the test implemented by the prov ### FileAPI.support.html5`:Boolean` -HTML5 borwser support +HTML5 browser support ### FileAPI.support.cors`:Boolean` @@ -1082,7 +1116,7 @@ Support dataURI as src for image. ### FileAPI.support.chunked`:Boolean` -Support chuncked upload. +Support chunked upload. --- @@ -1166,6 +1200,14 @@ Submit Query --- + +### Security +By default `FileAPI.flash.swf` allows access from any domain via `Security.allowDomain("*")`. +This can lead to same origin bypass vulnerability if swf is loaded from the same domain as your critical data. +To prevent this, allow only your domains [here](https://github.com/mailru/FileAPI/blob/master/flash/core/src/ru/mail/communication/JSCallbackPresenter.as#L25) and rebuild flash. + +--- + ## Server settings @@ -1266,7 +1308,7 @@ Response headers: -All the other codes - fatal error, user's involvement is recommend. +All the other codes - fatal error, user's involvement is recommended. --- @@ -1395,6 +1437,47 @@ Button like link. ## Changelog +### 2.0.20 + + + +### 2.0.19 + + + +### 2.0.18 + + + +### 2.0.16-2.0.17 + + + +### 2.0.12-2.0.15 (!) + + + +### 2.0.11 + + ### 2.0.10 -### 2.0.8 +### 2.0.8 diff --git a/README.ru.md b/README.ru.md index 3e33fae1..0a278886 100644 --- a/README.ru.md +++ b/README.ru.md @@ -367,6 +367,34 @@ var xhr = FileAPI.upload({ --- + +### uploadMethod`:String` +Метод запроса, только HTML5. + +```js +var xhr = FileAPI.upload({ + url: '...', + uploadMethod: 'PUT', + files: { ... }, +}); +``` + +--- + + +### uploadCredentials`:Boolean` +Передавать ли куки в запросе, только HTML5. + +```js +var xhr = FileAPI.upload({ + url: '...', + uploadCredentials: false, + files: { ... }, +}); +``` + +--- + ### headers`:Object` Дополнительные заголовки запроса, только HTML5. @@ -1145,6 +1173,14 @@ Submit Query --- + +### Security +По умолчанию `FileAPI.flash.swf` разрешает доступ с любых доменов `Security.allowDomain("*")`. +Это может привести к уязвимости same origin bypass, если flash лежит на том же домене, что и критичные данные. +Чтобы этого избежать, нужно разрешить доступ только к своим доменам [здесь](https://github.com/mailru/FileAPI/blob/master/flash/core/src/ru/mail/communication/JSCallbackPresenter.as#L25) и пересобрать flash. + +--- + ## Server settings diff --git a/bower.json b/bower.json index 3baaef09..7143a66a 100644 --- a/bower.json +++ b/bower.json @@ -1,12 +1,10 @@ { "name": "fileapi", - "version": "2.0.10", "main": [ "./dist/FileAPI.flash.camera.swf", "./dist/FileAPI.flash.image.swf", "./dist/FileAPI.flash.swf", "./dist/FileAPI.html5.js", - "./dist/FileAPI.html5.min.js", "./dist/FileAPI.js", "./dist/jquery.fileapi.min.js" ], @@ -26,4 +24,4 @@ "README.md", ".*" ] -} \ No newline at end of file +} diff --git a/dist/FileAPI.flash.swf b/dist/FileAPI.flash.swf index 7db28041..738f60d4 100644 Binary files a/dist/FileAPI.flash.swf and b/dist/FileAPI.flash.swf differ diff --git a/dist/FileAPI.html5.js b/dist/FileAPI.html5.js index 124182d5..0ac8698e 100644 --- a/dist/FileAPI.html5.js +++ b/dist/FileAPI.html5.js @@ -1,4 +1,4 @@ -/*! FileAPI 2.0.10 - BSD | git://github.com/mailru/FileAPI.git +/*! FileAPI 2.1.1 - BSD | git://github.com/mailru/FileAPI.git * FileAPI — a set of javascript tools for working with files. Multiupload, drag'n'drop and chunked file upload. Images: crop, resize and auto orientation by EXIF. */ @@ -105,6 +105,9 @@ document = window.document, doctype = document.doctype || {}, userAgent = window.navigator.userAgent, + safari = /safari\//i.test(userAgent) && !/chrome\//i.test(userAgent), + iemobile = /iemobile\//i.test(userAgent), + insecureChrome = !safari && /chrome\//i.test(userAgent) && window.location.protocol === 'http:', // https://github.com/blueimp/JavaScript-Load-Image/blob/master/load-image.js#L48 apiURL = (window.createObjectURL && window) || (window.URL && URL.revokeObjectURL && URL) || (window.webkitURL && webkitURL), @@ -119,12 +122,14 @@ jQuery = window.jQuery, html5 = !!(File && (FileReader && (window.Uint8Array || FormData || XMLHttpRequest.prototype.sendAsBinary))) - && !(/safari\//i.test(userAgent) && !/chrome\//i.test(userAgent) && /windows/i.test(userAgent)), // BugFix: https://github.com/mailru/FileAPI/issues/25 + && !(safari && /windows/i.test(userAgent) && !iemobile), // BugFix: https://github.com/mailru/FileAPI/issues/25 cors = html5 && ('withCredentials' in (new XMLHttpRequest)), chunked = html5 && !!Blob && !!(Blob.prototype.webkitSlice || Blob.prototype.mozSlice || Blob.prototype.slice), + normalize = ('' + ''.normalize).indexOf('[native code]') > 0, + // https://github.com/blueimp/JavaScript-Canvas-to-Blob dataURLtoBlob = window.dataURLtoBlob, @@ -136,6 +141,8 @@ _rdata = /^data:[^,]+,/, _toString = {}.toString, + _supportConsoleLog, + _supportConsoleLogApply, Math = window.Math, @@ -280,13 +287,14 @@ * FileAPI (core object) */ api = { - version: '2.0.10', + version: '2.1.1', cors: false, html5: true, media: false, formData: true, multiPassResize: true, + insecureChrome: insecureChrome, debug: false, pingUrl: false, @@ -340,8 +348,8 @@ }, log: function (){ - if( api.debug && window.console && console.log ){ - if( console.log.apply ){ + if( api.debug && _supportConsoleLog ){ + if( _supportConsoleLogApply ){ console.log.apply(console, arguments); } else { @@ -702,7 +710,7 @@ * @param {Boolean} [progress] */ readAsImage: function (file, fn, progress){ - if( api.isFile(file) ){ + if( api.isBlob(file) ){ if( apiURL ){ /** @namespace apiURL.createObjectURL */ var data = apiURL.createObjectURL(file); @@ -795,28 +803,84 @@ getDropFiles: function (evt, callback){ var files = [] + , all = [] + , items , dataTransfer = _getDataTransfer(evt) - , entrySupport = _isArray(dataTransfer.items) && dataTransfer.items[0] && _getAsEntry(dataTransfer.items[0]) - , queue = api.queue(function (){ callback(files); }) + , transFiles = dataTransfer.files + , transItems = dataTransfer.items + , entrySupport = _isArray(transItems) && transItems[0] && _getAsEntry(transItems[0]) + , queue = api.queue(function (){ callback(files, all); }) ; - _each((entrySupport ? dataTransfer.items : dataTransfer.files) || [], function (item){ + if( entrySupport ){ + if( normalize && transFiles ){ + var + i = transFiles.length + , file + , entry + ; + + items = new Array(i); + while( i-- ){ + file = transFiles[i]; + + try { + entry = _getAsEntry(transItems[i]); + } + catch( err ){ + api.log('[err] getDropFiles: ', err); + entry = null; + } + + if( _isEntry(entry) ){ + // OSX filesystems use Unicode Normalization Form D (NFD), + // and entry.file(…) can't read the files with the same names + if( entry.isDirectory || (entry.isFile && file.name == file.name.normalize('NFC')) ){ + items[i] = entry; + } + else { + items[i] = file; + } + } + else { + items[i] = file; + } + } + } + else { + items = transItems; + } + } + else { + items = transFiles; + } + + _each(items || [], function (item){ queue.inc(); try { - if( entrySupport ){ - _readEntryAsFiles(item, function (err, entryFiles){ + if( entrySupport && _isEntry(item) ){ + _readEntryAsFiles(item, function (err, entryFiles, allEntries){ if( err ){ api.log('[err] getDropFiles:', err); } else { files.push.apply(files, entryFiles); } + all.push.apply(all, allEntries); + queue.next(); }); } else { - _isRegularFile(item, function (yes){ - yes && files.push(item); + _isRegularFile(item, function (yes, err){ + if( yes ){ + files.push(item); + } + else { + item.error = err; + } + all.push(item); + queue.next(); }); } @@ -927,7 +991,7 @@ getInfo: function (file, fn){ var info = {}, readers = _infoReader.concat(); - if( api.isFile(file) ){ + if( api.isBlob(file) ){ (function _next(){ var reader = readers.shift(); if( reader ){ @@ -1307,7 +1371,13 @@ queue.inc(); file.toData(function (err, image){ - // @todo: error + // @todo: требует рефакторинга и обработки ошибки + if (file.file) { + image.type = file.file.type; + image.quality = file.matrix.quality; + filename = file.file && file.file.name; + } + filename = filename || (new Date).getTime()+'.png'; _addFile(image); @@ -1537,26 +1607,31 @@ function _isRegularFile(file, callback){ // http://stackoverflow.com/questions/8856628/detecting-folders-directories-in-javascript-filelist-objects - if( !file.type && (file.size % 4096) === 0 && (file.size <= 102400) ){ + if( !file.type && (safari || ((file.size % 4096) === 0 && (file.size <= 102400))) ){ if( FileReader ){ try { - var Reader = new FileReader(); + var reader = new FileReader(); - _one(Reader, _readerEvents, function (evt){ + _one(reader, _readerEvents, function (evt){ var isFile = evt.type != 'error'; - callback(isFile); if( isFile ){ - Reader.abort(); + if ( reader.readyState == null || reader.readyState === reader.LOADING ) { + reader.abort(); + } + callback(isFile); + } + else { + callback(false, reader.error); } }); - Reader.readAsDataURL(file); + reader.readAsDataURL(file); } catch( err ){ - callback(false); + callback(false, err); } } else { - callback(null); + callback(null, new Error('FileReader is not supported')); } } else { @@ -1565,6 +1640,11 @@ } + function _isEntry(item){ + return item && (item.isFile || item.isDirectory); + } + + function _getAsEntry(item){ var entry; if( item.getAsEntry ){ entry = item.getAsEntry(); } @@ -1576,34 +1656,52 @@ function _readEntryAsFiles(entry, callback){ if( !entry ){ // error - callback('invalid entry'); + var err = new Error('invalid entry'); + entry = new Object(entry); + entry.error = err; + callback(err.message, [], [entry]); } else if( entry.isFile ){ // Read as file - entry.file(function(file){ + entry.file(function (file){ // success file.fullPath = entry.fullPath; - callback(false, [file]); + callback(false, [file], [file]); }, function (err){ // error - callback('FileError.code: '+err.code); + entry.error = err; + callback('FileError.code: ' + err.code, [], [entry]); }); } else if( entry.isDirectory ){ - var reader = entry.createReader(), result = []; + var + reader = entry.createReader() + , firstAttempt = true + , files = [] + , all = [entry] + ; - var onerror = function() { + var onerror = function (err){ // error - callback('directory_reader'); + entry.error = err; + callback('DirectoryError.code: ' + err.code, files, all); }; - var ondone = function ondone(entries) { + var ondone = function ondone(entries){ + if( firstAttempt ){ + firstAttempt = false; + if( !entries.length ){ + entry.error = new Error('directory is empty'); + } + } + // success - if ( entries.length ) { + if( entries.length ){ api.afor(entries, function (next, entry){ - _readEntryAsFiles(entry, function (err, files){ + _readEntryAsFiles(entry, function (err, entryFiles, allEntries){ if( !err ){ - result = result.concat(files); + files = files.concat(entryFiles); } + all = all.concat(allEntries); if( next ){ next(); @@ -1615,7 +1713,7 @@ }); } else { - callback(false, result); + callback(false, files, all); } }; @@ -1738,11 +1836,12 @@ evt[preventDefault](); _type = 0; - onHover.call(evt[currentTarget], false, evt); - api.getDropFiles(evt, function (files){ - onDrop.call(evt[currentTarget], files, evt); + api.getDropFiles(evt, function (files, all){ + onDrop.call(evt[currentTarget], files, all, evt); }); + + onHover.call(evt[currentTarget], false, evt); }); } else { @@ -1796,7 +1895,13 @@ }); - // @configuration + // Configuration + try { + _supportConsoleLog = !!console.log; + _supportConsoleLogApply = !!console.log.apply; + } + catch (err) {} + if( !api.flashUrl ){ api.flashUrl = api.staticPath + 'FileAPI.flash.swf'; } if( !api.flashImageUrl ){ api.flashImageUrl = api.staticPath + 'FileAPI.flash.image.swf'; } if( !api.flashWebcamUrl ){ api.flashWebcamUrl = api.staticPath + 'FileAPI.flash.camera.swf'; } @@ -1979,6 +2084,9 @@ , (deg == 90 || deg == 180 ? -dh : 0) , dw, dh ); + + ctx.setTransform(1, 0, 0, 1, 0, 0); + dw = canvas.width; dh = canvas.height; @@ -2332,7 +2440,7 @@ loadImage.detectSubsampling = function (img) { var canvas, context; - if (img.width * img.height > 1024 * 1024) { // only consider mexapixel images + if (img.width * img.height > 1024 * 1024) { // only consider megapixel images canvas = document.createElement('canvas'); canvas.width = canvas.height = 1; context = canvas.getContext('2d'); @@ -2533,7 +2641,13 @@ }); this.each(function (file){ - next(file, data, queue, arg); + try{ + next(file, data, queue, arg); + } + catch( err ){ + api.log('FileAPI.Form._to: ' + err.message); + complete(err); + } }); queue.check(); @@ -2761,9 +2875,14 @@ var _this = this, options = this.options; FormData.toData(function (data){ - // Start uploading - options.upload(options, _this); - _this._send.call(_this, options, data); + if( data instanceof Error ){ + _this.end(0, data.message); + } + else{ + // Start uploading + options.upload(options, _this); + _this._send.call(_this, options, data); + } }, options); }, @@ -2861,7 +2980,11 @@ // send _this.readyState = 2; // loaded - form.submit(); + try { + form.submit(); + } catch (err) { + api.log('iframe.error: ' + err); + } form = null; } else { @@ -2879,9 +3002,11 @@ url += (url.indexOf('?') < 0 ? "?" : "&") + data.params.join("&"); } - xhr.open('POST', url, true); + xhr.open(options.uploadMethod || 'POST', url, true); - if( api.withCredentials ){ + if (typeof options.uploadCredentials === 'boolean') { + xhr.withCredentials = options.uploadCredentials ? 'true' : null; + } else if( api.withCredentials ){ xhr.withCredentials = "true"; } @@ -3142,7 +3267,11 @@ // }); // Set camera stream - video.src = URL.createObjectURL(stream); + try { + video.src = URL.createObjectURL(stream); + } catch (err) { + video.srcObject = stream; + } // Note: onloadedmetadata doesn't fire in Chrome when using it with getUserMedia. // See crbug.com/110938. @@ -3169,8 +3298,19 @@ try { this._active = false; this.video.pause(); - this.stream.stop(); - } catch( err ){ } + + try { + this.stream.stop(); + } catch (err) { + api.each(this.stream.getTracks(), function (track) { + track.stop(); + }); + } + + this.stream = null; + } catch( err ){ + api.log('[FileAPI.Camera] stop:', err); + } }, @@ -3245,7 +3385,7 @@ el.style.height = _px(options.height); - if( api.html5 && html5 ){ + if( api.html5 && html5 && !api.insecureChrome ){ // Create video element var video = document.createElement('video'); @@ -3276,6 +3416,38 @@ callback('not_support_camera'); }; + Camera.checkAlreadyCaptured = (function () { + var mediaDevices = navigator.mediaDevices, + MediaStreamTrack = window.MediaStreamTrack, + navigatorEnumerateDevices = navigator.enumerateDevices, + enumerateDevices; + + if (mediaDevices && mediaDevices.enumerateDevices) { + enumerateDevices = function (callback) { + mediaDevices.enumerateDevices().then(callback); + }; + } else if (MediaStreamTrack && MediaStreamTrack.getSources) { + enumerateDevices = MediaStreamTrack.getSources.bind(MediaStreamTrack); + } else if (navigatorEnumerateDevices) { + enumerateDevices = navigatorEnumerateDevices.bind(navigator); + } else { + enumerateDevices = function (fn) { + fn([]); + }; + } + + return function (callback) { + enumerateDevices(function (devices) { + var deviceExists = devices.some(function (device) { + return (device.kind === 'videoinput' || device.kind === 'video') && device.label; + }); + + callback(deviceExists); + }); + }; + + })(); + /** * @class FileAPI.Camera.Shot @@ -3315,7 +3487,9 @@ ctx.drawImage(video, 0, 0, 1, 1); res = ctx.getImageData(0, 0, 1, 1).data[4] != 255; } - catch( e ){} + catch( err ){ + api.log('[FileAPI.Camera] detectVideoSignal:', err); + } return res; } @@ -3338,7 +3512,7 @@ var _each = api.each, _cameraQueue = []; - if (api.support.flash && (api.media && (!api.support.media || !api.html5))) { + if (api.support.flash && (api.media && (!api.support.media || !api.html5 || api.insecureChrome))) { (function () { function _wrap(fn) { var id = fn.wid = api.uid(); @@ -3436,4 +3610,4 @@ }()); } }(window, window.jQuery, FileAPI)); -if( typeof define === "function" && define.amd ){ define("FileAPI", [], function (){ return FileAPI; }); } \ No newline at end of file +if( typeof define === "function" && define.amd ){ define("FileAPI", [], function (){ return FileAPI; }); } diff --git a/dist/FileAPI.html5.min.js b/dist/FileAPI.html5.min.js index 91a84eef..16b8c50f 100644 --- a/dist/FileAPI.html5.min.js +++ b/dist/FileAPI.html5.min.js @@ -1,3 +1,2 @@ -/*! FileAPI 2.0.10 - BSD | git://github.com/mailru/FileAPI.git */ -!function(a){"use strict";var b=a.HTMLCanvasElement&&a.HTMLCanvasElement.prototype,c=a.Blob&&function(){try{return Boolean(new Blob)}catch(a){return!1}}(),d=c&&a.Uint8Array&&function(){try{return 100===new Blob([new Uint8Array(100)]).size}catch(a){return!1}}(),e=a.BlobBuilder||a.WebKitBlobBuilder||a.MozBlobBuilder||a.MSBlobBuilder,f=(c||e)&&a.atob&&a.ArrayBuffer&&a.Uint8Array&&function(a){var b,f,g,h,i,j;for(b=a.split(",")[0].indexOf("base64")>=0?atob(a.split(",")[1]):decodeURIComponent(a.split(",")[1]),f=new ArrayBuffer(b.length),g=new Uint8Array(f),h=0;hd;d++)d in a&&b.call(c,a[d],d,a);else for(var f in a)a.hasOwnProperty(f)&&b.call(c,a[f],f,a)},S=function(a){for(var b=arguments,c=1,d=function(b,c){a[c]=b};c=c&&!d&&f.end()},isFail:function(){return d},fail:function(){!d&&a(d=!0)},end:function(){e||(e=!0,a())}};return f},each:R,afor:function(a,b){var c=0,d=a.length;Q(a)&&d--?!function e(){b(d!=c&&e,a[c],c++)}():b(!1)},extend:S,isFile:function(a){return"[object File]"===H.call(a)},isBlob:function(a){return this.isFile(a)||"[object Blob]"===H.call(a)},isCanvas:function(a){return a&&D.test(a.nodeName)},getFilesFilter:function(a){return a="string"==typeof a?a:a.getAttribute&&a.getAttribute("accept")||"",a?new RegExp("("+a.replace(/\./g,"\\.").replace(/,/g,"|")+")$","i"):/./},readAsDataURL:function(a,b){Y.isCanvas(a)?c(a,b,"load",Y.toDataURL(a)):e(a,b,"DataURL")},readAsBinaryString:function(a,b){d("BinaryString")?e(a,b,"BinaryString"):e(a,function(a){if("load"==a.type)try{a.result=Y.toBinaryString(a.result)}catch(c){a.type="error",a.message=c.toString()}b(a)},"DataURL")},readAsArrayBuffer:function(a,b){e(a,b,"ArrayBuffer")},readAsText:function(a,b,c){c||(c=b,b="utf-8"),e(a,c,"Text",b)},toDataURL:function(a,b){return"string"==typeof a?a:a.toDataURL?a.toDataURL(b||"image/png"):void 0},toBinaryString:function(b){return a.atob(Y.toDataURL(b).replace(G,""))},readAsImage:function(a,d,e){if(Y.isFile(a))if(r){var f=r.createObjectURL(a);f===b?c(a,d,"error"):Y.readAsImage(f,d,e)}else Y.readAsDataURL(a,function(b){"load"==b.type?Y.readAsImage(b.result,d,e):(e||"error"==b.type)&&c(a,d,b,null,{loaded:b.loaded,total:b.total})});else if(Y.isCanvas(a))c(a,d,"load",a);else if(C.test(a.nodeName))if(a.complete)c(a,d,"load",a);else{var g="error abort load";V(a,g,function i(b){"load"==b.type&&r&&r.revokeObjectURL(a.src),U(a,g,i),c(a,d,b,a)})}else if(a.iframe)c(a,d,{type:"error"});else{var h=Y.newImage(a.dataURL||a);Y.readAsImage(h,d,e)}},checkFileObj:function(a){var b={},c=Y.accept;return"object"==typeof a?b=a:b.name=(a+"").split(/\\|\//g).pop(),null==b.type&&(b.type=b.name.split(".").pop()),R(c,function(a,c){a=new RegExp(a.replace(/\s/g,"|"),"i"),(a.test(b.type)||Y.ext2mime[b.type])&&(b.type=Y.ext2mime[b.type]||c.split("/")[0]+"/"+b.type)}),b},getDropFiles:function(a,b){var c=[],d=k(a),e=Q(d.items)&&d.items[0]&&g(d.items[0]),i=Y.queue(function(){b(c)});R((e?d.items:d.files)||[],function(a){i.inc();try{e?h(a,function(a,b){a?Y.log("[err] getDropFiles:",a):c.push.apply(c,b),i.next()}):f(a,function(b){b&&c.push(a),i.next()})}catch(b){i.next(),Y.log("[err] getDropFiles: ",b)}}),i.check()},getFiles:function(a,b,c){var d=[];return c?(Y.filterFiles(Y.getFiles(a),b,c),null):(a.jquery&&(a.each(function(){d=d.concat(Y.getFiles(this))}),a=d,d=[]),"string"==typeof b&&(b=Y.getFilesFilter(b)),a.originalEvent?a=W(a.originalEvent):a.srcElement&&(a=W(a)),a.dataTransfer?a=a.dataTransfer:a.target&&(a=a.target),a.files?(d=a.files,y||(d[0].blob=a,d[0].iframe=!0)):!y&&j(a)?Y.trim(a.value)&&(d=[Y.checkFileObj(a.value)],d[0].blob=a,d[0].iframe=!0):Q(a)&&(d=a),Y.filter(d,function(a){return!b||b.test(a.name)}))},getTotalSize:function(a){for(var b=0,c=a&&a.length;c--;)b+=a[c].size;return b},getInfo:function(a,b){var c={},d=L.concat();Y.isFile(a)?!function e(){var f=d.shift();f?f.test(a.type)?f(a,function(a,d){a?b(a):(S(c,d),e())}):e():b(!1,c)}():b("not_support_info",c)},addInfoReader:function(a,b){b.test=function(b){return a.test(b)},L.push(b)},filter:function(a,b){for(var c,d=[],e=0,f=a.length;f>e;e++)e in a&&(c=a[e],b.call(c,c,e,a)&&d.push(c));return d},filterFiles:function(a,b,c){if(a.length){var d,e=a.concat(),f=[],g=[];!function h(){e.length?(d=e.shift(),Y.getInfo(d,function(a,c){(b(d,a?!1:c)?f:g).push(d),h()})):c(f,g)}()}else c([],a)},upload:function(a){a=S({jsonp:"callback",prepare:Y.F,beforeupload:Y.F,upload:Y.F,fileupload:Y.F,fileprogress:Y.F,filecomplete:Y.F,progress:Y.F,complete:Y.F,pause:Y.F,imageOriginal:!0,chunkSize:Y.chunkSize,chunkUploadRetry:Y.chunkUploadRetry,uploadRetry:Y.uploadRetry},a),a.imageAutoOrientation&&!a.imageTransform&&(a.imageTransform={rotate:"auto"});var b,c=new Y.XHR(a),d=this._getFilesDataArray(a.files),e=this,f=0,g=0,h=!1;return R(d,function(a){f+=a.size}),c.files=[],R(d,function(a){c.files.push(a.file)}),c.total=f,c.loaded=0,c.filesLeft=d.length,a.beforeupload(c,a),b=function(){var j=d.shift(),k=j&&j.file,l=!1,m=i(a);if(c.filesLeft=d.length,k&&k.name===Y.expando&&(k=null,Y.log("[warn] FileAPI.upload() — called without files")),("abort"!=c.statusText||c.current)&&j){if(h=!1,c.currentFile=k,k&&a.prepare(k,m)===!1)return void b.call(e);m.file=k,e._getFormData(m,j,function(h){g||a.upload(c,a);var i=new Y.XHR(S({},m,{upload:k?function(){a.fileupload(k,i,m)}:n,progress:k?function(b){l||(l=b.loaded===b.total,a.fileprogress({type:"progress",total:j.total=b.total,loaded:j.loaded=b.loaded},k,i,m),a.progress({type:"progress",total:f,loaded:c.loaded=g+j.size*(b.loaded/b.total)||0},k,i,m))}:n,complete:function(d){R(N,function(a){c[a]=i[a]}),k&&(j.total=j.total||j.size,j.loaded=j.total,d||(this.progress(j),l=!0,g+=j.size,c.loaded=g),a.filecomplete(d,i,k,m)),setTimeout(function(){b.call(e)},0)}}));c.abort=function(a){a||(d.length=0),this.current=a,i.abort()},i.send(h)})}else{var o=200==c.status||201==c.status||204==c.status;a.complete(o?!1:c.statusText||"error",c,a),h=!0}},setTimeout(b,0),c.append=function(a,g){a=Y._getFilesDataArray([].concat(a)),R(a,function(a){f+=a.size,c.files.push(a.file),g?d.unshift(a):d.push(a)}),c.statusText="",h&&b.call(e)},c.remove=function(a){for(var b,c=d.length;c--;)d[c].file==a&&(b=d.splice(c,1),f-=b.size);return b},c},_getFilesDataArray:function(a){var b=[],c={};if(j(a)){var d=Y.getFiles(a);c[a.name||"file"]=null!==a.getAttribute("multiple")?d:d[0]}else Q(a)&&j(a[0])?R(a,function(a){c[a.name||"file"]=Y.getFiles(a)}):c=a;return R(c,function e(a,c){Q(a)?R(a,function(a){e(a,c)}):a&&(a.name||a.image)&&b.push({name:c,file:a,size:a.size,total:a.size,loaded:0})}),b.length||b.push({file:{name:Y.expando}}),b},_getFormData:function(a,b,c){var d=b.file,e=b.name,f=d.name,g=d.type,h=Y.support.transform&&a.imageTransform,i=new Y.Form,j=Y.queue(function(){c(i)}),k=h&&l(h),m=Y.postNameConcat;R(a.data,function n(a,b){"object"==typeof a?R(a,function(a,c){n(a,m(b,c))}):i.append(b,a)}),function o(b){b.image?(j.inc(),b.toData(function(a,b){f=f||(new Date).getTime()+".png",o(b),j.next()})):Y.Image&&h&&(/^image/.test(b.type)||E.test(b.nodeName))?(j.inc(),k&&(h=[h]),Y.Image.transform(b,h,a.imageAutoOrientation,function(c,d){if(k&&!c)B||Y.flashEngine||(i.multipart=!0),i.append(e,d[0],f,h[0].type||g);else{var l=0;c||R(d,function(a,b){B||Y.flashEngine||(i.multipart=!0),h[b].postName||(l=1),i.append(h[b].postName||m(e,b),a,f,h[b].type||g)}),(c||a.imageOriginal)&&i.append(m(e,l?"original":null),b,f,g)}j.next()})):f!==Y.expando&&i.append(e,b,f)}(d),j.check()},reset:function(a,b){var c,d;return x?(d=x(a).clone(!0).insertBefore(a).val("")[0],b||x(a).remove()):(c=a.parentNode,d=c.insertBefore(a.cloneNode(!0),a),d.value="",b||c.removeChild(a),R(K[Y.uid(a)],function(b,c){R(b,function(b){U(a,c,b),T(d,c,b)})})),d},load:function(a,b){var c=Y.getXHR();return c?(c.open("GET",a,!0),c.overrideMimeType&&c.overrideMimeType("text/plain; charset=x-user-defined"),T(c,"progress",function(a){a.lengthComputable&&b({type:a.type,loaded:a.loaded,total:a.total},c)}),c.onreadystatechange=function(){if(4==c.readyState)if(c.onreadystatechange=null,200==c.status){a=a.split("/");var d={name:a[a.length-1],size:c.getResponseHeader("Content-Length"),type:c.getResponseHeader("Content-Type")};d.dataURL="data:"+d.type+";base64,"+Y.encode64(c.responseBody||c.responseText),b({type:"load",result:d},c)}else b({type:"error"},c)},c.send(null)):b({type:"error"}),c},encode64:function(a){var b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",c="",d=0;for("string"!=typeof a&&(a=String(a));d>2,k=(3&g)<<4|h>>4;isNaN(h)?e=f=64:(e=(15&h)<<2|i>>6,f=isNaN(i)?64:63&i),c+=b.charAt(j)+b.charAt(k)+b.charAt(e)+b.charAt(f)}return c}};Y.addInfoReader(/^image/,function(a,b){if(!a.__dimensions){var c=a.__dimensions=Y.defer();Y.readAsImage(a,function(a){var b=a.target;c.resolve("load"==a.type?!1:"error",{width:b.width,height:b.height}),b.src=Y.EMPTY_PNG,b=null})}a.__dimensions.then(b)}),Y.event.dnd=function(a,b,c){var d,e;c||(c=b,b=Y.F),u?(T(a,"dragenter dragleave dragover",b.ff=b.ff||function(a){for(var c=k(a).types,f=c&&c.length,g=!1;f--;)if(~c[f].indexOf("File")){a[P](),e!==a.type&&(e=a.type,"dragleave"!=e&&b.call(a[O],!0,a),g=!0);break}g&&(clearTimeout(d),d=setTimeout(function(){b.call(a[O],"dragleave"!=e,a)},50))}),T(a,"drop",c.ff=c.ff||function(a){a[P](),e=0,b.call(a[O],!1,a),Y.getDropFiles(a,function(b){c.call(a[O],b,a)})})):Y.log("Drag'n'Drop -- not supported")},Y.event.dnd.off=function(a,b,c){U(a,"dragenter dragleave dragover",b.ff),U(a,"drop",c.ff)},x&&!x.fn.dnd&&(x.fn.dnd=function(a,b){return this.each(function(){Y.event.dnd(this,a,b)})},x.fn.offdnd=function(a,b){return this.each(function(){Y.event.dnd.off(this,a,b)})}),a.FileAPI=S(Y,a.FileAPI),Y.log("FileAPI: "+Y.version),Y.log("protocol: "+a.location.protocol),Y.log("doctype: ["+p.name+"] "+p.publicId+" "+p.systemId),R(o.getElementsByTagName("meta"),function(a){/x-ua-compatible/i.test(a.getAttribute("http-equiv"))&&Y.log("meta.http-equiv: "+a.getAttribute("content"))}),Y.flashUrl||(Y.flashUrl=Y.staticPath+"FileAPI.flash.swf"),Y.flashImageUrl||(Y.flashImageUrl=Y.staticPath+"FileAPI.flash.image.swf"),Y.flashWebcamUrl||(Y.flashWebcamUrl=Y.staticPath+"FileAPI.flash.camera.swf")}(window,void 0),function(a,b,c){"use strict";function d(b){if(b instanceof d){var c=new d(b.file);return a.extend(c.matrix,b.matrix),c}return this instanceof d?(this.file=b,this.size=b.size||100,void(this.matrix={sx:0,sy:0,sw:0,sh:0,dx:0,dy:0,dw:0,dh:0,resize:0,deg:0,quality:1,filter:0})):new d(b)}var e=Math.min,f=Math.round,g=function(){return b.createElement("canvas")},h=!1,i={8:270,3:180,6:90,7:270,4:180,5:90};try{h=g().toDataURL("image/png").indexOf("data:image/png")>-1}catch(j){}d.prototype={image:!0,constructor:d,set:function(b){return a.extend(this.matrix,b),this},crop:function(a,b,d,e){return d===c&&(d=a,e=b,a=b=0),this.set({sx:a,sy:b,sw:d,sh:e||d})},resize:function(a,b,c){return/min|max|height|width/.test(b)&&(c=b,b=a),this.set({dw:a,dh:b||a,resize:c})},preview:function(a,b){return this.resize(a,b||a,"preview")},rotate:function(a){return this.set({deg:a})},filter:function(a){return this.set({filter:a})},overlay:function(a){return this.set({overlay:a})},clone:function(){return new d(this)},_load:function(b,c){var d=this;/img|video/i.test(b.nodeName)?c.call(d,null,b):a.readAsImage(b,function(a){c.call(d,"load"!=a.type,a.result)})},_apply:function(b,c){var f,h=g(),i=this.getMatrix(b),j=h.getContext("2d"),k=b.videoWidth||b.width,l=b.videoHeight||b.height,m=i.deg,n=i.dw,o=i.dh,p=k,q=l,r=i.filter,s=b,t=i.overlay,u=a.queue(function(){b.src=a.EMPTY_PNG,c(!1,h)}),v=a.renderImageToCanvas;for(m-=360*Math.floor(m/360),b._type=this.file.type;i.multipass&&e(p/n,q/o)>2;)p=p/2+.5|0,q=q/2+.5|0,f=g(),f.width=p,f.height=q,s!==b?(v(f,s,0,0,s.width,s.height,0,0,p,q),s=f):(s=f,v(s,b,i.sx,i.sy,i.sw,i.sh,0,0,p,q),i.sx=i.sy=i.sw=i.sh=0);h.width=m%180?o:n,h.height=m%180?n:o,h.type=i.type,h.quality=i.quality,j.rotate(m*Math.PI/180),v(j.canvas,s,i.sx,i.sy,i.sw||s.width,i.sh||s.height,180==m||270==m?-n:0,90==m||180==m?-o:0,n,o),n=h.width,o=h.height,t&&a.each([].concat(t),function(b){u.inc();var c=new window.Image,d=function(){var e=0|b.x,f=0|b.y,g=b.w||c.width,h=b.h||c.height,i=b.rel;e=1==i||4==i||7==i?(n-g+e)/2:2==i||5==i||8==i?n-(g+e):e,f=3==i||4==i||5==i?(o-h+f)/2:i>=6?o-(h+f):f,a.event.off(c,"error load abort",d);try{j.globalAlpha=b.opacity||1,j.drawImage(c,e,f,g,h)}catch(k){}u.next()};a.event.on(c,"error load abort",d),c.src=b.src,c.complete&&d()}),r&&(u.inc(),d.applyFilter(h,r,u.next)),u.check()},getMatrix:function(b){var c=a.extend({},this.matrix),d=c.sw=c.sw||b.videoWidth||b.naturalWidth||b.width,g=c.sh=c.sh||b.videoHeight||b.naturalHeight||b.height,h=c.dw=c.dw||d,i=c.dh=c.dh||g,j=d/g,k=h/i,l=c.resize;if("preview"==l){if(h!=d||i!=g){var m,n;k>=j?(m=d,n=m/k):(n=g,m=n*k),(m!=d||n!=g)&&(c.sx=~~((d-m)/2),c.sy=~~((g-n)/2),d=m,g=n)}}else"height"==l?h=i*j:"width"==l?i=h/j:l&&(d>h||g>i?"min"==l?(h=f(k>j?e(d,h):i*j),i=f(k>j?h/j:e(g,i))):(h=f(j>=k?e(d,h):i*j),i=f(j>=k?h/j:e(g,i))):(h=d,i=g));return c.sw=d,c.sh=g,c.dw=h,c.dh=i,c.multipass=a.multiPassResize,c},_trans:function(b){this._load(this.file,function(c,d){if(c)b(c);else try{this._apply(d,b)}catch(c){a.log("[err] FileAPI.Image.fn._apply:",c),b(c)}})},get:function(b){if(a.support.transform){var c=this,d=c.matrix;"auto"==d.deg?a.getInfo(c.file,function(a,e){d.deg=i[e&&e.exif&&e.exif.Orientation]||0,c._trans(b)}):c._trans(b)}else b("not_support_transform");return this},toData:function(a){return this.get(a)}},d.exifOrientation=i,d.transform=function(b,e,f,g){function h(h,i){var j={},k=a.queue(function(a){g(a,j)});h?k.fail():a.each(e,function(a,e){if(!k.isFail()){var g=new d(i.nodeType?i:b),h="function"==typeof a;if(h?a(i,g):a.width?g[a.preview?"preview":"resize"](a.width,a.height,a.strategy):a.maxWidth&&(i.width>a.maxWidth||i.height>a.maxHeight)&&g.resize(a.maxWidth,a.maxHeight,"max"),a.crop){var l=a.crop;g.crop(0|l.x,0|l.y,l.w||l.width,l.h||l.height)}a.rotate===c&&f&&(a.rotate="auto"),g.set({type:g.matrix.type||a.type||b.type||"image/png"}),h||g.set({deg:a.rotate,overlay:a.overlay,filter:a.filter,quality:a.quality||1}),k.inc(),g.toData(function(a,b){a?k.fail():(j[e]=b,k.next())})}})}b.width?h(!1,b):a.getInfo(b,h)},a.each(["TOP","CENTER","BOTTOM"],function(b,c){a.each(["LEFT","CENTER","RIGHT"],function(a,e){d[b+"_"+a]=3*c+e,d[a+"_"+b]=3*c+e})}),d.toCanvas=function(a){var c=b.createElement("canvas");return c.width=a.videoWidth||a.width,c.height=a.videoHeight||a.height,c.getContext("2d").drawImage(a,0,0),c},d.fromDataURL=function(b,c,d){var e=a.newImage(b);a.extend(e,c),d(e)},d.applyFilter=function(b,c,e){"function"==typeof c?c(b,e):window.Caman&&window.Caman("IMG"==b.tagName?d.toCanvas(b):b,function(){"string"==typeof c?this[c]():a.each(c,function(a,b){this[b](a)},this),this.render(e)})},a.renderImageToCanvas=function(b,c,d,e,f,g,h,i,j,k){try{return b.getContext("2d").drawImage(c,d,e,f,g,h,i,j,k)}catch(l){throw a.log("renderImageToCanvas failed"),l}},a.support.canvas=a.support.transform=h,a.Image=d}(FileAPI,document),function(a){"use strict";a(FileAPI)}(function(a){"use strict";if(window.navigator&&window.navigator.platform&&/iP(hone|od|ad)/.test(window.navigator.platform)){var b=a.renderImageToCanvas;a.detectSubsampling=function(a){var b,c;return a.width*a.height>1048576?(b=document.createElement("canvas"),b.width=b.height=1,c=b.getContext("2d"),c.drawImage(a,-a.width+1,0),0===c.getImageData(0,0,1,1).data[3]):!1},a.detectVerticalSquash=function(a,b){var c,d,e,f,g,h=a.naturalHeight||a.height,i=document.createElement("canvas"),j=i.getContext("2d");for(b&&(h/=2),i.width=1,i.height=h,j.drawImage(a,0,0),c=j.getImageData(0,0,1,h).data,d=0,e=h,f=h;f>d;)g=c[4*(f-1)+3],0===g?e=f:d=f,f=e+d>>1;return f/h||1},a.renderImageToCanvas=function(c,d,e,f,g,h,i,j,k,l){if("image/jpeg"===d._type){var m,n,o,p,q=c.getContext("2d"),r=document.createElement("canvas"),s=1024,t=r.getContext("2d");if(r.width=s,r.height=s,q.save(),m=a.detectSubsampling(d),m&&(e/=2,f/=2,g/=2,h/=2),n=a.detectVerticalSquash(d,m),m||1!==n){for(f*=n,k=Math.ceil(s*k/g),l=Math.ceil(s*l/h/n),j=0,p=0;h>p;){for(i=0,o=0;g>o;)t.clearRect(0,0,s,s),t.drawImage(d,e,f,g,h,-o,-p,g,h),q.drawImage(r,0,0,s,s,i,j,k,l),o+=s,i+=k;p+=s,j+=l}return q.restore(),c}}return b(c,d,e,f,g,h,i,j,k,l)}}}),function(a,b){"use strict";function c(b,c,d){var e=b.blob,f=b.file;if(f){if(!e.toDataURL)return void a.readAsBinaryString(e,function(a){"load"==a.type&&c(b,a.result)});var g={"image/jpeg":".jpe?g","image/png":".png"},h=g[b.type]?b.type:"image/png",i=g[h]||".png",j=e.quality||1;f.match(new RegExp(i+"$","i"))||(f+=i.replace("?","")),b.file=f,b.type=h,!d&&e.toBlob?e.toBlob(function(a){c(b,a)},h,j):c(b,a.toBinaryString(e.toDataURL(h,j)))}else c(b,e)}var d=b.document,e=b.FormData,f=function(){this.items=[]},g=b.encodeURIComponent;f.prototype={append:function(a,b,c,d){this.items.push({name:a,blob:b&&b.blob||(void 0==b?"":b),file:b&&(c||b.name),type:b&&(d||b.type)})},each:function(a){for(var b=0,c=this.items.length;c>b;b++)a.call(this,this.items[b])},toData:function(b,c){c._chunked=a.support.chunked&&c.chunkSize>0&&1==a.filter(this.items,function(a){return a.file}).length,a.support.html5?a.formData&&!this.multipart&&e?c._chunked?(a.log("FileAPI.Form.toPlainData"),this.toPlainData(b)):(a.log("FileAPI.Form.toFormData"),this.toFormData(b)):(a.log("FileAPI.Form.toMultipartData"),this.toMultipartData(b)):(a.log("FileAPI.Form.toHtmlData"),this.toHtmlData(b))},_to:function(b,c,d,e){var f=a.queue(function(){c(b)});this.each(function(a){d(a,b,f,e)}),f.check()},toHtmlData:function(b){this._to(d.createDocumentFragment(),b,function(b,c){var e,f=b.blob;b.file?(a.reset(f,!0),f.name=b.name,f.disabled=!1,c.appendChild(f)):(e=d.createElement("input"),e.name=b.name,e.type="hidden",e.value=f,c.appendChild(e))})},toPlainData:function(a){this._to({},a,function(a,b,d){a.file&&(b.type=a.file),a.blob.toBlob?(d.inc(),c(a,function(a,c){b.name=a.name,b.file=c,b.size=c.length,b.type=a.type,d.next()})):a.file?(b.name=a.blob.name,b.file=a.blob,b.size=a.blob.size,b.type=a.type):(b.params||(b.params=[]),b.params.push(g(a.name)+"="+g(a.blob))),b.start=-1,b.end=b.file&&b.file.FileAPIReadPosition||-1,b.retry=0})},toFormData:function(a){this._to(new e,a,function(a,b,d){a.blob&&a.blob.toBlob?(d.inc(),c(a,function(a,c){b.append(a.name,c,a.file),d.next()})):a.file?b.append(a.name,a.blob,a.file):b.append(a.name,a.blob),a.file&&b.append("_"+a.name,a.file)})},toMultipartData:function(b){this._to([],b,function(a,b,d,e){d.inc(),c(a,function(a,c){b.push("--_"+e+('\r\nContent-Disposition: form-data; name="'+a.name+'"'+(a.file?'; filename="'+g(a.file)+'"':"")+(a.file?"\r\nContent-Type: "+(a.type||"application/octet-stream"):"")+"\r\n\r\n"+(a.file?c:g(c))+"\r\n")),d.next()},!0)},a.expando)}},a.Form=f}(FileAPI,window),function(a,b){"use strict";var c=function(){},d=a.document,e=function(a){this.uid=b.uid(),this.xhr={abort:c,getResponseHeader:c,getAllResponseHeaders:c},this.options=a},f={"":1,XML:1,Text:1,Body:1};e.prototype={status:0,statusText:"",constructor:e,getResponseHeader:function(a){return this.xhr.getResponseHeader(a)},getAllResponseHeaders:function(){return this.xhr.getAllResponseHeaders()||{}},end:function(d,e){var f=this,g=f.options;f.end=f.abort=c,f.status=d,e&&(f.statusText=e),b.log("xhr.end:",d,e),g.complete(200==d||201==d?!1:f.statusText||"unknown",f),f.xhr&&f.xhr.node&&setTimeout(function(){var b=f.xhr.node;try{b.parentNode.removeChild(b)}catch(c){}try{delete a[f.uid]}catch(c){}a[f.uid]=f.xhr.node=null},9)},abort:function(){this.end(0,"abort"),this.xhr&&(this.xhr.aborted=!0,this.xhr.abort())},send:function(a){var b=this,c=this.options;a.toData(function(a){c.upload(c,b),b._send.call(b,c,a)},c)},_send:function(c,e){var g,h=this,i=h.uid,j=h.uid+"Load",k=c.url;if(b.log("XHR._send:",e),c.cache||(k+=(~k.indexOf("?")?"&":"?")+b.uid()),e.nodeName){var l=c.jsonp;k=k.replace(/([a-z]+)=(\?)/i,"$1="+i),c.upload(c,h);var m=function(a){if(~k.indexOf(a.origin))try{var c=b.parseJSON(a.data);c.id==i&&n(c.status,c.statusText,c.response)}catch(d){n(0,d.message)}},n=a[i]=function(c,d,e){h.readyState=4,h.responseText=e,h.end(c,d),b.event.off(a,"message",m),a[i]=g=p=a[j]=null};h.xhr.abort=function(){try{p.stop?p.stop():p.contentWindow.stop?p.contentWindow.stop():p.contentWindow.document.execCommand("Stop")}catch(a){}n(0,"abort")},b.event.on(a,"message",m),a[j]=function(){try{var a=p.contentWindow,c=a.document,d=a.result||b.parseJSON(c.body.innerHTML);n(d.status,d.statusText,d.response)}catch(e){b.log("[transport.onload]",e)}},g=d.createElement("div"),g.innerHTML='
'+(l&&c.url.indexOf("=?")<0?'':"")+"
";var o=g.getElementsByTagName("form")[0],p=g.getElementsByTagName("iframe")[0];o.appendChild(e),b.log(o.parentNode.innerHTML),d.body.appendChild(g),h.xhr.node=g,h.readyState=2,o.submit(),o=null}else{if(k=k.replace(/([a-z]+)=(\?)&?/i,""),this.xhr&&this.xhr.aborted)return void b.log("Error: already aborted");if(g=h.xhr=b.getXHR(),e.params&&(k+=(k.indexOf("?")<0?"?":"&")+e.params.join("&")),g.open("POST",k,!0),b.withCredentials&&(g.withCredentials="true"),c.headers&&c.headers["X-Requested-With"]||g.setRequestHeader("X-Requested-With","XMLHttpRequest"),b.each(c.headers,function(a,b){g.setRequestHeader(b,a)}),c._chunked){g.upload&&g.upload.addEventListener("progress",b.throttle(function(a){e.retry||c.progress({type:a.type,total:e.size,loaded:e.start+a.loaded,totalSize:e.size},h,c)},100),!1),g.onreadystatechange=function(){var a=parseInt(g.getResponseHeader("X-Last-Known-Byte"),10);if(h.status=g.status,h.statusText=g.statusText,h.readyState=g.readyState,4==g.readyState){for(var d in f)h["response"+d]=g["response"+d];if(g.onreadystatechange=null,!g.status||g.status-201>0)if(b.log("Error: "+g.status),(!g.status&&!g.aborted||500==g.status||416==g.status)&&++e.retry<=c.chunkUploadRetry){var i=g.status?0:b.chunkNetworkDownRetryTimeout;c.pause(e.file,c),b.log("X-Last-Known-Byte: "+a),a?e.end=a:(e.end=e.start-1,416==g.status&&(e.end=e.end-c.chunkSize)),setTimeout(function(){h._send(c,e)},i)}else h.end(g.status);else e.retry=0,e.end==e.size-1?h.end(g.status):(b.log("X-Last-Known-Byte: "+a),a&&(e.end=a),e.file.FileAPIReadPosition=e.end,setTimeout(function(){h._send(c,e)},0));g=null}},e.start=e.end+1,e.end=Math.max(Math.min(e.start+c.chunkSize,e.size)-1,e.start);var q=e.file,r=(q.slice||q.mozSlice||q.webkitSlice).call(q,e.start,e.end+1);e.size&&!r.size?setTimeout(function(){h.end(-1)}):(g.setRequestHeader("Content-Range","bytes "+e.start+"-"+e.end+"/"+e.size),g.setRequestHeader("Content-Disposition","attachment; filename="+encodeURIComponent(e.name)),g.setRequestHeader("Content-Type",e.type||"application/octet-stream"),g.send(r)),q=r=null}else if(g.upload&&g.upload.addEventListener("progress",b.throttle(function(a){c.progress(a,h,c)},100),!1),g.onreadystatechange=function(){if(h.status=g.status,h.statusText=g.statusText,h.readyState=g.readyState,4==g.readyState){for(var a in f)h["response"+a]=g["response"+a];if(g.onreadystatechange=null,!g.status||g.status>201)if(b.log("Error: "+g.status),(!g.status&&!g.aborted||500==g.status)&&(c.retry||0)=0?a+"px":a}function d(a){var b,c=f.createElement("canvas"),d=!1;try{b=c.getContext("2d"),b.drawImage(a,0,0,1,1),d=255!=b.getImageData(0,0,1,1).data[4]}catch(e){}return d}var e=a.URL||a.webkitURL,f=a.document,g=a.navigator,h=g.getUserMedia||g.webkitGetUserMedia||g.mozGetUserMedia||g.msGetUserMedia,i=!!h;b.support.media=i;var j=function(a){this.video=a};j.prototype={isActive:function(){return!!this._active},start:function(a){var b,c,f=this,i=f.video,j=function(d){f._active=!d,clearTimeout(c),clearTimeout(b),a&&a(d,f)};h.call(g,{video:!0},function(a){f.stream=a,i.src=e.createObjectURL(a),b=setInterval(function(){d(i)&&j(null)},1e3),c=setTimeout(function(){j("timeout")},5e3),i.play()},j)},stop:function(){try{this._active=!1,this.video.pause(),this.stream.stop()}catch(a){}},shot:function(){return new k(this.video)}},j.get=function(a){return new j(a.firstChild)},j.publish=function(d,e,g){"function"==typeof e&&(g=e,e={}),e=b.extend({},{width:"100%",height:"100%",start:!0},e),d.jquery&&(d=d[0]);var h=function(a){if(a)g(a);else{var b=j.get(d);e.start?b.start(g):g(null,b)}};if(d.style.width=c(e.width),d.style.height=c(e.height),b.html5&&i){var k=f.createElement("video");k.style.width=c(e.width),k.style.height=c(e.height),a.jQuery?jQuery(d).empty():d.innerHTML="",d.appendChild(k),h()}else j.fallback(d,e,h)},j.fallback=function(a,b,c){c("not_support_camera")};var k=function(a){var c=a.nodeName?b.Image.toCanvas(a):a,d=b.Image(c);return d.type="image/png",d.width=c.width,d.height=c.height,d.size=c.width*c.height*4,d};j.Shot=k,b.Camera=j}(window,FileAPI),function(a,b,c){"use strict";var d=c.each,e=[];!c.support.flash||!c.media||c.support.media&&c.html5||!function(){function a(a){var b=a.wid=c.uid();return c.Flash._fn[b]=a,"FileAPI.Flash._fn."+b}function b(a){try{c.Flash._fn[a.wid]=null,delete c.Flash._fn[a.wid] -}catch(b){}}var f=c.Flash;c.extend(c.Flash,{patchCamera:function(){c.Camera.fallback=function(d,e,g){var h=c.uid();c.log("FlashAPI.Camera.publish: "+h),f.publish(d,h,c.extend(e,{camera:!0,onEvent:a(function i(a){"camera"===a.type&&(b(i),a.error?(c.log("FlashAPI.Camera.publish.error: "+a.error),g(a.error)):(c.log("FlashAPI.Camera.publish.success: "+h),g(null)))})}))},d(e,function(a){c.Camera.fallback.apply(c.Camera,a)}),e=[],c.extend(c.Camera.prototype,{_id:function(){return this.video.id},start:function(d){var e=this;f.cmd(this._id(),"camera.on",{callback:a(function g(a){b(g),a.error?(c.log("FlashAPI.camera.on.error: "+a.error),d(a.error,e)):(c.log("FlashAPI.camera.on.success: "+e._id()),e._active=!0,d(null,e))})})},stop:function(){this._active=!1,f.cmd(this._id(),"camera.off")},shot:function(){c.log("FlashAPI.Camera.shot:",this._id());var a=c.Flash.cmd(this._id(),"shot",{});return a.type="image/png",a.flashId=this._id(),a.isShot=!0,new c.Camera.Shot(a)}})}}),c.Camera.fallback=function(){e.push(arguments)}}()}(window,window.jQuery,FileAPI),"function"==typeof define&&define.amd&&define("FileAPI",[],function(){return FileAPI}); \ No newline at end of file +/*! FileAPI 2.1.1 - BSD | git://github.com/mailru/FileAPI.git */ +!function(a){"use strict";var b=a.HTMLCanvasElement&&a.HTMLCanvasElement.prototype,c=a.Blob&&function(){try{return Boolean(new Blob)}catch(a){return!1}}(),d=c&&a.Uint8Array&&function(){try{return 100===new Blob([new Uint8Array(100)]).size}catch(a){return!1}}(),e=a.BlobBuilder||a.WebKitBlobBuilder||a.MozBlobBuilder||a.MSBlobBuilder,f=(c||e)&&a.atob&&a.ArrayBuffer&&a.Uint8Array&&function(a){var b,f,g,h,i,j;for(b=a.split(",")[0].indexOf("base64")>=0?atob(a.split(",")[1]):decodeURIComponent(a.split(",")[1]),f=new ArrayBuffer(b.length),g=new Uint8Array(f),h=0;h0,I=a.dataURLtoBlob,J=/img/i,K=/canvas/i,L=/img|canvas/i,M=/input/i,N=/^data:[^,]+,/,O={}.toString,P=a.Math,Q=function(b){return b=new a.Number(P.pow(1024,b)),b.from=function(a){return P.round(a*this)},b},R={},S=[],T="abort progress error load loadend",U="status statusText readyState response responseXML responseText responseBody".split(" "),V="currentTarget",W="preventDefault",X=function(a){return a&&"length"in a},Y=function(a,b,c){if(a)if(X(a))for(var d=0,e=a.length;d=c&&!d&&f.end()},isFail:function(){return d},fail:function(){!d&&a(d=!0)},end:function(){e||(e=!0,a())}};return f},each:Y,afor:function(a,b){var c=0,d=a.length;X(a)&&d--?function e(){b(d!=c&&e,a[c],c++)}():b(!1)},extend:Z,isFile:function(a){return"[object File]"===O.call(a)},isBlob:function(a){return this.isFile(a)||"[object Blob]"===O.call(a)},isCanvas:function(a){return a&&K.test(a.nodeName)},getFilesFilter:function(a){return a="string"==typeof a?a:a.getAttribute&&a.getAttribute("accept")||"",a?new RegExp("("+a.replace(/\./g,"\\.").replace(/,/g,"|")+")$","i"):/./},readAsDataURL:function(a,b){da.isCanvas(a)?c(a,b,"load",da.toDataURL(a)):e(a,b,"DataURL")},readAsBinaryString:function(a,b){d("BinaryString")?e(a,b,"BinaryString"):e(a,function(a){if("load"==a.type)try{a.result=da.toBinaryString(a.result)}catch(b){a.type="error",a.message=b.toString()}b(a)},"DataURL")},readAsArrayBuffer:function(a,b){e(a,b,"ArrayBuffer")},readAsText:function(a,b,c){c||(c=b,b="utf-8"),e(a,c,"Text",b)},toDataURL:function(a,b){return"string"==typeof a?a:a.toDataURL?a.toDataURL(b||"image/png"):void 0},toBinaryString:function(b){return a.atob(da.toDataURL(b).replace(N,""))},readAsImage:function(a,d,e){if(da.isBlob(a))if(x){var f=x.createObjectURL(a);f===b?c(a,d,"error"):da.readAsImage(f,d,e)}else da.readAsDataURL(a,function(b){"load"==b.type?da.readAsImage(b.result,d,e):(e||"error"==b.type)&&c(a,d,b,null,{loaded:b.loaded,total:b.total})});else if(da.isCanvas(a))c(a,d,"load",a);else if(J.test(a.nodeName))if(a.complete)c(a,d,"load",a);else{var g="error abort load";aa(a,g,function b(e){"load"==e.type&&x&&x.revokeObjectURL(a.src),_(a,g,b),c(a,d,e,a)})}else if(a.iframe)c(a,d,{type:"error"});else{var h=da.newImage(a.dataURL||a);da.readAsImage(h,d,e)}},checkFileObj:function(a){var b={},c=da.accept;return"object"==typeof a?b=a:b.name=(a+"").split(/\\|\//g).pop(),null==b.type&&(b.type=b.name.split(".").pop()),Y(c,function(a,c){a=new RegExp(a.replace(/\s/g,"|"),"i"),(a.test(b.type)||da.ext2mime[b.type])&&(b.type=da.ext2mime[b.type]||c.split("/")[0]+"/"+b.type)}),b},getDropFiles:function(a,b){var c,d=[],e=[],j=l(a),k=j.files,m=j.items,n=X(m)&&m[0]&&h(m[0]),o=da.queue(function(){b(d,e)});if(n)if(H&&k){var p,q,r=k.length;for(c=new Array(r);r--;){p=k[r];try{q=h(m[r])}catch(a){da.log("[err] getDropFiles: ",a),q=null}g(q)&&(q.isDirectory||q.isFile&&p.name==p.name.normalize("NFC"))?c[r]=q:c[r]=p}}else c=m;else c=k;Y(c||[],function(a){o.inc();try{n&&g(a)?i(a,function(a,b,c){a?da.log("[err] getDropFiles:",a):d.push.apply(d,b),e.push.apply(e,c),o.next()}):f(a,function(b,c){b?d.push(a):a.error=c,e.push(a),o.next()})}catch(a){o.next(),da.log("[err] getDropFiles: ",a)}}),o.check()},getFiles:function(a,b,c){var d=[];return c?(da.filterFiles(da.getFiles(a),b,c),null):(a.jquery&&(a.each(function(){d=d.concat(da.getFiles(this))}),a=d,d=[]),"string"==typeof b&&(b=da.getFilesFilter(b)),a.originalEvent?a=ba(a.originalEvent):a.srcElement&&(a=ba(a)),a.dataTransfer?a=a.dataTransfer:a.target&&(a=a.target),a.files?(d=a.files,E||(d[0].blob=a,d[0].iframe=!0)):!E&&k(a)?da.trim(a.value)&&(d=[da.checkFileObj(a.value)],d[0].blob=a,d[0].iframe=!0):X(a)&&(d=a),da.filter(d,function(a){return!b||b.test(a.name)}))},getTotalSize:function(a){for(var b=0,c=a&&a.length;c--;)b+=a[c].size;return b},getInfo:function(a,b){var c={},d=S.concat();da.isBlob(a)?function e(){var f=d.shift();f?f.test(a.type)?f(a,function(a,d){a?b(a):(Z(c,d),e())}):e():b(!1,c)}():b("not_support_info",c)},addInfoReader:function(a,b){b.test=function(b){return a.test(b)},S.push(b)},filter:function(a,b){for(var c,d=[],e=0,f=a.length;e>2,k=(3&g)<<4|h>>4;isNaN(h)?e=f=64:(e=(15&h)<<2|i>>6,f=isNaN(i)?64:63&i),c+=b.charAt(j)+b.charAt(k)+b.charAt(e)+b.charAt(f)}return c}};da.addInfoReader(/^image/,function(a,b){if(!a.__dimensions){var c=a.__dimensions=da.defer();da.readAsImage(a,function(a){var b=a.target;c.resolve("load"!=a.type&&"error",{width:b.width,height:b.height}),b.src=da.EMPTY_PNG,b=null})}a.__dimensions.then(b)}),da.event.dnd=function(a,b,c){var d,e;c||(c=b,b=da.F),A?($(a,"dragenter dragleave dragover",b.ff=b.ff||function(a){for(var c=l(a).types,f=c&&c.length,g=!1;f--;)if(~c[f].indexOf("File")){a[W](),e!==a.type&&(e=a.type,"dragleave"!=e&&b.call(a[V],!0,a),g=!0);break}g&&(clearTimeout(d),d=setTimeout(function(){b.call(a[V],"dragleave"!=e,a)},50))}),$(a,"drop",c.ff=c.ff||function(a){a[W](),e=0,da.getDropFiles(a,function(b,d){c.call(a[V],b,d,a)}),b.call(a[V],!1,a)})):da.log("Drag'n'Drop -- not supported")},da.event.dnd.off=function(a,b,c){_(a,"dragenter dragleave dragover",b.ff),_(a,"drop",c.ff)},D&&!D.fn.dnd&&(D.fn.dnd=function(a,b){return this.each(function(){da.event.dnd(this,a,b)})},D.fn.offdnd=function(a,b){return this.each(function(){da.event.dnd.off(this,a,b)})}),a.FileAPI=Z(da,a.FileAPI),da.log("FileAPI: "+da.version),da.log("protocol: "+a.location.protocol),da.log("doctype: ["+s.name+"] "+s.publicId+" "+s.systemId),Y(r.getElementsByTagName("meta"),function(a){/x-ua-compatible/i.test(a.getAttribute("http-equiv"))&&da.log("meta.http-equiv: "+a.getAttribute("content"))});try{n=!!console.log,o=!!console.log.apply}catch(a){}da.flashUrl||(da.flashUrl=da.staticPath+"FileAPI.flash.swf"),da.flashImageUrl||(da.flashImageUrl=da.staticPath+"FileAPI.flash.image.swf"),da.flashWebcamUrl||(da.flashWebcamUrl=da.staticPath+"FileAPI.flash.camera.swf")}(window,void 0),function(a,b,c){"use strict";function d(b){if(b instanceof d){var c=new d(b.file);return a.extend(c.matrix,b.matrix),c}if(!(this instanceof d))return new d(b);this.file=b,this.size=b.size||100,this.matrix={sx:0,sy:0,sw:0,sh:0,dx:0,dy:0,dw:0,dh:0,resize:0,deg:0,quality:1,filter:0}}var e=Math.min,f=Math.round,g=function(){return b.createElement("canvas")},h=!1,i={8:270,3:180,6:90,7:270,4:180,5:90};try{h=g().toDataURL("image/png").indexOf("data:image/png")>-1}catch(a){}d.prototype={image:!0,constructor:d,set:function(b){return a.extend(this.matrix,b),this},crop:function(a,b,d,e){return d===c&&(d=a,e=b,a=b=0),this.set({sx:a,sy:b,sw:d,sh:e||d})},resize:function(a,b,c){return/min|max|height|width/.test(b)&&(c=b,b=a),this.set({dw:a,dh:b||a,resize:c})},preview:function(a,b){return this.resize(a,b||a,"preview")},rotate:function(a){return this.set({deg:a})},filter:function(a){return this.set({filter:a})},overlay:function(a){return this.set({overlay:a})},clone:function(){return new d(this)},_load:function(b,c){var d=this;/img|video/i.test(b.nodeName)?c.call(d,null,b):a.readAsImage(b,function(a){c.call(d,"load"!=a.type,a.result)})},_apply:function(b,c){var f,h=g(),i=this.getMatrix(b),j=h.getContext("2d"),k=b.videoWidth||b.width,l=b.videoHeight||b.height,m=i.deg,n=i.dw,o=i.dh,p=k,q=l,r=i.filter,s=b,t=i.overlay,u=a.queue(function(){b.src=a.EMPTY_PNG,c(!1,h)}),v=a.renderImageToCanvas;for(m-=360*Math.floor(m/360),b._type=this.file.type;i.multipass&&e(p/n,q/o)>2;)p=p/2+.5|0,q=q/2+.5|0,f=g(),f.width=p,f.height=q,s!==b?(v(f,s,0,0,s.width,s.height,0,0,p,q),s=f):(s=f,v(s,b,i.sx,i.sy,i.sw,i.sh,0,0,p,q),i.sx=i.sy=i.sw=i.sh=0);h.width=m%180?o:n,h.height=m%180?n:o,h.type=i.type,h.quality=i.quality,j.rotate(m*Math.PI/180),v(j.canvas,s,i.sx,i.sy,i.sw||s.width,i.sh||s.height,180==m||270==m?-n:0,90==m||180==m?-o:0,n,o),n=h.width,o=h.height,t&&a.each([].concat(t),function(b){u.inc();var c=new window.Image,d=function(){var e=0|b.x,f=0|b.y,g=b.w||c.width,h=b.h||c.height,i=b.rel;e=1==i||4==i||7==i?(n-g+e)/2:2==i||5==i||8==i?n-(g+e):e,f=3==i||4==i||5==i?(o-h+f)/2:i>=6?o-(h+f):f,a.event.off(c,"error load abort",d);try{j.globalAlpha=b.opacity||1,j.drawImage(c,e,f,g,h)}catch(a){}u.next()};a.event.on(c,"error load abort",d),c.src=b.src,c.complete&&d()}),r&&(u.inc(),d.applyFilter(h,r,u.next)),u.check()},getMatrix:function(b){var c=a.extend({},this.matrix),d=c.sw=c.sw||b.videoWidth||b.naturalWidth||b.width,g=c.sh=c.sh||b.videoHeight||b.naturalHeight||b.height,h=c.dw=c.dw||d,i=c.dh=c.dh||g,j=d/g,k=h/i,l=c.resize;if("preview"==l){if(h!=d||i!=g){var m,n;k>=j?(m=d,n=m/k):(n=g,m=n*k),m==d&&n==g||(c.sx=~~((d-m)/2),c.sy=~~((g-n)/2),d=m,g=n)}}else"height"==l?h=i*j:"width"==l?i=h/j:l&&(d>h||g>i?"min"==l?(h=f(j=k?e(d,h):i*j),i=f(j>=k?h/j:e(g,i))):(h=d,i=g));return c.sw=d,c.sh=g,c.dw=h,c.dh=i,c.multipass=a.multiPassResize,c},_trans:function(b){this._load(this.file,function(c,d){if(c)b(c);else try{this._apply(d,b)}catch(c){a.log("[err] FileAPI.Image.fn._apply:",c),b(c)}})},get:function(b){if(a.support.transform){var c=this,d=c.matrix;"auto"==d.deg?a.getInfo(c.file,function(a,e){d.deg=i[e&&e.exif&&e.exif.Orientation]||0,c._trans(b)}):c._trans(b)}else b("not_support_transform");return this},toData:function(a){return this.get(a)}},d.exifOrientation=i,d.transform=function(b,e,f,g){function h(h,i){var j={},k=a.queue(function(a){g(a,j)});h?k.fail():a.each(e,function(a,e){if(!k.isFail()){var g=new d(i.nodeType?i:b),h="function"==typeof a;if(h?a(i,g):a.width?g[a.preview?"preview":"resize"](a.width,a.height,a.strategy):a.maxWidth&&(i.width>a.maxWidth||i.height>a.maxHeight)&&g.resize(a.maxWidth,a.maxHeight,"max"),a.crop){var l=a.crop;g.crop(0|l.x,0|l.y,l.w||l.width,l.h||l.height)}a.rotate===c&&f&&(a.rotate="auto"),g.set({type:g.matrix.type||a.type||b.type||"image/png"}),h||g.set({deg:a.rotate,overlay:a.overlay,filter:a.filter,quality:a.quality||1}),k.inc(),g.toData(function(a,b){a?k.fail():(j[e]=b,k.next())})}})}b.width?h(!1,b):a.getInfo(b,h)},a.each(["TOP","CENTER","BOTTOM"],function(b,c){a.each(["LEFT","CENTER","RIGHT"],function(a,e){d[b+"_"+a]=3*c+e,d[a+"_"+b]=3*c+e})}),d.toCanvas=function(a){var c=b.createElement("canvas");return c.width=a.videoWidth||a.width,c.height=a.videoHeight||a.height,c.getContext("2d").drawImage(a,0,0),c},d.fromDataURL=function(b,c,d){var e=a.newImage(b);a.extend(e,c),d(e)},d.applyFilter=function(b,c,e){"function"==typeof c?c(b,e):window.Caman&&window.Caman("IMG"==b.tagName?d.toCanvas(b):b,function(){"string"==typeof c?this[c]():a.each(c,function(a,b){this[b](a)},this),this.render(e)})},a.renderImageToCanvas=function(b,c,d,e,f,g,h,i,j,k){try{return b.getContext("2d").drawImage(c,d,e,f,g,h,i,j,k)}catch(b){throw a.log("renderImageToCanvas failed"),b}},a.support.canvas=a.support.transform=h,a.Image=d}(FileAPI,document),function(a){"use strict";a(FileAPI)}(function(a){"use strict";if(window.navigator&&window.navigator.platform&&/iP(hone|od|ad)/.test(window.navigator.platform)){var b=a.renderImageToCanvas;a.detectSubsampling=function(a){var b,c;return a.width*a.height>1048576&&(b=document.createElement("canvas"),b.width=b.height=1,c=b.getContext("2d"),c.drawImage(a,1-a.width,0),0===c.getImageData(0,0,1,1).data[3])},a.detectVerticalSquash=function(a,b){var c,d,e,f,g,h=a.naturalHeight||a.height,i=document.createElement("canvas"),j=i.getContext("2d");for(b&&(h/=2),i.width=1,i.height=h,j.drawImage(a,0,0),c=j.getImageData(0,0,1,h).data,d=0,e=h,f=h;f>d;)g=c[4*(f-1)+3],0===g?e=f:d=f,f=e+d>>1;return f/h||1},a.renderImageToCanvas=function(c,d,e,f,g,h,i,j,k,l){if("image/jpeg"===d._type){var m,n,o,p,q=c.getContext("2d"),r=document.createElement("canvas"),s=1024,t=r.getContext("2d");if(r.width=s,r.height=s,q.save(),m=a.detectSubsampling(d),m&&(e/=2,f/=2,g/=2,h/=2),n=a.detectVerticalSquash(d,m),m||1!==n){for(f*=n,k=Math.ceil(s*k/g),l=Math.ceil(s*l/h/n),j=0,p=0;p0&&1==a.filter(this.items,function(a){return a.file}).length,a.support.html5?a.formData&&!this.multipart&&e?c._chunked?(a.log("FileAPI.Form.toPlainData"),this.toPlainData(b)):(a.log("FileAPI.Form.toFormData"),this.toFormData(b)):(a.log("FileAPI.Form.toMultipartData"),this.toMultipartData(b)):(a.log("FileAPI.Form.toHtmlData"),this.toHtmlData(b))},_to:function(b,c,d,e){var f=a.queue(function(){c(b)});this.each(function(g){try{d(g,b,f,e)}catch(b){a.log("FileAPI.Form._to: "+b.message),c(b)}}),f.check()},toHtmlData:function(b){this._to(d.createDocumentFragment(),b,function(b,c){var e,f=b.blob;b.file?(a.reset(f,!0),f.name=b.name,f.disabled=!1,c.appendChild(f)):(e=d.createElement("input"),e.name=b.name,e.type="hidden",e.value=f,c.appendChild(e))})},toPlainData:function(a){this._to({},a,function(a,b,d){a.file&&(b.type=a.file),a.blob.toBlob?(d.inc(),c(a,function(a,c){b.name=a.name,b.file=c,b.size=c.length,b.type=a.type,d.next()})):a.file?(b.name=a.blob.name,b.file=a.blob,b.size=a.blob.size,b.type=a.type):(b.params||(b.params=[]),b.params.push(g(a.name)+"="+g(a.blob))),b.start=-1,b.end=b.file&&b.file.FileAPIReadPosition||-1,b.retry=0})},toFormData:function(a){this._to(new e,a,function(a,b,d){a.blob&&a.blob.toBlob?(d.inc(),c(a,function(a,c){b.append(a.name,c,a.file),d.next()})):a.file?b.append(a.name,a.blob,a.file):b.append(a.name,a.blob),a.file&&b.append("_"+a.name,a.file)})},toMultipartData:function(b){this._to([],b,function(a,b,d,e){d.inc(),c(a,function(a,c){b.push("--_"+e+'\r\nContent-Disposition: form-data; name="'+a.name+'"'+(a.file?'; filename="'+g(a.file)+'"':"")+(a.file?"\r\nContent-Type: "+(a.type||"application/octet-stream"):"")+"\r\n\r\n"+(a.file?c:g(c))+"\r\n"),d.next()},!0)},a.expando)}},a.Form=f}(FileAPI,window),function(a,b){"use strict";var c=function(){},d=a.document,e=function(a){this.uid=b.uid(),this.xhr={abort:c,getResponseHeader:c,getAllResponseHeaders:c},this.options=a},f={"":1,XML:1,Text:1,Body:1};e.prototype={status:0,statusText:"",constructor:e,getResponseHeader:function(a){return this.xhr.getResponseHeader(a)},getAllResponseHeaders:function(){return this.xhr.getAllResponseHeaders()||{}},end:function(d,e){var f=this,g=f.options;f.end=f.abort=c,f.status=d,e&&(f.statusText=e),b.log("xhr.end:",d,e),g.complete(200!=d&&201!=d&&(f.statusText||"unknown"),f),f.xhr&&f.xhr.node&&setTimeout(function(){var b=f.xhr.node;try{b.parentNode.removeChild(b)}catch(a){}try{delete a[f.uid]}catch(a){}a[f.uid]=f.xhr.node=null},9)},abort:function(){this.end(0,"abort"),this.xhr&&(this.xhr.aborted=!0,this.xhr.abort())},send:function(a){var b=this,c=this.options;a.toData(function(a){a instanceof Error?b.end(0,a.message):(c.upload(c,b),b._send.call(b,c,a))},c)},_send:function(c,e){var g,h=this,i=h.uid,j=h.uid+"Load",k=c.url;if(b.log("XHR._send:",e),c.cache||(k+=(~k.indexOf("?")?"&":"?")+b.uid()),e.nodeName){var l=c.jsonp;k=k.replace(/([a-z]+)=(\?)/i,"$1="+i),c.upload(c,h);var m=function(a){if(~k.indexOf(a.origin))try{var c=b.parseJSON(a.data);c.id==i&&n(c.status,c.statusText,c.response)}catch(a){n(0,a.message)}},n=a[i]=function(c,d,e){h.readyState=4,h.responseText=e,h.end(c,d),b.event.off(a,"message",m),a[i]=g=p=a[j]=null};h.xhr.abort=function(){try{p.stop?p.stop():p.contentWindow.stop?p.contentWindow.stop():p.contentWindow.document.execCommand("Stop")}catch(a){}n(0,"abort")},b.event.on(a,"message",m),a[j]=function(){try{var a=p.contentWindow,c=a.document,d=a.result||b.parseJSON(c.body.innerHTML);n(d.status,d.statusText,d.response)}catch(a){b.log("[transport.onload]",a)}},g=d.createElement("div"),g.innerHTML='
'+(l&&c.url.indexOf("=?")<0?'':"")+"
";var o=g.getElementsByTagName("form")[0],p=g.getElementsByTagName("iframe")[0];o.appendChild(e),b.log(o.parentNode.innerHTML),d.body.appendChild(g),h.xhr.node=g,h.readyState=2;try{o.submit()}catch(a){b.log("iframe.error: "+a)}o=null}else{if(k=k.replace(/([a-z]+)=(\?)&?/i,""),this.xhr&&this.xhr.aborted)return void b.log("Error: already aborted");if(g=h.xhr=b.getXHR(),e.params&&(k+=(k.indexOf("?")<0?"?":"&")+e.params.join("&")),g.open(c.uploadMethod||"POST",k,!0),"boolean"==typeof c.uploadCredentials?g.withCredentials=c.uploadCredentials?"true":null:b.withCredentials&&(g.withCredentials="true"),c.headers&&c.headers["X-Requested-With"]||g.setRequestHeader("X-Requested-With","XMLHttpRequest"),b.each(c.headers,function(a,b){g.setRequestHeader(b,a)}),c._chunked){g.upload&&g.upload.addEventListener("progress",b.throttle(function(a){e.retry||c.progress({type:a.type,total:e.size,loaded:e.start+a.loaded,totalSize:e.size},h,c)},100),!1),g.onreadystatechange=function(){var a=parseInt(g.getResponseHeader("X-Last-Known-Byte"),10);if(h.status=g.status,h.statusText=g.statusText,h.readyState=g.readyState,4==g.readyState){for(var d in f)h["response"+d]=g["response"+d];if(g.onreadystatechange=null,!g.status||g.status-201>0)if(b.log("Error: "+g.status),(!g.status&&!g.aborted||500==g.status||416==g.status)&&++e.retry<=c.chunkUploadRetry){var i=g.status?0:b.chunkNetworkDownRetryTimeout;c.pause(e.file,c),b.log("X-Last-Known-Byte: "+a),a?e.end=a:(e.end=e.start-1,416==g.status&&(e.end=e.end-c.chunkSize)),setTimeout(function(){h._send(c,e)},i)}else h.end(g.status);else e.retry=0,e.end==e.size-1?h.end(g.status):(b.log("X-Last-Known-Byte: "+a),a&&(e.end=a),e.file.FileAPIReadPosition=e.end,setTimeout(function(){h._send(c,e)},0));g=null}},e.start=e.end+1,e.end=Math.max(Math.min(e.start+c.chunkSize,e.size)-1,e.start);var q=e.file,r=(q.slice||q.mozSlice||q.webkitSlice).call(q,e.start,e.end+1);e.size&&!r.size?setTimeout(function(){h.end(-1)}):(g.setRequestHeader("Content-Range","bytes "+e.start+"-"+e.end+"/"+e.size),g.setRequestHeader("Content-Disposition","attachment; filename="+encodeURIComponent(e.name)),g.setRequestHeader("Content-Type",e.type||"application/octet-stream"),g.send(r)),q=r=null}else if(g.upload&&g.upload.addEventListener("progress",b.throttle(function(a){c.progress(a,h,c)},100),!1),g.onreadystatechange=function(){if(h.status=g.status,h.statusText=g.statusText,h.readyState=g.readyState,4==g.readyState){for(var a in f)h["response"+a]=g["response"+a];if(g.onreadystatechange=null,!g.status||g.status>201)if(b.log("Error: "+g.status),(!g.status&&!g.aborted||500==g.status)&&(c.retry||0)=0?a+"px":a}function d(a){var c,d=f.createElement("canvas"),e=!1;try{c=d.getContext("2d"),c.drawImage(a,0,0,1,1),e=255!=c.getImageData(0,0,1,1).data[4]}catch(a){b.log("[FileAPI.Camera] detectVideoSignal:",a)}return e}var e=a.URL||a.webkitURL,f=a.document,g=a.navigator,h=g.getUserMedia||g.webkitGetUserMedia||g.mozGetUserMedia||g.msGetUserMedia,i=!!h;b.support.media=i;var j=function(a){this.video=a};j.prototype={isActive:function(){return!!this._active},start:function(a){var b,c,f=this,i=f.video,j=function(d){f._active=!d,clearTimeout(c),clearTimeout(b),a&&a(d,f)};h.call(g,{video:!0},function(a){f.stream=a;try{i.src=e.createObjectURL(a)}catch(b){i.srcObject=a}b=setInterval(function(){d(i)&&j(null)},1e3),c=setTimeout(function(){j("timeout")},5e3),i.play()},j)},stop:function(){try{this._active=!1,this.video.pause();try{this.stream.stop()}catch(a){b.each(this.stream.getTracks(),function(a){a.stop()})}this.stream=null}catch(a){b.log("[FileAPI.Camera] stop:",a)}},shot:function(){return new k(this.video)}},j.get=function(a){return new j(a.firstChild)},j.publish=function(d,e,g){"function"==typeof e&&(g=e,e={}),e=b.extend({},{width:"100%",height:"100%",start:!0},e),d.jquery&&(d=d[0]);var h=function(a){if(a)g(a);else{var b=j.get(d);e.start?b.start(g):g(null,b)}};if(d.style.width=c(e.width),d.style.height=c(e.height),b.html5&&i&&!b.insecureChrome){var k=f.createElement("video");k.style.width=c(e.width),k.style.height=c(e.height),a.jQuery?jQuery(d).empty():d.innerHTML="",d.appendChild(k),h()}else j.fallback(d,e,h)},j.fallback=function(a,b,c){c("not_support_camera")},j.checkAlreadyCaptured=function(){var b,c=g.mediaDevices,d=a.MediaStreamTrack,e=g.enumerateDevices;return b=c&&c.enumerateDevices?function(a){c.enumerateDevices().then(a)}:d&&d.getSources?d.getSources.bind(d):e?e.bind(g):function(a){a([])},function(a){b(function(b){var c=b.some(function(a){return("videoinput"===a.kind||"video"===a.kind)&&a.label});a(c)})}}();var k=function(a){var c=a.nodeName?b.Image.toCanvas(a):a,d=b.Image(c);return d.type="image/png",d.width=c.width,d.height=c.height,d.size=c.width*c.height*4,d};j.Shot=k,b.Camera=j}(window,FileAPI),function(a,b,c){"use strict";var d=c.each,e=[];!c.support.flash||!c.media||c.support.media&&c.html5&&!c.insecureChrome||function(){function a(a){var b=a.wid=c.uid();return c.Flash._fn[b]=a,"FileAPI.Flash._fn."+b}function b(a){try{c.Flash._fn[a.wid]=null,delete c.Flash._fn[a.wid]}catch(a){}}var f=c.Flash;c.extend(c.Flash,{patchCamera:function(){c.Camera.fallback=function(d,e,g){var h=c.uid();c.log("FlashAPI.Camera.publish: "+h),f.publish(d,h,c.extend(e,{camera:!0,onEvent:a(function a(d){"camera"===d.type&&(b(a),d.error?(c.log("FlashAPI.Camera.publish.error: "+d.error),g(d.error)):(c.log("FlashAPI.Camera.publish.success: "+h),g(null)))})}))},d(e,function(a){c.Camera.fallback.apply(c.Camera,a)}),e=[],c.extend(c.Camera.prototype,{_id:function(){return this.video.id},start:function(d){var e=this;f.cmd(this._id(),"camera.on",{callback:a(function a(f){b(a),f.error?(c.log("FlashAPI.camera.on.error: "+f.error),d(f.error,e)):(c.log("FlashAPI.camera.on.success: "+e._id()),e._active=!0,d(null,e))})})},stop:function(){this._active=!1,f.cmd(this._id(),"camera.off")},shot:function(){c.log("FlashAPI.Camera.shot:",this._id());var a=c.Flash.cmd(this._id(),"shot",{});return a.type="image/png",a.flashId=this._id(),a.isShot=!0,new c.Camera.Shot(a)}})}}),c.Camera.fallback=function(){e.push(arguments)}}()}(window,window.jQuery,FileAPI),"function"==typeof define&&define.amd&&define("FileAPI",[],function(){return FileAPI}); \ No newline at end of file diff --git a/dist/FileAPI.js b/dist/FileAPI.js index b8506273..210de9d9 100644 --- a/dist/FileAPI.js +++ b/dist/FileAPI.js @@ -1,4 +1,4 @@ -/*! FileAPI 2.0.10 - BSD | git://github.com/mailru/FileAPI.git +/*! FileAPI 2.1.1 - BSD | git://github.com/mailru/FileAPI.git * FileAPI — a set of javascript tools for working with files. Multiupload, drag'n'drop and chunked file upload. Images: crop, resize and auto orientation by EXIF. */ @@ -105,6 +105,9 @@ document = window.document, doctype = document.doctype || {}, userAgent = window.navigator.userAgent, + safari = /safari\//i.test(userAgent) && !/chrome\//i.test(userAgent), + iemobile = /iemobile\//i.test(userAgent), + insecureChrome = !safari && /chrome\//i.test(userAgent) && window.location.protocol === 'http:', // https://github.com/blueimp/JavaScript-Load-Image/blob/master/load-image.js#L48 apiURL = (window.createObjectURL && window) || (window.URL && URL.revokeObjectURL && URL) || (window.webkitURL && webkitURL), @@ -119,12 +122,14 @@ jQuery = window.jQuery, html5 = !!(File && (FileReader && (window.Uint8Array || FormData || XMLHttpRequest.prototype.sendAsBinary))) - && !(/safari\//i.test(userAgent) && !/chrome\//i.test(userAgent) && /windows/i.test(userAgent)), // BugFix: https://github.com/mailru/FileAPI/issues/25 + && !(safari && /windows/i.test(userAgent) && !iemobile), // BugFix: https://github.com/mailru/FileAPI/issues/25 cors = html5 && ('withCredentials' in (new XMLHttpRequest)), chunked = html5 && !!Blob && !!(Blob.prototype.webkitSlice || Blob.prototype.mozSlice || Blob.prototype.slice), + normalize = ('' + ''.normalize).indexOf('[native code]') > 0, + // https://github.com/blueimp/JavaScript-Canvas-to-Blob dataURLtoBlob = window.dataURLtoBlob, @@ -136,6 +141,8 @@ _rdata = /^data:[^,]+,/, _toString = {}.toString, + _supportConsoleLog, + _supportConsoleLogApply, Math = window.Math, @@ -280,13 +287,14 @@ * FileAPI (core object) */ api = { - version: '2.0.10', + version: '2.1.1', cors: false, html5: true, media: false, formData: true, multiPassResize: true, + insecureChrome: insecureChrome, debug: false, pingUrl: false, @@ -340,8 +348,8 @@ }, log: function (){ - if( api.debug && window.console && console.log ){ - if( console.log.apply ){ + if( api.debug && _supportConsoleLog ){ + if( _supportConsoleLogApply ){ console.log.apply(console, arguments); } else { @@ -702,7 +710,7 @@ * @param {Boolean} [progress] */ readAsImage: function (file, fn, progress){ - if( api.isFile(file) ){ + if( api.isBlob(file) ){ if( apiURL ){ /** @namespace apiURL.createObjectURL */ var data = apiURL.createObjectURL(file); @@ -795,28 +803,84 @@ getDropFiles: function (evt, callback){ var files = [] + , all = [] + , items , dataTransfer = _getDataTransfer(evt) - , entrySupport = _isArray(dataTransfer.items) && dataTransfer.items[0] && _getAsEntry(dataTransfer.items[0]) - , queue = api.queue(function (){ callback(files); }) + , transFiles = dataTransfer.files + , transItems = dataTransfer.items + , entrySupport = _isArray(transItems) && transItems[0] && _getAsEntry(transItems[0]) + , queue = api.queue(function (){ callback(files, all); }) ; - _each((entrySupport ? dataTransfer.items : dataTransfer.files) || [], function (item){ + if( entrySupport ){ + if( normalize && transFiles ){ + var + i = transFiles.length + , file + , entry + ; + + items = new Array(i); + while( i-- ){ + file = transFiles[i]; + + try { + entry = _getAsEntry(transItems[i]); + } + catch( err ){ + api.log('[err] getDropFiles: ', err); + entry = null; + } + + if( _isEntry(entry) ){ + // OSX filesystems use Unicode Normalization Form D (NFD), + // and entry.file(…) can't read the files with the same names + if( entry.isDirectory || (entry.isFile && file.name == file.name.normalize('NFC')) ){ + items[i] = entry; + } + else { + items[i] = file; + } + } + else { + items[i] = file; + } + } + } + else { + items = transItems; + } + } + else { + items = transFiles; + } + + _each(items || [], function (item){ queue.inc(); try { - if( entrySupport ){ - _readEntryAsFiles(item, function (err, entryFiles){ + if( entrySupport && _isEntry(item) ){ + _readEntryAsFiles(item, function (err, entryFiles, allEntries){ if( err ){ api.log('[err] getDropFiles:', err); } else { files.push.apply(files, entryFiles); } + all.push.apply(all, allEntries); + queue.next(); }); } else { - _isRegularFile(item, function (yes){ - yes && files.push(item); + _isRegularFile(item, function (yes, err){ + if( yes ){ + files.push(item); + } + else { + item.error = err; + } + all.push(item); + queue.next(); }); } @@ -927,7 +991,7 @@ getInfo: function (file, fn){ var info = {}, readers = _infoReader.concat(); - if( api.isFile(file) ){ + if( api.isBlob(file) ){ (function _next(){ var reader = readers.shift(); if( reader ){ @@ -1307,7 +1371,13 @@ queue.inc(); file.toData(function (err, image){ - // @todo: error + // @todo: требует рефакторинга и обработки ошибки + if (file.file) { + image.type = file.file.type; + image.quality = file.matrix.quality; + filename = file.file && file.file.name; + } + filename = filename || (new Date).getTime()+'.png'; _addFile(image); @@ -1537,26 +1607,31 @@ function _isRegularFile(file, callback){ // http://stackoverflow.com/questions/8856628/detecting-folders-directories-in-javascript-filelist-objects - if( !file.type && (file.size % 4096) === 0 && (file.size <= 102400) ){ + if( !file.type && (safari || ((file.size % 4096) === 0 && (file.size <= 102400))) ){ if( FileReader ){ try { - var Reader = new FileReader(); + var reader = new FileReader(); - _one(Reader, _readerEvents, function (evt){ + _one(reader, _readerEvents, function (evt){ var isFile = evt.type != 'error'; - callback(isFile); if( isFile ){ - Reader.abort(); + if ( reader.readyState == null || reader.readyState === reader.LOADING ) { + reader.abort(); + } + callback(isFile); + } + else { + callback(false, reader.error); } }); - Reader.readAsDataURL(file); + reader.readAsDataURL(file); } catch( err ){ - callback(false); + callback(false, err); } } else { - callback(null); + callback(null, new Error('FileReader is not supported')); } } else { @@ -1565,6 +1640,11 @@ } + function _isEntry(item){ + return item && (item.isFile || item.isDirectory); + } + + function _getAsEntry(item){ var entry; if( item.getAsEntry ){ entry = item.getAsEntry(); } @@ -1576,34 +1656,52 @@ function _readEntryAsFiles(entry, callback){ if( !entry ){ // error - callback('invalid entry'); + var err = new Error('invalid entry'); + entry = new Object(entry); + entry.error = err; + callback(err.message, [], [entry]); } else if( entry.isFile ){ // Read as file - entry.file(function(file){ + entry.file(function (file){ // success file.fullPath = entry.fullPath; - callback(false, [file]); + callback(false, [file], [file]); }, function (err){ // error - callback('FileError.code: '+err.code); + entry.error = err; + callback('FileError.code: ' + err.code, [], [entry]); }); } else if( entry.isDirectory ){ - var reader = entry.createReader(), result = []; + var + reader = entry.createReader() + , firstAttempt = true + , files = [] + , all = [entry] + ; - var onerror = function() { + var onerror = function (err){ // error - callback('directory_reader'); + entry.error = err; + callback('DirectoryError.code: ' + err.code, files, all); }; - var ondone = function ondone(entries) { + var ondone = function ondone(entries){ + if( firstAttempt ){ + firstAttempt = false; + if( !entries.length ){ + entry.error = new Error('directory is empty'); + } + } + // success - if ( entries.length ) { + if( entries.length ){ api.afor(entries, function (next, entry){ - _readEntryAsFiles(entry, function (err, files){ + _readEntryAsFiles(entry, function (err, entryFiles, allEntries){ if( !err ){ - result = result.concat(files); + files = files.concat(entryFiles); } + all = all.concat(allEntries); if( next ){ next(); @@ -1615,7 +1713,7 @@ }); } else { - callback(false, result); + callback(false, files, all); } }; @@ -1738,11 +1836,12 @@ evt[preventDefault](); _type = 0; - onHover.call(evt[currentTarget], false, evt); - api.getDropFiles(evt, function (files){ - onDrop.call(evt[currentTarget], files, evt); + api.getDropFiles(evt, function (files, all){ + onDrop.call(evt[currentTarget], files, all, evt); }); + + onHover.call(evt[currentTarget], false, evt); }); } else { @@ -1796,7 +1895,13 @@ }); - // @configuration + // Configuration + try { + _supportConsoleLog = !!console.log; + _supportConsoleLogApply = !!console.log.apply; + } + catch (err) {} + if( !api.flashUrl ){ api.flashUrl = api.staticPath + 'FileAPI.flash.swf'; } if( !api.flashImageUrl ){ api.flashImageUrl = api.staticPath + 'FileAPI.flash.image.swf'; } if( !api.flashWebcamUrl ){ api.flashWebcamUrl = api.staticPath + 'FileAPI.flash.camera.swf'; } @@ -1979,6 +2084,9 @@ , (deg == 90 || deg == 180 ? -dh : 0) , dw, dh ); + + ctx.setTransform(1, 0, 0, 1, 0, 0); + dw = canvas.width; dh = canvas.height; @@ -2332,7 +2440,7 @@ loadImage.detectSubsampling = function (img) { var canvas, context; - if (img.width * img.height > 1024 * 1024) { // only consider mexapixel images + if (img.width * img.height > 1024 * 1024) { // only consider megapixel images canvas = document.createElement('canvas'); canvas.width = canvas.height = 1; context = canvas.getContext('2d'); @@ -2533,7 +2641,13 @@ }); this.each(function (file){ - next(file, data, queue, arg); + try{ + next(file, data, queue, arg); + } + catch( err ){ + api.log('FileAPI.Form._to: ' + err.message); + complete(err); + } }); queue.check(); @@ -2761,9 +2875,14 @@ var _this = this, options = this.options; FormData.toData(function (data){ - // Start uploading - options.upload(options, _this); - _this._send.call(_this, options, data); + if( data instanceof Error ){ + _this.end(0, data.message); + } + else{ + // Start uploading + options.upload(options, _this); + _this._send.call(_this, options, data); + } }, options); }, @@ -2861,7 +2980,11 @@ // send _this.readyState = 2; // loaded - form.submit(); + try { + form.submit(); + } catch (err) { + api.log('iframe.error: ' + err); + } form = null; } else { @@ -2879,9 +3002,11 @@ url += (url.indexOf('?') < 0 ? "?" : "&") + data.params.join("&"); } - xhr.open('POST', url, true); + xhr.open(options.uploadMethod || 'POST', url, true); - if( api.withCredentials ){ + if (typeof options.uploadCredentials === 'boolean') { + xhr.withCredentials = options.uploadCredentials ? 'true' : null; + } else if( api.withCredentials ){ xhr.withCredentials = "true"; } @@ -3142,7 +3267,11 @@ // }); // Set camera stream - video.src = URL.createObjectURL(stream); + try { + video.src = URL.createObjectURL(stream); + } catch (err) { + video.srcObject = stream; + } // Note: onloadedmetadata doesn't fire in Chrome when using it with getUserMedia. // See crbug.com/110938. @@ -3169,8 +3298,19 @@ try { this._active = false; this.video.pause(); - this.stream.stop(); - } catch( err ){ } + + try { + this.stream.stop(); + } catch (err) { + api.each(this.stream.getTracks(), function (track) { + track.stop(); + }); + } + + this.stream = null; + } catch( err ){ + api.log('[FileAPI.Camera] stop:', err); + } }, @@ -3245,7 +3385,7 @@ el.style.height = _px(options.height); - if( api.html5 && html5 ){ + if( api.html5 && html5 && !api.insecureChrome ){ // Create video element var video = document.createElement('video'); @@ -3276,6 +3416,38 @@ callback('not_support_camera'); }; + Camera.checkAlreadyCaptured = (function () { + var mediaDevices = navigator.mediaDevices, + MediaStreamTrack = window.MediaStreamTrack, + navigatorEnumerateDevices = navigator.enumerateDevices, + enumerateDevices; + + if (mediaDevices && mediaDevices.enumerateDevices) { + enumerateDevices = function (callback) { + mediaDevices.enumerateDevices().then(callback); + }; + } else if (MediaStreamTrack && MediaStreamTrack.getSources) { + enumerateDevices = MediaStreamTrack.getSources.bind(MediaStreamTrack); + } else if (navigatorEnumerateDevices) { + enumerateDevices = navigatorEnumerateDevices.bind(navigator); + } else { + enumerateDevices = function (fn) { + fn([]); + }; + } + + return function (callback) { + enumerateDevices(function (devices) { + var deviceExists = devices.some(function (device) { + return (device.kind === 'videoinput' || device.kind === 'video') && device.label; + }); + + callback(deviceExists); + }); + }; + + })(); + /** * @class FileAPI.Camera.Shot @@ -3315,7 +3487,9 @@ ctx.drawImage(video, 0, 0, 1, 1); res = ctx.getImageData(0, 0, 1, 1).data[4] != 255; } - catch( e ){} + catch( err ){ + api.log('[FileAPI.Camera] detectVideoSignal:', err); + } return res; } @@ -3371,6 +3545,7 @@ || !api.html5 || !api.support.html5 || (api.cors && !api.support.cors) || (api.media && !api.support.media) + || api.insecureChrome ) && (function (){ var @@ -3404,7 +3579,7 @@ , width: 5 , height: 5 , position: 'absolute' - , zIndex: 1e6+'' // set max zIndex + , zIndex: 2147483647+'' // set max zIndex }); child.parentNode.insertBefore(dummy, child); @@ -3515,7 +3690,7 @@ , left: 0 , width: target.offsetWidth , height: target.offsetHeight - , zIndex: 1e6+'' // set max zIndex + , zIndex: 2147483647+'' // set max zIndex , position: 'absolute' }); @@ -4130,7 +4305,7 @@ var _each = api.each, _cameraQueue = []; - if (api.support.flash && (api.media && (!api.support.media || !api.html5))) { + if (api.support.flash && (api.media && (!api.support.media || !api.html5 || api.insecureChrome))) { (function () { function _wrap(fn) { var id = fn.wid = api.uid(); @@ -4228,4 +4403,4 @@ }()); } }(window, window.jQuery, FileAPI)); -if( typeof define === "function" && define.amd ){ define("FileAPI", [], function (){ return FileAPI; }); } \ No newline at end of file +if( typeof define === "function" && define.amd ){ define("FileAPI", [], function (){ return FileAPI; }); } diff --git a/dist/FileAPI.min.js b/dist/FileAPI.min.js index e1c12b85..d42d7acb 100644 --- a/dist/FileAPI.min.js +++ b/dist/FileAPI.min.js @@ -1,3 +1,2 @@ -/*! FileAPI 2.0.10 - BSD | git://github.com/mailru/FileAPI.git */ -!function(a){"use strict";var b=a.HTMLCanvasElement&&a.HTMLCanvasElement.prototype,c=a.Blob&&function(){try{return Boolean(new Blob)}catch(a){return!1}}(),d=c&&a.Uint8Array&&function(){try{return 100===new Blob([new Uint8Array(100)]).size}catch(a){return!1}}(),e=a.BlobBuilder||a.WebKitBlobBuilder||a.MozBlobBuilder||a.MSBlobBuilder,f=(c||e)&&a.atob&&a.ArrayBuffer&&a.Uint8Array&&function(a){var b,f,g,h,i,j;for(b=a.split(",")[0].indexOf("base64")>=0?atob(a.split(",")[1]):decodeURIComponent(a.split(",")[1]),f=new ArrayBuffer(b.length),g=new Uint8Array(f),h=0;hd;d++)d in a&&b.call(c,a[d],d,a);else for(var f in a)a.hasOwnProperty(f)&&b.call(c,a[f],f,a)},S=function(a){for(var b=arguments,c=1,d=function(b,c){a[c]=b};c=c&&!d&&f.end()},isFail:function(){return d},fail:function(){!d&&a(d=!0)},end:function(){e||(e=!0,a())}};return f},each:R,afor:function(a,b){var c=0,d=a.length;Q(a)&&d--?!function e(){b(d!=c&&e,a[c],c++)}():b(!1)},extend:S,isFile:function(a){return"[object File]"===H.call(a)},isBlob:function(a){return this.isFile(a)||"[object Blob]"===H.call(a)},isCanvas:function(a){return a&&D.test(a.nodeName)},getFilesFilter:function(a){return a="string"==typeof a?a:a.getAttribute&&a.getAttribute("accept")||"",a?new RegExp("("+a.replace(/\./g,"\\.").replace(/,/g,"|")+")$","i"):/./},readAsDataURL:function(a,b){Y.isCanvas(a)?c(a,b,"load",Y.toDataURL(a)):e(a,b,"DataURL")},readAsBinaryString:function(a,b){d("BinaryString")?e(a,b,"BinaryString"):e(a,function(a){if("load"==a.type)try{a.result=Y.toBinaryString(a.result)}catch(c){a.type="error",a.message=c.toString()}b(a)},"DataURL")},readAsArrayBuffer:function(a,b){e(a,b,"ArrayBuffer")},readAsText:function(a,b,c){c||(c=b,b="utf-8"),e(a,c,"Text",b)},toDataURL:function(a,b){return"string"==typeof a?a:a.toDataURL?a.toDataURL(b||"image/png"):void 0},toBinaryString:function(b){return a.atob(Y.toDataURL(b).replace(G,""))},readAsImage:function(a,d,e){if(Y.isFile(a))if(r){var f=r.createObjectURL(a);f===b?c(a,d,"error"):Y.readAsImage(f,d,e)}else Y.readAsDataURL(a,function(b){"load"==b.type?Y.readAsImage(b.result,d,e):(e||"error"==b.type)&&c(a,d,b,null,{loaded:b.loaded,total:b.total})});else if(Y.isCanvas(a))c(a,d,"load",a);else if(C.test(a.nodeName))if(a.complete)c(a,d,"load",a);else{var g="error abort load";V(a,g,function i(b){"load"==b.type&&r&&r.revokeObjectURL(a.src),U(a,g,i),c(a,d,b,a)})}else if(a.iframe)c(a,d,{type:"error"});else{var h=Y.newImage(a.dataURL||a);Y.readAsImage(h,d,e)}},checkFileObj:function(a){var b={},c=Y.accept;return"object"==typeof a?b=a:b.name=(a+"").split(/\\|\//g).pop(),null==b.type&&(b.type=b.name.split(".").pop()),R(c,function(a,c){a=new RegExp(a.replace(/\s/g,"|"),"i"),(a.test(b.type)||Y.ext2mime[b.type])&&(b.type=Y.ext2mime[b.type]||c.split("/")[0]+"/"+b.type)}),b},getDropFiles:function(a,b){var c=[],d=k(a),e=Q(d.items)&&d.items[0]&&g(d.items[0]),i=Y.queue(function(){b(c)});R((e?d.items:d.files)||[],function(a){i.inc();try{e?h(a,function(a,b){a?Y.log("[err] getDropFiles:",a):c.push.apply(c,b),i.next()}):f(a,function(b){b&&c.push(a),i.next()})}catch(b){i.next(),Y.log("[err] getDropFiles: ",b)}}),i.check()},getFiles:function(a,b,c){var d=[];return c?(Y.filterFiles(Y.getFiles(a),b,c),null):(a.jquery&&(a.each(function(){d=d.concat(Y.getFiles(this))}),a=d,d=[]),"string"==typeof b&&(b=Y.getFilesFilter(b)),a.originalEvent?a=W(a.originalEvent):a.srcElement&&(a=W(a)),a.dataTransfer?a=a.dataTransfer:a.target&&(a=a.target),a.files?(d=a.files,y||(d[0].blob=a,d[0].iframe=!0)):!y&&j(a)?Y.trim(a.value)&&(d=[Y.checkFileObj(a.value)],d[0].blob=a,d[0].iframe=!0):Q(a)&&(d=a),Y.filter(d,function(a){return!b||b.test(a.name)}))},getTotalSize:function(a){for(var b=0,c=a&&a.length;c--;)b+=a[c].size;return b},getInfo:function(a,b){var c={},d=L.concat();Y.isFile(a)?!function e(){var f=d.shift();f?f.test(a.type)?f(a,function(a,d){a?b(a):(S(c,d),e())}):e():b(!1,c)}():b("not_support_info",c)},addInfoReader:function(a,b){b.test=function(b){return a.test(b)},L.push(b)},filter:function(a,b){for(var c,d=[],e=0,f=a.length;f>e;e++)e in a&&(c=a[e],b.call(c,c,e,a)&&d.push(c));return d},filterFiles:function(a,b,c){if(a.length){var d,e=a.concat(),f=[],g=[];!function h(){e.length?(d=e.shift(),Y.getInfo(d,function(a,c){(b(d,a?!1:c)?f:g).push(d),h()})):c(f,g)}()}else c([],a)},upload:function(a){a=S({jsonp:"callback",prepare:Y.F,beforeupload:Y.F,upload:Y.F,fileupload:Y.F,fileprogress:Y.F,filecomplete:Y.F,progress:Y.F,complete:Y.F,pause:Y.F,imageOriginal:!0,chunkSize:Y.chunkSize,chunkUploadRetry:Y.chunkUploadRetry,uploadRetry:Y.uploadRetry},a),a.imageAutoOrientation&&!a.imageTransform&&(a.imageTransform={rotate:"auto"});var b,c=new Y.XHR(a),d=this._getFilesDataArray(a.files),e=this,f=0,g=0,h=!1;return R(d,function(a){f+=a.size}),c.files=[],R(d,function(a){c.files.push(a.file)}),c.total=f,c.loaded=0,c.filesLeft=d.length,a.beforeupload(c,a),b=function(){var j=d.shift(),k=j&&j.file,l=!1,m=i(a);if(c.filesLeft=d.length,k&&k.name===Y.expando&&(k=null,Y.log("[warn] FileAPI.upload() — called without files")),("abort"!=c.statusText||c.current)&&j){if(h=!1,c.currentFile=k,k&&a.prepare(k,m)===!1)return void b.call(e);m.file=k,e._getFormData(m,j,function(h){g||a.upload(c,a);var i=new Y.XHR(S({},m,{upload:k?function(){a.fileupload(k,i,m)}:n,progress:k?function(b){l||(l=b.loaded===b.total,a.fileprogress({type:"progress",total:j.total=b.total,loaded:j.loaded=b.loaded},k,i,m),a.progress({type:"progress",total:f,loaded:c.loaded=g+j.size*(b.loaded/b.total)||0},k,i,m))}:n,complete:function(d){R(N,function(a){c[a]=i[a]}),k&&(j.total=j.total||j.size,j.loaded=j.total,d||(this.progress(j),l=!0,g+=j.size,c.loaded=g),a.filecomplete(d,i,k,m)),setTimeout(function(){b.call(e)},0)}}));c.abort=function(a){a||(d.length=0),this.current=a,i.abort()},i.send(h)})}else{var o=200==c.status||201==c.status||204==c.status;a.complete(o?!1:c.statusText||"error",c,a),h=!0}},setTimeout(b,0),c.append=function(a,g){a=Y._getFilesDataArray([].concat(a)),R(a,function(a){f+=a.size,c.files.push(a.file),g?d.unshift(a):d.push(a)}),c.statusText="",h&&b.call(e)},c.remove=function(a){for(var b,c=d.length;c--;)d[c].file==a&&(b=d.splice(c,1),f-=b.size);return b},c},_getFilesDataArray:function(a){var b=[],c={};if(j(a)){var d=Y.getFiles(a);c[a.name||"file"]=null!==a.getAttribute("multiple")?d:d[0]}else Q(a)&&j(a[0])?R(a,function(a){c[a.name||"file"]=Y.getFiles(a)}):c=a;return R(c,function e(a,c){Q(a)?R(a,function(a){e(a,c)}):a&&(a.name||a.image)&&b.push({name:c,file:a,size:a.size,total:a.size,loaded:0})}),b.length||b.push({file:{name:Y.expando}}),b},_getFormData:function(a,b,c){var d=b.file,e=b.name,f=d.name,g=d.type,h=Y.support.transform&&a.imageTransform,i=new Y.Form,j=Y.queue(function(){c(i)}),k=h&&l(h),m=Y.postNameConcat;R(a.data,function n(a,b){"object"==typeof a?R(a,function(a,c){n(a,m(b,c))}):i.append(b,a)}),function o(b){b.image?(j.inc(),b.toData(function(a,b){f=f||(new Date).getTime()+".png",o(b),j.next()})):Y.Image&&h&&(/^image/.test(b.type)||E.test(b.nodeName))?(j.inc(),k&&(h=[h]),Y.Image.transform(b,h,a.imageAutoOrientation,function(c,d){if(k&&!c)B||Y.flashEngine||(i.multipart=!0),i.append(e,d[0],f,h[0].type||g);else{var l=0;c||R(d,function(a,b){B||Y.flashEngine||(i.multipart=!0),h[b].postName||(l=1),i.append(h[b].postName||m(e,b),a,f,h[b].type||g)}),(c||a.imageOriginal)&&i.append(m(e,l?"original":null),b,f,g)}j.next()})):f!==Y.expando&&i.append(e,b,f)}(d),j.check()},reset:function(a,b){var c,d;return x?(d=x(a).clone(!0).insertBefore(a).val("")[0],b||x(a).remove()):(c=a.parentNode,d=c.insertBefore(a.cloneNode(!0),a),d.value="",b||c.removeChild(a),R(K[Y.uid(a)],function(b,c){R(b,function(b){U(a,c,b),T(d,c,b)})})),d},load:function(a,b){var c=Y.getXHR();return c?(c.open("GET",a,!0),c.overrideMimeType&&c.overrideMimeType("text/plain; charset=x-user-defined"),T(c,"progress",function(a){a.lengthComputable&&b({type:a.type,loaded:a.loaded,total:a.total},c)}),c.onreadystatechange=function(){if(4==c.readyState)if(c.onreadystatechange=null,200==c.status){a=a.split("/");var d={name:a[a.length-1],size:c.getResponseHeader("Content-Length"),type:c.getResponseHeader("Content-Type")};d.dataURL="data:"+d.type+";base64,"+Y.encode64(c.responseBody||c.responseText),b({type:"load",result:d},c)}else b({type:"error"},c)},c.send(null)):b({type:"error"}),c},encode64:function(a){var b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",c="",d=0;for("string"!=typeof a&&(a=String(a));d>2,k=(3&g)<<4|h>>4;isNaN(h)?e=f=64:(e=(15&h)<<2|i>>6,f=isNaN(i)?64:63&i),c+=b.charAt(j)+b.charAt(k)+b.charAt(e)+b.charAt(f)}return c}};Y.addInfoReader(/^image/,function(a,b){if(!a.__dimensions){var c=a.__dimensions=Y.defer();Y.readAsImage(a,function(a){var b=a.target;c.resolve("load"==a.type?!1:"error",{width:b.width,height:b.height}),b.src=Y.EMPTY_PNG,b=null})}a.__dimensions.then(b)}),Y.event.dnd=function(a,b,c){var d,e;c||(c=b,b=Y.F),u?(T(a,"dragenter dragleave dragover",b.ff=b.ff||function(a){for(var c=k(a).types,f=c&&c.length,g=!1;f--;)if(~c[f].indexOf("File")){a[P](),e!==a.type&&(e=a.type,"dragleave"!=e&&b.call(a[O],!0,a),g=!0);break}g&&(clearTimeout(d),d=setTimeout(function(){b.call(a[O],"dragleave"!=e,a)},50))}),T(a,"drop",c.ff=c.ff||function(a){a[P](),e=0,b.call(a[O],!1,a),Y.getDropFiles(a,function(b){c.call(a[O],b,a)})})):Y.log("Drag'n'Drop -- not supported")},Y.event.dnd.off=function(a,b,c){U(a,"dragenter dragleave dragover",b.ff),U(a,"drop",c.ff)},x&&!x.fn.dnd&&(x.fn.dnd=function(a,b){return this.each(function(){Y.event.dnd(this,a,b)})},x.fn.offdnd=function(a,b){return this.each(function(){Y.event.dnd.off(this,a,b)})}),a.FileAPI=S(Y,a.FileAPI),Y.log("FileAPI: "+Y.version),Y.log("protocol: "+a.location.protocol),Y.log("doctype: ["+p.name+"] "+p.publicId+" "+p.systemId),R(o.getElementsByTagName("meta"),function(a){/x-ua-compatible/i.test(a.getAttribute("http-equiv"))&&Y.log("meta.http-equiv: "+a.getAttribute("content"))}),Y.flashUrl||(Y.flashUrl=Y.staticPath+"FileAPI.flash.swf"),Y.flashImageUrl||(Y.flashImageUrl=Y.staticPath+"FileAPI.flash.image.swf"),Y.flashWebcamUrl||(Y.flashWebcamUrl=Y.staticPath+"FileAPI.flash.camera.swf")}(window,void 0),function(a,b,c){"use strict";function d(b){if(b instanceof d){var c=new d(b.file);return a.extend(c.matrix,b.matrix),c}return this instanceof d?(this.file=b,this.size=b.size||100,void(this.matrix={sx:0,sy:0,sw:0,sh:0,dx:0,dy:0,dw:0,dh:0,resize:0,deg:0,quality:1,filter:0})):new d(b)}var e=Math.min,f=Math.round,g=function(){return b.createElement("canvas")},h=!1,i={8:270,3:180,6:90,7:270,4:180,5:90};try{h=g().toDataURL("image/png").indexOf("data:image/png")>-1}catch(j){}d.prototype={image:!0,constructor:d,set:function(b){return a.extend(this.matrix,b),this},crop:function(a,b,d,e){return d===c&&(d=a,e=b,a=b=0),this.set({sx:a,sy:b,sw:d,sh:e||d})},resize:function(a,b,c){return/min|max|height|width/.test(b)&&(c=b,b=a),this.set({dw:a,dh:b||a,resize:c})},preview:function(a,b){return this.resize(a,b||a,"preview")},rotate:function(a){return this.set({deg:a})},filter:function(a){return this.set({filter:a})},overlay:function(a){return this.set({overlay:a})},clone:function(){return new d(this)},_load:function(b,c){var d=this;/img|video/i.test(b.nodeName)?c.call(d,null,b):a.readAsImage(b,function(a){c.call(d,"load"!=a.type,a.result)})},_apply:function(b,c){var f,h=g(),i=this.getMatrix(b),j=h.getContext("2d"),k=b.videoWidth||b.width,l=b.videoHeight||b.height,m=i.deg,n=i.dw,o=i.dh,p=k,q=l,r=i.filter,s=b,t=i.overlay,u=a.queue(function(){b.src=a.EMPTY_PNG,c(!1,h)}),v=a.renderImageToCanvas;for(m-=360*Math.floor(m/360),b._type=this.file.type;i.multipass&&e(p/n,q/o)>2;)p=p/2+.5|0,q=q/2+.5|0,f=g(),f.width=p,f.height=q,s!==b?(v(f,s,0,0,s.width,s.height,0,0,p,q),s=f):(s=f,v(s,b,i.sx,i.sy,i.sw,i.sh,0,0,p,q),i.sx=i.sy=i.sw=i.sh=0);h.width=m%180?o:n,h.height=m%180?n:o,h.type=i.type,h.quality=i.quality,j.rotate(m*Math.PI/180),v(j.canvas,s,i.sx,i.sy,i.sw||s.width,i.sh||s.height,180==m||270==m?-n:0,90==m||180==m?-o:0,n,o),n=h.width,o=h.height,t&&a.each([].concat(t),function(b){u.inc();var c=new window.Image,d=function(){var e=0|b.x,f=0|b.y,g=b.w||c.width,h=b.h||c.height,i=b.rel;e=1==i||4==i||7==i?(n-g+e)/2:2==i||5==i||8==i?n-(g+e):e,f=3==i||4==i||5==i?(o-h+f)/2:i>=6?o-(h+f):f,a.event.off(c,"error load abort",d);try{j.globalAlpha=b.opacity||1,j.drawImage(c,e,f,g,h)}catch(k){}u.next()};a.event.on(c,"error load abort",d),c.src=b.src,c.complete&&d()}),r&&(u.inc(),d.applyFilter(h,r,u.next)),u.check()},getMatrix:function(b){var c=a.extend({},this.matrix),d=c.sw=c.sw||b.videoWidth||b.naturalWidth||b.width,g=c.sh=c.sh||b.videoHeight||b.naturalHeight||b.height,h=c.dw=c.dw||d,i=c.dh=c.dh||g,j=d/g,k=h/i,l=c.resize;if("preview"==l){if(h!=d||i!=g){var m,n;k>=j?(m=d,n=m/k):(n=g,m=n*k),(m!=d||n!=g)&&(c.sx=~~((d-m)/2),c.sy=~~((g-n)/2),d=m,g=n)}}else"height"==l?h=i*j:"width"==l?i=h/j:l&&(d>h||g>i?"min"==l?(h=f(k>j?e(d,h):i*j),i=f(k>j?h/j:e(g,i))):(h=f(j>=k?e(d,h):i*j),i=f(j>=k?h/j:e(g,i))):(h=d,i=g));return c.sw=d,c.sh=g,c.dw=h,c.dh=i,c.multipass=a.multiPassResize,c},_trans:function(b){this._load(this.file,function(c,d){if(c)b(c);else try{this._apply(d,b)}catch(c){a.log("[err] FileAPI.Image.fn._apply:",c),b(c)}})},get:function(b){if(a.support.transform){var c=this,d=c.matrix;"auto"==d.deg?a.getInfo(c.file,function(a,e){d.deg=i[e&&e.exif&&e.exif.Orientation]||0,c._trans(b)}):c._trans(b)}else b("not_support_transform");return this},toData:function(a){return this.get(a)}},d.exifOrientation=i,d.transform=function(b,e,f,g){function h(h,i){var j={},k=a.queue(function(a){g(a,j)});h?k.fail():a.each(e,function(a,e){if(!k.isFail()){var g=new d(i.nodeType?i:b),h="function"==typeof a;if(h?a(i,g):a.width?g[a.preview?"preview":"resize"](a.width,a.height,a.strategy):a.maxWidth&&(i.width>a.maxWidth||i.height>a.maxHeight)&&g.resize(a.maxWidth,a.maxHeight,"max"),a.crop){var l=a.crop;g.crop(0|l.x,0|l.y,l.w||l.width,l.h||l.height)}a.rotate===c&&f&&(a.rotate="auto"),g.set({type:g.matrix.type||a.type||b.type||"image/png"}),h||g.set({deg:a.rotate,overlay:a.overlay,filter:a.filter,quality:a.quality||1}),k.inc(),g.toData(function(a,b){a?k.fail():(j[e]=b,k.next())})}})}b.width?h(!1,b):a.getInfo(b,h)},a.each(["TOP","CENTER","BOTTOM"],function(b,c){a.each(["LEFT","CENTER","RIGHT"],function(a,e){d[b+"_"+a]=3*c+e,d[a+"_"+b]=3*c+e})}),d.toCanvas=function(a){var c=b.createElement("canvas");return c.width=a.videoWidth||a.width,c.height=a.videoHeight||a.height,c.getContext("2d").drawImage(a,0,0),c},d.fromDataURL=function(b,c,d){var e=a.newImage(b);a.extend(e,c),d(e)},d.applyFilter=function(b,c,e){"function"==typeof c?c(b,e):window.Caman&&window.Caman("IMG"==b.tagName?d.toCanvas(b):b,function(){"string"==typeof c?this[c]():a.each(c,function(a,b){this[b](a)},this),this.render(e)})},a.renderImageToCanvas=function(b,c,d,e,f,g,h,i,j,k){try{return b.getContext("2d").drawImage(c,d,e,f,g,h,i,j,k)}catch(l){throw a.log("renderImageToCanvas failed"),l}},a.support.canvas=a.support.transform=h,a.Image=d}(FileAPI,document),function(a){"use strict";a(FileAPI)}(function(a){"use strict";if(window.navigator&&window.navigator.platform&&/iP(hone|od|ad)/.test(window.navigator.platform)){var b=a.renderImageToCanvas;a.detectSubsampling=function(a){var b,c;return a.width*a.height>1048576?(b=document.createElement("canvas"),b.width=b.height=1,c=b.getContext("2d"),c.drawImage(a,-a.width+1,0),0===c.getImageData(0,0,1,1).data[3]):!1},a.detectVerticalSquash=function(a,b){var c,d,e,f,g,h=a.naturalHeight||a.height,i=document.createElement("canvas"),j=i.getContext("2d");for(b&&(h/=2),i.width=1,i.height=h,j.drawImage(a,0,0),c=j.getImageData(0,0,1,h).data,d=0,e=h,f=h;f>d;)g=c[4*(f-1)+3],0===g?e=f:d=f,f=e+d>>1;return f/h||1},a.renderImageToCanvas=function(c,d,e,f,g,h,i,j,k,l){if("image/jpeg"===d._type){var m,n,o,p,q=c.getContext("2d"),r=document.createElement("canvas"),s=1024,t=r.getContext("2d");if(r.width=s,r.height=s,q.save(),m=a.detectSubsampling(d),m&&(e/=2,f/=2,g/=2,h/=2),n=a.detectVerticalSquash(d,m),m||1!==n){for(f*=n,k=Math.ceil(s*k/g),l=Math.ceil(s*l/h/n),j=0,p=0;h>p;){for(i=0,o=0;g>o;)t.clearRect(0,0,s,s),t.drawImage(d,e,f,g,h,-o,-p,g,h),q.drawImage(r,0,0,s,s,i,j,k,l),o+=s,i+=k;p+=s,j+=l}return q.restore(),c}}return b(c,d,e,f,g,h,i,j,k,l)}}}),function(a,b){"use strict";function c(b,c,d){var e=b.blob,f=b.file;if(f){if(!e.toDataURL)return void a.readAsBinaryString(e,function(a){"load"==a.type&&c(b,a.result)});var g={"image/jpeg":".jpe?g","image/png":".png"},h=g[b.type]?b.type:"image/png",i=g[h]||".png",j=e.quality||1;f.match(new RegExp(i+"$","i"))||(f+=i.replace("?","")),b.file=f,b.type=h,!d&&e.toBlob?e.toBlob(function(a){c(b,a)},h,j):c(b,a.toBinaryString(e.toDataURL(h,j)))}else c(b,e)}var d=b.document,e=b.FormData,f=function(){this.items=[]},g=b.encodeURIComponent;f.prototype={append:function(a,b,c,d){this.items.push({name:a,blob:b&&b.blob||(void 0==b?"":b),file:b&&(c||b.name),type:b&&(d||b.type)})},each:function(a){for(var b=0,c=this.items.length;c>b;b++)a.call(this,this.items[b])},toData:function(b,c){c._chunked=a.support.chunked&&c.chunkSize>0&&1==a.filter(this.items,function(a){return a.file}).length,a.support.html5?a.formData&&!this.multipart&&e?c._chunked?(a.log("FileAPI.Form.toPlainData"),this.toPlainData(b)):(a.log("FileAPI.Form.toFormData"),this.toFormData(b)):(a.log("FileAPI.Form.toMultipartData"),this.toMultipartData(b)):(a.log("FileAPI.Form.toHtmlData"),this.toHtmlData(b))},_to:function(b,c,d,e){var f=a.queue(function(){c(b)});this.each(function(a){d(a,b,f,e)}),f.check()},toHtmlData:function(b){this._to(d.createDocumentFragment(),b,function(b,c){var e,f=b.blob;b.file?(a.reset(f,!0),f.name=b.name,f.disabled=!1,c.appendChild(f)):(e=d.createElement("input"),e.name=b.name,e.type="hidden",e.value=f,c.appendChild(e))})},toPlainData:function(a){this._to({},a,function(a,b,d){a.file&&(b.type=a.file),a.blob.toBlob?(d.inc(),c(a,function(a,c){b.name=a.name,b.file=c,b.size=c.length,b.type=a.type,d.next()})):a.file?(b.name=a.blob.name,b.file=a.blob,b.size=a.blob.size,b.type=a.type):(b.params||(b.params=[]),b.params.push(g(a.name)+"="+g(a.blob))),b.start=-1,b.end=b.file&&b.file.FileAPIReadPosition||-1,b.retry=0})},toFormData:function(a){this._to(new e,a,function(a,b,d){a.blob&&a.blob.toBlob?(d.inc(),c(a,function(a,c){b.append(a.name,c,a.file),d.next()})):a.file?b.append(a.name,a.blob,a.file):b.append(a.name,a.blob),a.file&&b.append("_"+a.name,a.file)})},toMultipartData:function(b){this._to([],b,function(a,b,d,e){d.inc(),c(a,function(a,c){b.push("--_"+e+('\r\nContent-Disposition: form-data; name="'+a.name+'"'+(a.file?'; filename="'+g(a.file)+'"':"")+(a.file?"\r\nContent-Type: "+(a.type||"application/octet-stream"):"")+"\r\n\r\n"+(a.file?c:g(c))+"\r\n")),d.next()},!0)},a.expando)}},a.Form=f}(FileAPI,window),function(a,b){"use strict";var c=function(){},d=a.document,e=function(a){this.uid=b.uid(),this.xhr={abort:c,getResponseHeader:c,getAllResponseHeaders:c},this.options=a},f={"":1,XML:1,Text:1,Body:1};e.prototype={status:0,statusText:"",constructor:e,getResponseHeader:function(a){return this.xhr.getResponseHeader(a)},getAllResponseHeaders:function(){return this.xhr.getAllResponseHeaders()||{}},end:function(d,e){var f=this,g=f.options;f.end=f.abort=c,f.status=d,e&&(f.statusText=e),b.log("xhr.end:",d,e),g.complete(200==d||201==d?!1:f.statusText||"unknown",f),f.xhr&&f.xhr.node&&setTimeout(function(){var b=f.xhr.node;try{b.parentNode.removeChild(b)}catch(c){}try{delete a[f.uid]}catch(c){}a[f.uid]=f.xhr.node=null},9)},abort:function(){this.end(0,"abort"),this.xhr&&(this.xhr.aborted=!0,this.xhr.abort())},send:function(a){var b=this,c=this.options;a.toData(function(a){c.upload(c,b),b._send.call(b,c,a)},c)},_send:function(c,e){var g,h=this,i=h.uid,j=h.uid+"Load",k=c.url;if(b.log("XHR._send:",e),c.cache||(k+=(~k.indexOf("?")?"&":"?")+b.uid()),e.nodeName){var l=c.jsonp;k=k.replace(/([a-z]+)=(\?)/i,"$1="+i),c.upload(c,h);var m=function(a){if(~k.indexOf(a.origin))try{var c=b.parseJSON(a.data);c.id==i&&n(c.status,c.statusText,c.response)}catch(d){n(0,d.message)}},n=a[i]=function(c,d,e){h.readyState=4,h.responseText=e,h.end(c,d),b.event.off(a,"message",m),a[i]=g=p=a[j]=null};h.xhr.abort=function(){try{p.stop?p.stop():p.contentWindow.stop?p.contentWindow.stop():p.contentWindow.document.execCommand("Stop")}catch(a){}n(0,"abort")},b.event.on(a,"message",m),a[j]=function(){try{var a=p.contentWindow,c=a.document,d=a.result||b.parseJSON(c.body.innerHTML);n(d.status,d.statusText,d.response)}catch(e){b.log("[transport.onload]",e)}},g=d.createElement("div"),g.innerHTML='
'+(l&&c.url.indexOf("=?")<0?'':"")+"
";var o=g.getElementsByTagName("form")[0],p=g.getElementsByTagName("iframe")[0];o.appendChild(e),b.log(o.parentNode.innerHTML),d.body.appendChild(g),h.xhr.node=g,h.readyState=2,o.submit(),o=null}else{if(k=k.replace(/([a-z]+)=(\?)&?/i,""),this.xhr&&this.xhr.aborted)return void b.log("Error: already aborted");if(g=h.xhr=b.getXHR(),e.params&&(k+=(k.indexOf("?")<0?"?":"&")+e.params.join("&")),g.open("POST",k,!0),b.withCredentials&&(g.withCredentials="true"),c.headers&&c.headers["X-Requested-With"]||g.setRequestHeader("X-Requested-With","XMLHttpRequest"),b.each(c.headers,function(a,b){g.setRequestHeader(b,a)}),c._chunked){g.upload&&g.upload.addEventListener("progress",b.throttle(function(a){e.retry||c.progress({type:a.type,total:e.size,loaded:e.start+a.loaded,totalSize:e.size},h,c)},100),!1),g.onreadystatechange=function(){var a=parseInt(g.getResponseHeader("X-Last-Known-Byte"),10);if(h.status=g.status,h.statusText=g.statusText,h.readyState=g.readyState,4==g.readyState){for(var d in f)h["response"+d]=g["response"+d];if(g.onreadystatechange=null,!g.status||g.status-201>0)if(b.log("Error: "+g.status),(!g.status&&!g.aborted||500==g.status||416==g.status)&&++e.retry<=c.chunkUploadRetry){var i=g.status?0:b.chunkNetworkDownRetryTimeout;c.pause(e.file,c),b.log("X-Last-Known-Byte: "+a),a?e.end=a:(e.end=e.start-1,416==g.status&&(e.end=e.end-c.chunkSize)),setTimeout(function(){h._send(c,e)},i)}else h.end(g.status);else e.retry=0,e.end==e.size-1?h.end(g.status):(b.log("X-Last-Known-Byte: "+a),a&&(e.end=a),e.file.FileAPIReadPosition=e.end,setTimeout(function(){h._send(c,e)},0));g=null}},e.start=e.end+1,e.end=Math.max(Math.min(e.start+c.chunkSize,e.size)-1,e.start);var q=e.file,r=(q.slice||q.mozSlice||q.webkitSlice).call(q,e.start,e.end+1);e.size&&!r.size?setTimeout(function(){h.end(-1)}):(g.setRequestHeader("Content-Range","bytes "+e.start+"-"+e.end+"/"+e.size),g.setRequestHeader("Content-Disposition","attachment; filename="+encodeURIComponent(e.name)),g.setRequestHeader("Content-Type",e.type||"application/octet-stream"),g.send(r)),q=r=null}else if(g.upload&&g.upload.addEventListener("progress",b.throttle(function(a){c.progress(a,h,c)},100),!1),g.onreadystatechange=function(){if(h.status=g.status,h.statusText=g.statusText,h.readyState=g.readyState,4==g.readyState){for(var a in f)h["response"+a]=g["response"+a];if(g.onreadystatechange=null,!g.status||g.status>201)if(b.log("Error: "+g.status),(!g.status&&!g.aborted||500==g.status)&&(c.retry||0)=0?a+"px":a}function d(a){var b,c=f.createElement("canvas"),d=!1;try{b=c.getContext("2d"),b.drawImage(a,0,0,1,1),d=255!=b.getImageData(0,0,1,1).data[4]}catch(e){}return d}var e=a.URL||a.webkitURL,f=a.document,g=a.navigator,h=g.getUserMedia||g.webkitGetUserMedia||g.mozGetUserMedia||g.msGetUserMedia,i=!!h;b.support.media=i;var j=function(a){this.video=a};j.prototype={isActive:function(){return!!this._active},start:function(a){var b,c,f=this,i=f.video,j=function(d){f._active=!d,clearTimeout(c),clearTimeout(b),a&&a(d,f)};h.call(g,{video:!0},function(a){f.stream=a,i.src=e.createObjectURL(a),b=setInterval(function(){d(i)&&j(null)},1e3),c=setTimeout(function(){j("timeout")},5e3),i.play()},j)},stop:function(){try{this._active=!1,this.video.pause(),this.stream.stop()}catch(a){}},shot:function(){return new k(this.video)}},j.get=function(a){return new j(a.firstChild)},j.publish=function(d,e,g){"function"==typeof e&&(g=e,e={}),e=b.extend({},{width:"100%",height:"100%",start:!0},e),d.jquery&&(d=d[0]);var h=function(a){if(a)g(a);else{var b=j.get(d);e.start?b.start(g):g(null,b)}};if(d.style.width=c(e.width),d.style.height=c(e.height),b.html5&&i){var k=f.createElement("video");k.style.width=c(e.width),k.style.height=c(e.height),a.jQuery?jQuery(d).empty():d.innerHTML="",d.appendChild(k),h()}else j.fallback(d,e,h)},j.fallback=function(a,b,c){c("not_support_camera")};var k=function(a){var c=a.nodeName?b.Image.toCanvas(a):a,d=b.Image(c);return d.type="image/png",d.width=c.width,d.height=c.height,d.size=c.width*c.height*4,d};j.Shot=k,b.Camera=j}(window,FileAPI),function(a,b,c){"use strict";var d=a.document,e=a.location,f=a.navigator,g=c.each;c.support.flash=function(){var b=f.mimeTypes,d=!1;if(f.plugins&&"object"==typeof f.plugins["Shockwave Flash"])d=f.plugins["Shockwave Flash"].description&&!(b&&b["application/x-shockwave-flash"]&&!b["application/x-shockwave-flash"].enabledPlugin); -else try{d=!(!a.ActiveXObject||!new ActiveXObject("ShockwaveFlash.ShockwaveFlash"))}catch(g){c.log("Flash -- does not supported.")}return d&&/^file:/i.test(e)&&c.log("[warn] Flash does not work on `file:` protocol."),d}(),c.support.flash&&(0||!c.html5||!c.support.html5||c.cors&&!c.support.cors||c.media&&!c.support.media)&&function(){function h(a){return('').replace(/#(\w+)#/gi,function(b,c){return a[c]})}function i(a,b){if(a&&a.style){var c,d;for(c in b){d=b[c],"number"==typeof d&&(d+="px");try{a.style[c]=d}catch(e){}}}}function j(a,b){g(b,function(b,c){var d=a[c];a[c]=function(){return this.parent=d,b.apply(this,arguments)}})}function k(a){return a&&!a.flashId}function l(a){var b=a.wid=c.uid();return v._fn[b]=a,"FileAPI.Flash._fn."+b}function m(a){try{v._fn[a.wid]=null,delete v._fn[a.wid]}catch(b){}}function n(a,b){if(!u.test(a)){if(/^\.\//.test(a)||"/"!=a.charAt(0)){var c=e.pathname;c=c.substr(0,c.lastIndexOf("/")),a=(c+"/"+a).replace("/./","/")}"//"!=a.substr(0,2)&&(a="//"+e.host+a),u.test(a)||(a=e.protocol+a)}return b&&(a+=(/\?/.test(a)?"&":"?")+b),a}function o(a,b,e){function f(){try{var a=v.get(j);a.setImage(b)}catch(d){c.log('[err] FlashAPI.Preview.setImage -- can not set "base64":',d)}}var g,j=c.uid(),k=d.createElement("div"),o=10;for(g in a)k.setAttribute(g,a[g]),k[g]=a[g];i(k,a),a.width="100%",a.height="100%",k.innerHTML=h(c.extend({id:j,src:n(c.flashImageUrl,"r="+c.uid()),wmode:"opaque",flashvars:"scale="+a.scale+"&callback="+l(function p(){return m(p),--o>0&&f(),!0})},a)),e(!1,k),k=null}function p(a){return{id:a.id,name:a.name,matrix:a.matrix,flashId:a.flashId}}function q(b){var c=b.getBoundingClientRect(),e=d.body,f=(b&&b.ownerDocument).documentElement;return{top:c.top+(a.pageYOffset||f.scrollTop)-(f.clientTop||e.clientTop||0),left:c.left+(a.pageXOffset||f.scrollLeft)-(f.clientLeft||e.clientLeft||0),width:c.right-c.left,height:c.bottom-c.top}}var r=c.uid(),s=0,t={},u=/^https?:/i,v={_fn:{},init:function(){var a=d.body&&d.body.firstChild;if(a)do if(1==a.nodeType){c.log("FlashAPI.state: awaiting");var b=d.createElement("div");return b.id="_"+r,i(b,{top:1,right:1,width:5,height:5,position:"absolute",zIndex:1e6+""}),a.parentNode.insertBefore(b,a),void v.publish(b,r)}while(a=a.nextSibling);10>s&&setTimeout(v.init,50*++s)},publish:function(a,b,d){d=d||{},a.innerHTML=h({id:b,src:n(c.flashUrl,"r="+c.version),wmode:d.camera?"":"transparent",flashvars:"callback="+(d.onEvent||"FileAPI.Flash.onEvent")+"&flashId="+b+"&storeKey="+f.userAgent.match(/\d/gi).join("")+"_"+c.version+(v.isReady||(c.pingUrl?"&ping="+c.pingUrl:""))+"&timeout="+c.flashAbortTimeout+(d.camera?"&useCamera="+n(c.flashWebcamUrl):"")+"&debug="+(c.debug?"1":"")},d)},ready:function(){c.log("FlashAPI.state: ready"),v.ready=c.F,v.isReady=!0,v.patch(),v.patchCamera&&v.patchCamera(),c.event.on(d,"mouseover",v.mouseover),c.event.on(d,"click",function(a){v.mouseover(a)&&(a.preventDefault?a.preventDefault():a.returnValue=!0)})},getEl:function(){return d.getElementById("_"+r)},getWrapper:function(a){do if(/js-fileapi-wrapper/.test(a.className))return a;while((a=a.parentNode)&&a!==d.body)},mouseover:function(a){var b=c.event.fix(a).target;if(/input/i.test(b.nodeName)&&"file"==b.type&&!b.disabled){var e=b.getAttribute(r),f=v.getWrapper(b);if(c.multiFlash){if("i"==e||"r"==e)return!1;if("p"!=e){b.setAttribute(r,"i");var g=d.createElement("div");if(!f)return void c.log("[err] FlashAPI.mouseover: js-fileapi-wrapper not found");i(g,{top:0,left:0,width:b.offsetWidth,height:b.offsetHeight,zIndex:1e6+"",position:"absolute"}),f.appendChild(g),v.publish(g,c.uid()),b.setAttribute(r,"p")}return!0}if(f){var h=q(f);i(v.getEl(),h),v.curInp=b}}else/object|embed/i.test(b.nodeName)||i(v.getEl(),{top:1,left:1,width:5,height:5})},onEvent:function(a){var b=a.type;if("ready"==b){try{v.getInput(a.flashId).setAttribute(r,"r")}catch(d){}return v.ready(),setTimeout(function(){v.mouseenter(a)},50),!0}"ping"===b?c.log("(flash -> js).ping:",[a.status,a.savedStatus],a.error):"log"===b?c.log("(flash -> js).log:",a.target):b in v&&setTimeout(function(){c.log("FlashAPI.event."+a.type+":",a),v[b](a)},1)},mouseenter:function(a){var b=v.getInput(a.flashId);if(b){v.cmd(a,"multiple",null!=b.getAttribute("multiple"));var d=[],e={};g((b.getAttribute("accept")||"").split(/,\s*/),function(a){c.accept[a]&&g(c.accept[a].split(" "),function(a){e[a]=1})}),g(e,function(a,b){d.push(b)}),v.cmd(a,"accept",d.length?d.join(",")+","+d.join(",").toUpperCase():"*")}},get:function(b){return d[b]||a[b]||d.embeds[b]},getInput:function(a){if(!c.multiFlash)return v.curInp;try{var b=v.getWrapper(v.get(a));if(b)return b.getElementsByTagName("input")[0]}catch(d){c.log('[err] Can not find "input" by flashId:',a,d)}},select:function(a){var e,f=v.getInput(a.flashId),h=c.uid(f),i=a.target.files;g(i,function(a){c.checkFileObj(a)}),t[h]=i,d.createEvent?(e=d.createEvent("Event"),e.files=i,e.initEvent("change",!0,!0),f.dispatchEvent(e)):b?b(f).trigger({type:"change",files:i}):(e=d.createEventObject(),e.files=i,f.fireEvent("onchange",e))},cmd:function(a,b,d,e){try{return c.log("(js -> flash)."+b+":",d),v.get(a.flashId||a).cmd(b,d)}catch(f){c.log("(js -> flash).onError:",f.toString()),e||setTimeout(function(){v.cmd(a,b,d,!0)},50)}},patch:function(){c.flashEngine=!0,j(c,{getFiles:function(a,b,d){if(d)return c.filterFiles(c.getFiles(a),b,d),null;var e=c.isArray(a)?a:t[c.uid(a.target||a.srcElement||a)];return e?(b&&(b=c.getFilesFilter(b),e=c.filter(e,function(a){return b.test(a.name)})),e):this.parent.apply(this,arguments)},getInfo:function(a,b){if(k(a))this.parent.apply(this,arguments);else if(a.isShot)b(null,a.info={width:a.width,height:a.height});else{if(!a.__info){var d=a.__info=c.defer();v.cmd(a,"getFileInfo",{id:a.id,callback:l(function e(b,c){m(e),d.resolve(b,a.info=c)})})}a.__info.then(b)}}}),c.support.transform=!0,c.Image&&j(c.Image.prototype,{get:function(a,b){return this.set({scaleMode:b||"noScale"}),this.parent(a)},_load:function(a,b){if(c.log("FlashAPI.Image._load:",a),k(a))this.parent.apply(this,arguments);else{var d=this;c.getInfo(a,function(c){b.call(d,c,a)})}},_apply:function(a,b){if(c.log("FlashAPI.Image._apply:",a),k(a))this.parent.apply(this,arguments);else{var d=this.getMatrix(a.info),e=b;v.cmd(a,"imageTransform",{id:a.id,matrix:d,callback:l(function f(g,h){c.log("FlashAPI.Image._apply.callback:",g),m(f),g?e(g):c.support.html5||c.support.dataURI&&!(h.length>3e4)?(d.filter&&(e=function(a,e){a?b(a):c.Image.applyFilter(e,d.filter,function(){b(a,this.canvas)})}),c.newImage("data:"+a.type+";base64,"+h,e)):o({width:d.deg%180?d.dh:d.dw,height:d.deg%180?d.dw:d.dh,scale:d.scaleMode},h,e)})})}},toData:function(a){var b=this.file,d=b.info,e=this.getMatrix(d);c.log("FlashAPI.Image.toData"),k(b)?this.parent.apply(this,arguments):("auto"==e.deg&&(e.deg=c.Image.exifOrientation[d&&d.exif&&d.exif.Orientation]||0),a.call(this,!b.info,{id:b.id,flashId:b.flashId,name:b.name,type:b.type,matrix:e}))}}),c.Image&&j(c.Image,{fromDataURL:function(a,b,d){!c.support.dataURI||a.length>3e4?o(c.extend({scale:"exactFit"},b),a.replace(/^data:[^,]+,/,""),function(a,b){d(b)}):this.parent(a,b,d)}}),j(c.Form.prototype,{toData:function(a){for(var b=this.items,d=b.length;d--;)if(b[d].file&&k(b[d].blob))return this.parent.apply(this,arguments);c.log("FlashAPI.Form.toData"),a(b)}}),j(c.XHR.prototype,{_send:function(a,b){if(b.nodeName||b.append&&c.support.html5||c.isArray(b)&&"string"==typeof b[0])return this.parent.apply(this,arguments);var d,e,f={},h={},i=this;if(g(b,function(a){a.file?(h[a.name]=a=p(a.blob),e=a.id,d=a.flashId):f[a.name]=a.blob}),e||(d=r),!d)return c.log("[err] FlashAPI._send: flashId -- undefined"),this.parent.apply(this,arguments);c.log("FlashAPI.XHR._send: "+d+" -> "+e),i.xhr={headers:{},abort:function(){v.cmd(d,"abort",{id:e})},getResponseHeader:function(a){return this.headers[a]},getAllResponseHeaders:function(){return this.headers}};var j=c.queue(function(){v.cmd(d,"upload",{url:n(a.url.replace(/([a-z]+)=(\?)&?/i,"")),data:f,files:e?h:null,headers:a.headers||{},callback:l(function b(d){var e=d.type,f=d.result;c.log("FlashAPI.upload."+e),"progress"==e?(d.loaded=Math.min(d.loaded,d.total),d.lengthComputable=!0,a.progress(d)):"complete"==e?(m(b),"string"==typeof f&&(i.responseText=f.replace(/%22/g,'"').replace(/%5c/g,"\\").replace(/%26/g,"&").replace(/%25/g,"%")),i.end(d.status||200)):("abort"==e||"error"==e)&&(i.end(d.status||0,d.message),m(b))})})});g(h,function(a){j.inc(),c.getInfo(a,j.next)}),j.check()}})}};c.Flash=v,c.newImage("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==",function(a,b){c.support.dataURI=!(1!=b.width||1!=b.height),v.init()})}()}(window,window.jQuery,FileAPI),function(a,b,c){"use strict";var d=c.each,e=[];!c.support.flash||!c.media||c.support.media&&c.html5||!function(){function a(a){var b=a.wid=c.uid();return c.Flash._fn[b]=a,"FileAPI.Flash._fn."+b}function b(a){try{c.Flash._fn[a.wid]=null,delete c.Flash._fn[a.wid]}catch(b){}}var f=c.Flash;c.extend(c.Flash,{patchCamera:function(){c.Camera.fallback=function(d,e,g){var h=c.uid();c.log("FlashAPI.Camera.publish: "+h),f.publish(d,h,c.extend(e,{camera:!0,onEvent:a(function i(a){"camera"===a.type&&(b(i),a.error?(c.log("FlashAPI.Camera.publish.error: "+a.error),g(a.error)):(c.log("FlashAPI.Camera.publish.success: "+h),g(null)))})}))},d(e,function(a){c.Camera.fallback.apply(c.Camera,a)}),e=[],c.extend(c.Camera.prototype,{_id:function(){return this.video.id},start:function(d){var e=this;f.cmd(this._id(),"camera.on",{callback:a(function g(a){b(g),a.error?(c.log("FlashAPI.camera.on.error: "+a.error),d(a.error,e)):(c.log("FlashAPI.camera.on.success: "+e._id()),e._active=!0,d(null,e))})})},stop:function(){this._active=!1,f.cmd(this._id(),"camera.off")},shot:function(){c.log("FlashAPI.Camera.shot:",this._id());var a=c.Flash.cmd(this._id(),"shot",{});return a.type="image/png",a.flashId=this._id(),a.isShot=!0,new c.Camera.Shot(a)}})}}),c.Camera.fallback=function(){e.push(arguments)}}()}(window,window.jQuery,FileAPI),"function"==typeof define&&define.amd&&define("FileAPI",[],function(){return FileAPI}); \ No newline at end of file +/*! FileAPI 2.1.1 - BSD | git://github.com/mailru/FileAPI.git */ +!function(a){"use strict";var b=a.HTMLCanvasElement&&a.HTMLCanvasElement.prototype,c=a.Blob&&function(){try{return Boolean(new Blob)}catch(a){return!1}}(),d=c&&a.Uint8Array&&function(){try{return 100===new Blob([new Uint8Array(100)]).size}catch(a){return!1}}(),e=a.BlobBuilder||a.WebKitBlobBuilder||a.MozBlobBuilder||a.MSBlobBuilder,f=(c||e)&&a.atob&&a.ArrayBuffer&&a.Uint8Array&&function(a){var b,f,g,h,i,j;for(b=a.split(",")[0].indexOf("base64")>=0?atob(a.split(",")[1]):decodeURIComponent(a.split(",")[1]),f=new ArrayBuffer(b.length),g=new Uint8Array(f),h=0;h0,I=a.dataURLtoBlob,J=/img/i,K=/canvas/i,L=/img|canvas/i,M=/input/i,N=/^data:[^,]+,/,O={}.toString,P=a.Math,Q=function(b){return b=new a.Number(P.pow(1024,b)),b.from=function(a){return P.round(a*this)},b},R={},S=[],T="abort progress error load loadend",U="status statusText readyState response responseXML responseText responseBody".split(" "),V="currentTarget",W="preventDefault",X=function(a){return a&&"length"in a},Y=function(a,b,c){if(a)if(X(a))for(var d=0,e=a.length;d=c&&!d&&f.end()},isFail:function(){return d},fail:function(){!d&&a(d=!0)},end:function(){e||(e=!0,a())}};return f},each:Y,afor:function(a,b){var c=0,d=a.length;X(a)&&d--?function e(){b(d!=c&&e,a[c],c++)}():b(!1)},extend:Z,isFile:function(a){return"[object File]"===O.call(a)},isBlob:function(a){return this.isFile(a)||"[object Blob]"===O.call(a)},isCanvas:function(a){return a&&K.test(a.nodeName)},getFilesFilter:function(a){return a="string"==typeof a?a:a.getAttribute&&a.getAttribute("accept")||"",a?new RegExp("("+a.replace(/\./g,"\\.").replace(/,/g,"|")+")$","i"):/./},readAsDataURL:function(a,b){da.isCanvas(a)?c(a,b,"load",da.toDataURL(a)):e(a,b,"DataURL")},readAsBinaryString:function(a,b){d("BinaryString")?e(a,b,"BinaryString"):e(a,function(a){if("load"==a.type)try{a.result=da.toBinaryString(a.result)}catch(b){a.type="error",a.message=b.toString()}b(a)},"DataURL")},readAsArrayBuffer:function(a,b){e(a,b,"ArrayBuffer")},readAsText:function(a,b,c){c||(c=b,b="utf-8"),e(a,c,"Text",b)},toDataURL:function(a,b){return"string"==typeof a?a:a.toDataURL?a.toDataURL(b||"image/png"):void 0},toBinaryString:function(b){return a.atob(da.toDataURL(b).replace(N,""))},readAsImage:function(a,d,e){if(da.isBlob(a))if(x){var f=x.createObjectURL(a);f===b?c(a,d,"error"):da.readAsImage(f,d,e)}else da.readAsDataURL(a,function(b){"load"==b.type?da.readAsImage(b.result,d,e):(e||"error"==b.type)&&c(a,d,b,null,{loaded:b.loaded,total:b.total})});else if(da.isCanvas(a))c(a,d,"load",a);else if(J.test(a.nodeName))if(a.complete)c(a,d,"load",a);else{var g="error abort load";aa(a,g,function b(e){"load"==e.type&&x&&x.revokeObjectURL(a.src),_(a,g,b),c(a,d,e,a)})}else if(a.iframe)c(a,d,{type:"error"});else{var h=da.newImage(a.dataURL||a);da.readAsImage(h,d,e)}},checkFileObj:function(a){var b={},c=da.accept;return"object"==typeof a?b=a:b.name=(a+"").split(/\\|\//g).pop(),null==b.type&&(b.type=b.name.split(".").pop()),Y(c,function(a,c){a=new RegExp(a.replace(/\s/g,"|"),"i"),(a.test(b.type)||da.ext2mime[b.type])&&(b.type=da.ext2mime[b.type]||c.split("/")[0]+"/"+b.type)}),b},getDropFiles:function(a,b){var c,d=[],e=[],j=l(a),k=j.files,m=j.items,n=X(m)&&m[0]&&h(m[0]),o=da.queue(function(){b(d,e)});if(n)if(H&&k){var p,q,r=k.length;for(c=new Array(r);r--;){p=k[r];try{q=h(m[r])}catch(a){da.log("[err] getDropFiles: ",a),q=null}g(q)&&(q.isDirectory||q.isFile&&p.name==p.name.normalize("NFC"))?c[r]=q:c[r]=p}}else c=m;else c=k;Y(c||[],function(a){o.inc();try{n&&g(a)?i(a,function(a,b,c){a?da.log("[err] getDropFiles:",a):d.push.apply(d,b),e.push.apply(e,c),o.next()}):f(a,function(b,c){b?d.push(a):a.error=c,e.push(a),o.next()})}catch(a){o.next(),da.log("[err] getDropFiles: ",a)}}),o.check()},getFiles:function(a,b,c){var d=[];return c?(da.filterFiles(da.getFiles(a),b,c),null):(a.jquery&&(a.each(function(){d=d.concat(da.getFiles(this))}),a=d,d=[]),"string"==typeof b&&(b=da.getFilesFilter(b)),a.originalEvent?a=ba(a.originalEvent):a.srcElement&&(a=ba(a)),a.dataTransfer?a=a.dataTransfer:a.target&&(a=a.target),a.files?(d=a.files,E||(d[0].blob=a,d[0].iframe=!0)):!E&&k(a)?da.trim(a.value)&&(d=[da.checkFileObj(a.value)],d[0].blob=a,d[0].iframe=!0):X(a)&&(d=a),da.filter(d,function(a){return!b||b.test(a.name)}))},getTotalSize:function(a){for(var b=0,c=a&&a.length;c--;)b+=a[c].size;return b},getInfo:function(a,b){var c={},d=S.concat();da.isBlob(a)?function e(){var f=d.shift();f?f.test(a.type)?f(a,function(a,d){a?b(a):(Z(c,d),e())}):e():b(!1,c)}():b("not_support_info",c)},addInfoReader:function(a,b){b.test=function(b){return a.test(b)},S.push(b)},filter:function(a,b){for(var c,d=[],e=0,f=a.length;e>2,k=(3&g)<<4|h>>4;isNaN(h)?e=f=64:(e=(15&h)<<2|i>>6,f=isNaN(i)?64:63&i),c+=b.charAt(j)+b.charAt(k)+b.charAt(e)+b.charAt(f)}return c}};da.addInfoReader(/^image/,function(a,b){if(!a.__dimensions){var c=a.__dimensions=da.defer();da.readAsImage(a,function(a){var b=a.target;c.resolve("load"!=a.type&&"error",{width:b.width,height:b.height}),b.src=da.EMPTY_PNG,b=null})}a.__dimensions.then(b)}),da.event.dnd=function(a,b,c){var d,e;c||(c=b,b=da.F),A?($(a,"dragenter dragleave dragover",b.ff=b.ff||function(a){for(var c=l(a).types,f=c&&c.length,g=!1;f--;)if(~c[f].indexOf("File")){a[W](),e!==a.type&&(e=a.type,"dragleave"!=e&&b.call(a[V],!0,a),g=!0);break}g&&(clearTimeout(d),d=setTimeout(function(){b.call(a[V],"dragleave"!=e,a)},50))}),$(a,"drop",c.ff=c.ff||function(a){a[W](),e=0,da.getDropFiles(a,function(b,d){c.call(a[V],b,d,a)}),b.call(a[V],!1,a)})):da.log("Drag'n'Drop -- not supported")},da.event.dnd.off=function(a,b,c){_(a,"dragenter dragleave dragover",b.ff),_(a,"drop",c.ff)},D&&!D.fn.dnd&&(D.fn.dnd=function(a,b){return this.each(function(){da.event.dnd(this,a,b)})},D.fn.offdnd=function(a,b){return this.each(function(){da.event.dnd.off(this,a,b)})}),a.FileAPI=Z(da,a.FileAPI),da.log("FileAPI: "+da.version),da.log("protocol: "+a.location.protocol),da.log("doctype: ["+s.name+"] "+s.publicId+" "+s.systemId),Y(r.getElementsByTagName("meta"),function(a){/x-ua-compatible/i.test(a.getAttribute("http-equiv"))&&da.log("meta.http-equiv: "+a.getAttribute("content"))});try{n=!!console.log,o=!!console.log.apply}catch(a){}da.flashUrl||(da.flashUrl=da.staticPath+"FileAPI.flash.swf"),da.flashImageUrl||(da.flashImageUrl=da.staticPath+"FileAPI.flash.image.swf"),da.flashWebcamUrl||(da.flashWebcamUrl=da.staticPath+"FileAPI.flash.camera.swf")}(window,void 0),function(a,b,c){"use strict";function d(b){if(b instanceof d){var c=new d(b.file);return a.extend(c.matrix,b.matrix),c}if(!(this instanceof d))return new d(b);this.file=b,this.size=b.size||100,this.matrix={sx:0,sy:0,sw:0,sh:0,dx:0,dy:0,dw:0,dh:0,resize:0,deg:0,quality:1,filter:0}}var e=Math.min,f=Math.round,g=function(){return b.createElement("canvas")},h=!1,i={8:270,3:180,6:90,7:270,4:180,5:90};try{h=g().toDataURL("image/png").indexOf("data:image/png")>-1}catch(a){}d.prototype={image:!0,constructor:d,set:function(b){return a.extend(this.matrix,b),this},crop:function(a,b,d,e){return d===c&&(d=a,e=b,a=b=0),this.set({sx:a,sy:b,sw:d,sh:e||d})},resize:function(a,b,c){return/min|max|height|width/.test(b)&&(c=b,b=a),this.set({dw:a,dh:b||a,resize:c})},preview:function(a,b){return this.resize(a,b||a,"preview")},rotate:function(a){return this.set({deg:a})},filter:function(a){return this.set({filter:a})},overlay:function(a){return this.set({overlay:a})},clone:function(){return new d(this)},_load:function(b,c){var d=this;/img|video/i.test(b.nodeName)?c.call(d,null,b):a.readAsImage(b,function(a){c.call(d,"load"!=a.type,a.result)})},_apply:function(b,c){var f,h=g(),i=this.getMatrix(b),j=h.getContext("2d"),k=b.videoWidth||b.width,l=b.videoHeight||b.height,m=i.deg,n=i.dw,o=i.dh,p=k,q=l,r=i.filter,s=b,t=i.overlay,u=a.queue(function(){b.src=a.EMPTY_PNG,c(!1,h)}),v=a.renderImageToCanvas;for(m-=360*Math.floor(m/360),b._type=this.file.type;i.multipass&&e(p/n,q/o)>2;)p=p/2+.5|0,q=q/2+.5|0,f=g(),f.width=p,f.height=q,s!==b?(v(f,s,0,0,s.width,s.height,0,0,p,q),s=f):(s=f,v(s,b,i.sx,i.sy,i.sw,i.sh,0,0,p,q),i.sx=i.sy=i.sw=i.sh=0);h.width=m%180?o:n,h.height=m%180?n:o,h.type=i.type,h.quality=i.quality,j.rotate(m*Math.PI/180),v(j.canvas,s,i.sx,i.sy,i.sw||s.width,i.sh||s.height,180==m||270==m?-n:0,90==m||180==m?-o:0,n,o),n=h.width,o=h.height,t&&a.each([].concat(t),function(b){u.inc();var c=new window.Image,d=function(){var e=0|b.x,f=0|b.y,g=b.w||c.width,h=b.h||c.height,i=b.rel;e=1==i||4==i||7==i?(n-g+e)/2:2==i||5==i||8==i?n-(g+e):e,f=3==i||4==i||5==i?(o-h+f)/2:i>=6?o-(h+f):f,a.event.off(c,"error load abort",d);try{j.globalAlpha=b.opacity||1,j.drawImage(c,e,f,g,h)}catch(a){}u.next()};a.event.on(c,"error load abort",d),c.src=b.src,c.complete&&d()}),r&&(u.inc(),d.applyFilter(h,r,u.next)),u.check()},getMatrix:function(b){var c=a.extend({},this.matrix),d=c.sw=c.sw||b.videoWidth||b.naturalWidth||b.width,g=c.sh=c.sh||b.videoHeight||b.naturalHeight||b.height,h=c.dw=c.dw||d,i=c.dh=c.dh||g,j=d/g,k=h/i,l=c.resize;if("preview"==l){if(h!=d||i!=g){var m,n;k>=j?(m=d,n=m/k):(n=g,m=n*k),m==d&&n==g||(c.sx=~~((d-m)/2),c.sy=~~((g-n)/2),d=m,g=n)}}else"height"==l?h=i*j:"width"==l?i=h/j:l&&(d>h||g>i?"min"==l?(h=f(j=k?e(d,h):i*j),i=f(j>=k?h/j:e(g,i))):(h=d,i=g));return c.sw=d,c.sh=g,c.dw=h,c.dh=i,c.multipass=a.multiPassResize,c},_trans:function(b){this._load(this.file,function(c,d){if(c)b(c);else try{this._apply(d,b)}catch(c){a.log("[err] FileAPI.Image.fn._apply:",c),b(c)}})},get:function(b){if(a.support.transform){var c=this,d=c.matrix;"auto"==d.deg?a.getInfo(c.file,function(a,e){d.deg=i[e&&e.exif&&e.exif.Orientation]||0,c._trans(b)}):c._trans(b)}else b("not_support_transform");return this},toData:function(a){return this.get(a)}},d.exifOrientation=i,d.transform=function(b,e,f,g){function h(h,i){var j={},k=a.queue(function(a){g(a,j)});h?k.fail():a.each(e,function(a,e){if(!k.isFail()){var g=new d(i.nodeType?i:b),h="function"==typeof a;if(h?a(i,g):a.width?g[a.preview?"preview":"resize"](a.width,a.height,a.strategy):a.maxWidth&&(i.width>a.maxWidth||i.height>a.maxHeight)&&g.resize(a.maxWidth,a.maxHeight,"max"),a.crop){var l=a.crop;g.crop(0|l.x,0|l.y,l.w||l.width,l.h||l.height)}a.rotate===c&&f&&(a.rotate="auto"),g.set({type:g.matrix.type||a.type||b.type||"image/png"}),h||g.set({deg:a.rotate,overlay:a.overlay,filter:a.filter,quality:a.quality||1}),k.inc(),g.toData(function(a,b){a?k.fail():(j[e]=b,k.next())})}})}b.width?h(!1,b):a.getInfo(b,h)},a.each(["TOP","CENTER","BOTTOM"],function(b,c){a.each(["LEFT","CENTER","RIGHT"],function(a,e){d[b+"_"+a]=3*c+e,d[a+"_"+b]=3*c+e})}),d.toCanvas=function(a){var c=b.createElement("canvas");return c.width=a.videoWidth||a.width,c.height=a.videoHeight||a.height,c.getContext("2d").drawImage(a,0,0),c},d.fromDataURL=function(b,c,d){var e=a.newImage(b);a.extend(e,c),d(e)},d.applyFilter=function(b,c,e){"function"==typeof c?c(b,e):window.Caman&&window.Caman("IMG"==b.tagName?d.toCanvas(b):b,function(){"string"==typeof c?this[c]():a.each(c,function(a,b){this[b](a)},this),this.render(e)})},a.renderImageToCanvas=function(b,c,d,e,f,g,h,i,j,k){try{return b.getContext("2d").drawImage(c,d,e,f,g,h,i,j,k)}catch(b){throw a.log("renderImageToCanvas failed"),b}},a.support.canvas=a.support.transform=h,a.Image=d}(FileAPI,document),function(a){"use strict";a(FileAPI)}(function(a){"use strict";if(window.navigator&&window.navigator.platform&&/iP(hone|od|ad)/.test(window.navigator.platform)){var b=a.renderImageToCanvas;a.detectSubsampling=function(a){var b,c;return a.width*a.height>1048576&&(b=document.createElement("canvas"),b.width=b.height=1,c=b.getContext("2d"),c.drawImage(a,1-a.width,0),0===c.getImageData(0,0,1,1).data[3])},a.detectVerticalSquash=function(a,b){var c,d,e,f,g,h=a.naturalHeight||a.height,i=document.createElement("canvas"),j=i.getContext("2d");for(b&&(h/=2),i.width=1,i.height=h,j.drawImage(a,0,0),c=j.getImageData(0,0,1,h).data,d=0,e=h,f=h;f>d;)g=c[4*(f-1)+3],0===g?e=f:d=f,f=e+d>>1;return f/h||1},a.renderImageToCanvas=function(c,d,e,f,g,h,i,j,k,l){if("image/jpeg"===d._type){var m,n,o,p,q=c.getContext("2d"),r=document.createElement("canvas"),s=1024,t=r.getContext("2d");if(r.width=s,r.height=s,q.save(),m=a.detectSubsampling(d),m&&(e/=2,f/=2,g/=2,h/=2),n=a.detectVerticalSquash(d,m),m||1!==n){for(f*=n,k=Math.ceil(s*k/g),l=Math.ceil(s*l/h/n),j=0,p=0;p0&&1==a.filter(this.items,function(a){return a.file}).length,a.support.html5?a.formData&&!this.multipart&&e?c._chunked?(a.log("FileAPI.Form.toPlainData"),this.toPlainData(b)):(a.log("FileAPI.Form.toFormData"),this.toFormData(b)):(a.log("FileAPI.Form.toMultipartData"),this.toMultipartData(b)):(a.log("FileAPI.Form.toHtmlData"),this.toHtmlData(b))},_to:function(b,c,d,e){var f=a.queue(function(){c(b)});this.each(function(g){try{d(g,b,f,e)}catch(b){a.log("FileAPI.Form._to: "+b.message),c(b)}}),f.check()},toHtmlData:function(b){this._to(d.createDocumentFragment(),b,function(b,c){var e,f=b.blob;b.file?(a.reset(f,!0),f.name=b.name,f.disabled=!1,c.appendChild(f)):(e=d.createElement("input"),e.name=b.name,e.type="hidden",e.value=f,c.appendChild(e))})},toPlainData:function(a){this._to({},a,function(a,b,d){a.file&&(b.type=a.file),a.blob.toBlob?(d.inc(),c(a,function(a,c){b.name=a.name,b.file=c,b.size=c.length,b.type=a.type,d.next()})):a.file?(b.name=a.blob.name,b.file=a.blob,b.size=a.blob.size,b.type=a.type):(b.params||(b.params=[]),b.params.push(g(a.name)+"="+g(a.blob))),b.start=-1,b.end=b.file&&b.file.FileAPIReadPosition||-1,b.retry=0})},toFormData:function(a){this._to(new e,a,function(a,b,d){a.blob&&a.blob.toBlob?(d.inc(),c(a,function(a,c){b.append(a.name,c,a.file),d.next()})):a.file?b.append(a.name,a.blob,a.file):b.append(a.name,a.blob),a.file&&b.append("_"+a.name,a.file)})},toMultipartData:function(b){this._to([],b,function(a,b,d,e){d.inc(),c(a,function(a,c){b.push("--_"+e+'\r\nContent-Disposition: form-data; name="'+a.name+'"'+(a.file?'; filename="'+g(a.file)+'"':"")+(a.file?"\r\nContent-Type: "+(a.type||"application/octet-stream"):"")+"\r\n\r\n"+(a.file?c:g(c))+"\r\n"),d.next()},!0)},a.expando)}},a.Form=f}(FileAPI,window),function(a,b){"use strict";var c=function(){},d=a.document,e=function(a){this.uid=b.uid(),this.xhr={abort:c,getResponseHeader:c,getAllResponseHeaders:c},this.options=a},f={"":1,XML:1,Text:1,Body:1};e.prototype={status:0,statusText:"",constructor:e,getResponseHeader:function(a){return this.xhr.getResponseHeader(a)},getAllResponseHeaders:function(){return this.xhr.getAllResponseHeaders()||{}},end:function(d,e){var f=this,g=f.options;f.end=f.abort=c,f.status=d,e&&(f.statusText=e),b.log("xhr.end:",d,e),g.complete(200!=d&&201!=d&&(f.statusText||"unknown"),f),f.xhr&&f.xhr.node&&setTimeout(function(){var b=f.xhr.node;try{b.parentNode.removeChild(b)}catch(a){}try{delete a[f.uid]}catch(a){}a[f.uid]=f.xhr.node=null},9)},abort:function(){this.end(0,"abort"),this.xhr&&(this.xhr.aborted=!0,this.xhr.abort())},send:function(a){var b=this,c=this.options;a.toData(function(a){a instanceof Error?b.end(0,a.message):(c.upload(c,b),b._send.call(b,c,a))},c)},_send:function(c,e){var g,h=this,i=h.uid,j=h.uid+"Load",k=c.url;if(b.log("XHR._send:",e),c.cache||(k+=(~k.indexOf("?")?"&":"?")+b.uid()),e.nodeName){var l=c.jsonp;k=k.replace(/([a-z]+)=(\?)/i,"$1="+i),c.upload(c,h);var m=function(a){if(~k.indexOf(a.origin))try{var c=b.parseJSON(a.data);c.id==i&&n(c.status,c.statusText,c.response)}catch(a){n(0,a.message)}},n=a[i]=function(c,d,e){h.readyState=4,h.responseText=e,h.end(c,d),b.event.off(a,"message",m),a[i]=g=p=a[j]=null};h.xhr.abort=function(){try{p.stop?p.stop():p.contentWindow.stop?p.contentWindow.stop():p.contentWindow.document.execCommand("Stop")}catch(a){}n(0,"abort")},b.event.on(a,"message",m),a[j]=function(){try{var a=p.contentWindow,c=a.document,d=a.result||b.parseJSON(c.body.innerHTML);n(d.status,d.statusText,d.response)}catch(a){b.log("[transport.onload]",a)}},g=d.createElement("div"),g.innerHTML='
'+(l&&c.url.indexOf("=?")<0?'':"")+"
";var o=g.getElementsByTagName("form")[0],p=g.getElementsByTagName("iframe")[0];o.appendChild(e),b.log(o.parentNode.innerHTML),d.body.appendChild(g),h.xhr.node=g,h.readyState=2;try{o.submit()}catch(a){b.log("iframe.error: "+a)}o=null}else{if(k=k.replace(/([a-z]+)=(\?)&?/i,""),this.xhr&&this.xhr.aborted)return void b.log("Error: already aborted");if(g=h.xhr=b.getXHR(),e.params&&(k+=(k.indexOf("?")<0?"?":"&")+e.params.join("&")),g.open(c.uploadMethod||"POST",k,!0),"boolean"==typeof c.uploadCredentials?g.withCredentials=c.uploadCredentials?"true":null:b.withCredentials&&(g.withCredentials="true"),c.headers&&c.headers["X-Requested-With"]||g.setRequestHeader("X-Requested-With","XMLHttpRequest"),b.each(c.headers,function(a,b){g.setRequestHeader(b,a)}),c._chunked){g.upload&&g.upload.addEventListener("progress",b.throttle(function(a){e.retry||c.progress({type:a.type,total:e.size,loaded:e.start+a.loaded,totalSize:e.size},h,c)},100),!1),g.onreadystatechange=function(){var a=parseInt(g.getResponseHeader("X-Last-Known-Byte"),10);if(h.status=g.status,h.statusText=g.statusText,h.readyState=g.readyState,4==g.readyState){for(var d in f)h["response"+d]=g["response"+d];if(g.onreadystatechange=null,!g.status||g.status-201>0)if(b.log("Error: "+g.status),(!g.status&&!g.aborted||500==g.status||416==g.status)&&++e.retry<=c.chunkUploadRetry){var i=g.status?0:b.chunkNetworkDownRetryTimeout;c.pause(e.file,c),b.log("X-Last-Known-Byte: "+a),a?e.end=a:(e.end=e.start-1,416==g.status&&(e.end=e.end-c.chunkSize)),setTimeout(function(){h._send(c,e)},i)}else h.end(g.status);else e.retry=0,e.end==e.size-1?h.end(g.status):(b.log("X-Last-Known-Byte: "+a),a&&(e.end=a),e.file.FileAPIReadPosition=e.end,setTimeout(function(){h._send(c,e)},0));g=null}},e.start=e.end+1,e.end=Math.max(Math.min(e.start+c.chunkSize,e.size)-1,e.start);var q=e.file,r=(q.slice||q.mozSlice||q.webkitSlice).call(q,e.start,e.end+1);e.size&&!r.size?setTimeout(function(){h.end(-1)}):(g.setRequestHeader("Content-Range","bytes "+e.start+"-"+e.end+"/"+e.size),g.setRequestHeader("Content-Disposition","attachment; filename="+encodeURIComponent(e.name)),g.setRequestHeader("Content-Type",e.type||"application/octet-stream"),g.send(r)),q=r=null}else if(g.upload&&g.upload.addEventListener("progress",b.throttle(function(a){c.progress(a,h,c)},100),!1),g.onreadystatechange=function(){if(h.status=g.status,h.statusText=g.statusText,h.readyState=g.readyState,4==g.readyState){for(var a in f)h["response"+a]=g["response"+a];if(g.onreadystatechange=null,!g.status||g.status>201)if(b.log("Error: "+g.status),(!g.status&&!g.aborted||500==g.status)&&(c.retry||0)=0?a+"px":a}function d(a){var c,d=f.createElement("canvas"),e=!1;try{c=d.getContext("2d"),c.drawImage(a,0,0,1,1),e=255!=c.getImageData(0,0,1,1).data[4]}catch(a){b.log("[FileAPI.Camera] detectVideoSignal:",a)}return e}var e=a.URL||a.webkitURL,f=a.document,g=a.navigator,h=g.getUserMedia||g.webkitGetUserMedia||g.mozGetUserMedia||g.msGetUserMedia,i=!!h;b.support.media=i;var j=function(a){this.video=a};j.prototype={isActive:function(){return!!this._active},start:function(a){var b,c,f=this,i=f.video,j=function(d){f._active=!d,clearTimeout(c),clearTimeout(b),a&&a(d,f)};h.call(g,{video:!0},function(a){f.stream=a;try{i.src=e.createObjectURL(a)}catch(b){i.srcObject=a}b=setInterval(function(){d(i)&&j(null)},1e3),c=setTimeout(function(){j("timeout")},5e3),i.play()},j)},stop:function(){try{this._active=!1,this.video.pause();try{this.stream.stop()}catch(a){b.each(this.stream.getTracks(),function(a){a.stop()})}this.stream=null}catch(a){b.log("[FileAPI.Camera] stop:",a)}},shot:function(){return new k(this.video)}},j.get=function(a){return new j(a.firstChild)},j.publish=function(d,e,g){"function"==typeof e&&(g=e,e={}),e=b.extend({},{width:"100%",height:"100%",start:!0},e),d.jquery&&(d=d[0]);var h=function(a){if(a)g(a);else{var b=j.get(d);e.start?b.start(g):g(null,b)}};if(d.style.width=c(e.width),d.style.height=c(e.height),b.html5&&i&&!b.insecureChrome){var k=f.createElement("video");k.style.width=c(e.width),k.style.height=c(e.height),a.jQuery?jQuery(d).empty():d.innerHTML="",d.appendChild(k),h()}else j.fallback(d,e,h)},j.fallback=function(a,b,c){c("not_support_camera")},j.checkAlreadyCaptured=function(){var b,c=g.mediaDevices,d=a.MediaStreamTrack,e=g.enumerateDevices;return b=c&&c.enumerateDevices?function(a){c.enumerateDevices().then(a)}:d&&d.getSources?d.getSources.bind(d):e?e.bind(g):function(a){a([])},function(a){b(function(b){var c=b.some(function(a){return("videoinput"===a.kind||"video"===a.kind)&&a.label});a(c)})}}();var k=function(a){var c=a.nodeName?b.Image.toCanvas(a):a,d=b.Image(c);return d.type="image/png",d.width=c.width,d.height=c.height,d.size=c.width*c.height*4,d};j.Shot=k,b.Camera=j}(window,FileAPI),function(a,b,c){"use strict";var d=a.document,e=a.location,f=a.navigator,g=c.each;c.support.flash=function(){var b=f.mimeTypes,d=!1;if(f.plugins&&"object"==typeof f.plugins["Shockwave Flash"])d=f.plugins["Shockwave Flash"].description&&!(b&&b["application/x-shockwave-flash"]&&!b["application/x-shockwave-flash"].enabledPlugin);else try{d=!(!a.ActiveXObject||!new ActiveXObject("ShockwaveFlash.ShockwaveFlash"))}catch(a){c.log("Flash -- does not supported.")}return d&&/^file:/i.test(e)&&c.log("[warn] Flash does not work on `file:` protocol."),d}(),c.support.flash&&(!c.html5||!c.support.html5||c.cors&&!c.support.cors||c.media&&!c.support.media||c.insecureChrome)&&function(){function h(a){return('').replace(/#(\w+)#/gi,function(b,c){return a[c]})}function i(a,b){if(a&&a.style){var c,d;for(c in b){d=b[c],"number"==typeof d&&(d+="px");try{a.style[c]=d}catch(a){}}}}function j(a,b){g(b,function(b,c){var d=a[c];a[c]=function(){return this.parent=d,b.apply(this,arguments)}})}function k(a){return a&&!a.flashId}function l(a){var b=a.wid=c.uid();return v._fn[b]=a,"FileAPI.Flash._fn."+b}function m(a){try{v._fn[a.wid]=null,delete v._fn[a.wid]}catch(a){}}function n(a,b){if(!u.test(a)){if(/^\.\//.test(a)||"/"!=a.charAt(0)){var c=e.pathname;c=c.substr(0,c.lastIndexOf("/")),a=(c+"/"+a).replace("/./","/")}"//"!=a.substr(0,2)&&(a="//"+e.host+a),u.test(a)||(a=e.protocol+a)}return b&&(a+=(/\?/.test(a)?"&":"?")+b),a}function o(a,b,e){function f(){try{v.get(j).setImage(b)}catch(a){c.log('[err] FlashAPI.Preview.setImage -- can not set "base64":',a)}}var g,j=c.uid(),k=d.createElement("div"),o=10;for(g in a)k.setAttribute(g,a[g]),k[g]=a[g];i(k,a),a.width="100%",a.height="100%",k.innerHTML=h(c.extend({id:j,src:n(c.flashImageUrl,"r="+c.uid()),wmode:"opaque",flashvars:"scale="+a.scale+"&callback="+l(function a(){return m(a),--o>0&&f(),!0})},a)),e(!1,k),k=null}function p(a){return{id:a.id,name:a.name,matrix:a.matrix,flashId:a.flashId}}function q(b){var c=b.getBoundingClientRect(),e=d.body,f=(b&&b.ownerDocument).documentElement;return{top:c.top+(a.pageYOffset||f.scrollTop)-(f.clientTop||e.clientTop||0),left:c.left+(a.pageXOffset||f.scrollLeft)-(f.clientLeft||e.clientLeft||0),width:c.right-c.left,height:c.bottom-c.top}}var r=c.uid(),s=0,t={},u=/^https?:/i,v={_fn:{},init:function(){var a=d.body&&d.body.firstChild;if(a)do{if(1==a.nodeType){c.log("FlashAPI.state: awaiting");var b=d.createElement("div");return b.id="_"+r,i(b,{top:1,right:1,width:5,height:5,position:"absolute",zIndex:"2147483647"}),a.parentNode.insertBefore(b,a),void v.publish(b,r)}}while(a=a.nextSibling);s<10&&setTimeout(v.init,50*++s)},publish:function(a,b,d){d=d||{},a.innerHTML=h({id:b,src:n(c.flashUrl,"r="+c.version),wmode:d.camera?"":"transparent",flashvars:"callback="+(d.onEvent||"FileAPI.Flash.onEvent")+"&flashId="+b+"&storeKey="+f.userAgent.match(/\d/gi).join("")+"_"+c.version+(v.isReady||(c.pingUrl?"&ping="+c.pingUrl:""))+"&timeout="+c.flashAbortTimeout+(d.camera?"&useCamera="+n(c.flashWebcamUrl):"")+"&debug="+(c.debug?"1":"")},d)},ready:function(){c.log("FlashAPI.state: ready"),v.ready=c.F,v.isReady=!0,v.patch(),v.patchCamera&&v.patchCamera(),c.event.on(d,"mouseover",v.mouseover),c.event.on(d,"click",function(a){v.mouseover(a)&&(a.preventDefault?a.preventDefault():a.returnValue=!0)})},getEl:function(){return d.getElementById("_"+r)},getWrapper:function(a){do{if(/js-fileapi-wrapper/.test(a.className))return a}while((a=a.parentNode)&&a!==d.body)},mouseover:function(a){var b=c.event.fix(a).target;if(/input/i.test(b.nodeName)&&"file"==b.type&&!b.disabled){var e=b.getAttribute(r),f=v.getWrapper(b);if(c.multiFlash){if("i"==e||"r"==e)return!1;if("p"!=e){b.setAttribute(r,"i");var g=d.createElement("div");if(!f)return void c.log("[err] FlashAPI.mouseover: js-fileapi-wrapper not found");i(g,{top:0,left:0,width:b.offsetWidth,height:b.offsetHeight,zIndex:"2147483647",position:"absolute"}),f.appendChild(g),v.publish(g,c.uid()),b.setAttribute(r,"p")}return!0}if(f){var h=q(f);i(v.getEl(),h),v.curInp=b}}else/object|embed/i.test(b.nodeName)||i(v.getEl(),{top:1,left:1,width:5,height:5})},onEvent:function(a){var b=a.type;if("ready"==b){try{v.getInput(a.flashId).setAttribute(r,"r")}catch(a){}return v.ready(),setTimeout(function(){v.mouseenter(a)},50),!0}"ping"===b?c.log("(flash -> js).ping:",[a.status,a.savedStatus],a.error):"log"===b?c.log("(flash -> js).log:",a.target):b in v&&setTimeout(function(){c.log("FlashAPI.event."+a.type+":",a),v[b](a)},1)},mouseenter:function(a){var b=v.getInput(a.flashId);if(b){v.cmd(a,"multiple",null!=b.getAttribute("multiple"));var d=[],e={};g((b.getAttribute("accept")||"").split(/,\s*/),function(a){c.accept[a]&&g(c.accept[a].split(" "),function(a){e[a]=1})}),g(e,function(a,b){d.push(b)}),v.cmd(a,"accept",d.length?d.join(",")+","+d.join(",").toUpperCase():"*")}},get:function(b){return d[b]||a[b]||d.embeds[b]},getInput:function(a){if(!c.multiFlash)return v.curInp;try{var b=v.getWrapper(v.get(a));if(b)return b.getElementsByTagName("input")[0]}catch(b){c.log('[err] Can not find "input" by flashId:',a,b)}},select:function(a){var e,f=v.getInput(a.flashId),h=c.uid(f),i=a.target.files;g(i,function(a){c.checkFileObj(a)}),t[h]=i,d.createEvent?(e=d.createEvent("Event"),e.files=i,e.initEvent("change",!0,!0),f.dispatchEvent(e)):b?b(f).trigger({type:"change",files:i}):(e=d.createEventObject(),e.files=i,f.fireEvent("onchange",e))},cmd:function(a,b,d,e){try{return c.log("(js -> flash)."+b+":",d),v.get(a.flashId||a).cmd(b,d)}catch(f){c.log("(js -> flash).onError:",f.toString()),e||setTimeout(function(){v.cmd(a,b,d,!0)},50)}},patch:function(){c.flashEngine=!0,j(c,{getFiles:function(a,b,d){if(d)return c.filterFiles(c.getFiles(a),b,d),null;var e=c.isArray(a)?a:t[c.uid(a.target||a.srcElement||a)];return e?(b&&(b=c.getFilesFilter(b),e=c.filter(e,function(a){return b.test(a.name)})),e):this.parent.apply(this,arguments)},getInfo:function(a,b){if(k(a))this.parent.apply(this,arguments);else if(a.isShot)b(null,a.info={width:a.width,height:a.height});else{if(!a.__info){var d=a.__info=c.defer();v.cmd(a,"getFileInfo",{id:a.id,callback:l(function b(c,e){m(b),d.resolve(c,a.info=e)})})}a.__info.then(b)}}}),c.support.transform=!0,c.Image&&j(c.Image.prototype,{get:function(a,b){return this.set({scaleMode:b||"noScale"}),this.parent(a)},_load:function(a,b){if(c.log("FlashAPI.Image._load:",a),k(a))this.parent.apply(this,arguments);else{var d=this;c.getInfo(a,function(c){b.call(d,c,a)})}},_apply:function(a,b){if(c.log("FlashAPI.Image._apply:",a),k(a))this.parent.apply(this,arguments);else{var d=this.getMatrix(a.info),e=b;v.cmd(a,"imageTransform",{id:a.id,matrix:d,callback:l(function f(g,h){c.log("FlashAPI.Image._apply.callback:",g),m(f),g?e(g):c.support.html5||c.support.dataURI&&!(h.length>3e4)?(d.filter&&(e=function(a,e){a?b(a):c.Image.applyFilter(e,d.filter,function(){b(a,this.canvas)})}),c.newImage("data:"+a.type+";base64,"+h,e)):o({width:d.deg%180?d.dh:d.dw,height:d.deg%180?d.dw:d.dh,scale:d.scaleMode},h,e)})})}},toData:function(a){var b=this.file,d=b.info,e=this.getMatrix(d);c.log("FlashAPI.Image.toData"),k(b)?this.parent.apply(this,arguments):("auto"==e.deg&&(e.deg=c.Image.exifOrientation[d&&d.exif&&d.exif.Orientation]||0),a.call(this,!b.info,{id:b.id,flashId:b.flashId,name:b.name,type:b.type,matrix:e}))}}),c.Image&&j(c.Image,{fromDataURL:function(a,b,d){!c.support.dataURI||a.length>3e4?o(c.extend({scale:"exactFit"},b),a.replace(/^data:[^,]+,/,""),function(a,b){d(b)}):this.parent(a,b,d)}}),j(c.Form.prototype,{toData:function(a){for(var b=this.items,d=b.length;d--;)if(b[d].file&&k(b[d].blob))return this.parent.apply(this,arguments);c.log("FlashAPI.Form.toData"),a(b)}}),j(c.XHR.prototype,{_send:function(a,b){if(b.nodeName||b.append&&c.support.html5||c.isArray(b)&&"string"==typeof b[0])return this.parent.apply(this,arguments);var d,e,f={},h={},i=this;if(g(b,function(a){a.file?(h[a.name]=a=p(a.blob),e=a.id,d=a.flashId):f[a.name]=a.blob}),e||(d=r),!d)return c.log("[err] FlashAPI._send: flashId -- undefined"),this.parent.apply(this,arguments);c.log("FlashAPI.XHR._send: "+d+" -> "+e),i.xhr={headers:{},abort:function(){v.cmd(d,"abort",{id:e})},getResponseHeader:function(a){return this.headers[a]},getAllResponseHeaders:function(){return this.headers}};var j=c.queue(function(){v.cmd(d,"upload",{url:n(a.url.replace(/([a-z]+)=(\?)&?/i,"")),data:f,files:e?h:null,headers:a.headers||{},callback:l(function b(d){var e=d.type,f=d.result;c.log("FlashAPI.upload."+e),"progress"==e?(d.loaded=Math.min(d.loaded,d.total),d.lengthComputable=!0,a.progress(d)):"complete"==e?(m(b),"string"==typeof f&&(i.responseText=f.replace(/%22/g,'"').replace(/%5c/g,"\\").replace(/%26/g,"&").replace(/%25/g,"%")),i.end(d.status||200)):"abort"!=e&&"error"!=e||(i.end(d.status||0,d.message),m(b))})})});g(h,function(a){j.inc(),c.getInfo(a,j.next)}),j.check()}})}};c.Flash=v,c.newImage("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==",function(a,b){c.support.dataURI=!(1!=b.width||1!=b.height),v.init()})}()}(window,window.jQuery,FileAPI),function(a,b,c){"use strict";var d=c.each,e=[];!c.support.flash||!c.media||c.support.media&&c.html5&&!c.insecureChrome||function(){function a(a){var b=a.wid=c.uid();return c.Flash._fn[b]=a,"FileAPI.Flash._fn."+b}function b(a){try{c.Flash._fn[a.wid]=null,delete c.Flash._fn[a.wid]}catch(a){}}var f=c.Flash;c.extend(c.Flash,{patchCamera:function(){c.Camera.fallback=function(d,e,g){var h=c.uid();c.log("FlashAPI.Camera.publish: "+h),f.publish(d,h,c.extend(e,{camera:!0,onEvent:a(function a(d){"camera"===d.type&&(b(a),d.error?(c.log("FlashAPI.Camera.publish.error: "+d.error),g(d.error)):(c.log("FlashAPI.Camera.publish.success: "+h),g(null)))})}))},d(e,function(a){c.Camera.fallback.apply(c.Camera,a)}),e=[],c.extend(c.Camera.prototype,{_id:function(){return this.video.id},start:function(d){var e=this;f.cmd(this._id(),"camera.on",{callback:a(function a(f){b(a),f.error?(c.log("FlashAPI.camera.on.error: "+f.error),d(f.error,e)):(c.log("FlashAPI.camera.on.success: "+e._id()),e._active=!0,d(null,e))})})},stop:function(){this._active=!1,f.cmd(this._id(),"camera.off")},shot:function(){c.log("FlashAPI.Camera.shot:",this._id());var a=c.Flash.cmd(this._id(),"shot",{});return a.type="image/png",a.flashId=this._id(),a.isShot=!0,new c.Camera.Shot(a)}})}}),c.Camera.fallback=function(){e.push(arguments)}}()}(window,window.jQuery,FileAPI),"function"==typeof define&&define.amd&&define("FileAPI",[],function(){return FileAPI}); \ No newline at end of file diff --git a/examples/demo.html b/examples/demo.html index 1b098107..93570b8c 100644 --- a/examples/demo.html +++ b/examples/demo.html @@ -486,7 +486,7 @@ _upload: function (file){ if( file ){ file.xhr = FileAPI.upload({ - url: 'http://www.rubaxa.org/index.php', + url: '/upload', files: { file: file }, upload: function (){ FU._getEl(file).addClass('b-file_upload'); diff --git a/examples/thumbnails.html b/examples/thumbnails.html index 03c94ba2..dd4e1e95 100644 --- a/examples/thumbnails.html +++ b/examples/thumbnails.html @@ -57,6 +57,20 @@ right: 0; position: absolute; } + /* IE9/IE8 required */ + .js-fileapi-wrapper { position: relative; } + .js-fileapi-wrapper input { + top: -10px; + right: -40px; + z-index: 2; + position: absolute; + cursor: pointer; + opacity: 0; + width: auto; + height: auto; + filter: alpha(opacity=0); + font-size: 50px; + } diff --git a/examples/userpic.html b/examples/userpic.html index e2383f25..e72a55d4 100644 --- a/examples/userpic.html +++ b/examples/userpic.html @@ -154,7 +154,7 @@ // Параметры загрузки var uploadOpts = { - url: 'http://www.rubaxa.org/index.php' // куда грузить + url: '/upload' // куда грузить , data: {} // дополнительный POST-параметры , name: 'userpic' // название POST-параметра загружаемого файла , activeClassName: 'upload_active' // класс, который будем добавлять общему контейнеру при загрузке diff --git a/examples/watermark.html b/examples/watermark.html index d6172282..4403d000 100644 --- a/examples/watermark.html +++ b/examples/watermark.html @@ -182,7 +182,7 @@

EXIF

// Upload FileAPI.upload({ - url: '//rubaxa.org/FileAPI/server/ctrl.php' + url: '/upload' , files: elms.file , imageTransform: { width: elms.width.value|0 diff --git a/examples/webcam.html b/examples/webcam.html index 12281d92..0a995eee 100644 --- a/examples/webcam.html +++ b/examples/webcam.html @@ -114,7 +114,7 @@

Server

; FileAPI.upload({ - url: 'http://rubaxa.org/FileAPI/server/ctrl.php' + url: '/upload' , files: { shot: file } , complete: function (err, xhr){ var res = JSON.parse(xhr.responseText); diff --git a/flash/core/html-template/index.template.html b/flash/core/html-template/index.template.html index d327dade..8d458fd7 100644 --- a/flash/core/html-template/index.template.html +++ b/flash/core/html-template/index.template.html @@ -1,108 +1,108 @@ - - - - - - ${title} - - - - - - - - - - - - - -
-

- To view this page ensure that Adobe Flash Player version - ${version_major}.${version_minor}.${version_revision} or greater is installed. -

- -
- - - - + + + + + + ${title} + + + + + + + + + + + + + +
+

+ To view this page ensure that Adobe Flash Player version + ${version_major}.${version_minor}.${version_revision} or greater is installed. +

+ +
+ + + + diff --git a/flash/core/src/FileAPI_flash.as b/flash/core/src/FileAPI_flash.as index b4d8767e..c869a068 100644 --- a/flash/core/src/FileAPI_flash.as +++ b/flash/core/src/FileAPI_flash.as @@ -7,11 +7,11 @@ package import flash.events.Event; import flash.events.UncaughtErrorEvent; - import ru.mail.controller.AppController; + import ru.mail.controller.AppController; /** * - * @author v.demidov + * @author v.demidov https://github.com/im-saxo * */ public class FileAPI_flash extends Sprite @@ -36,7 +36,6 @@ package */ protected function init(event:Event = null):void { - trace ("{FlashFileAPI} - init"); removeEventListener(Event.ADDED_TO_STAGE, init); // config stage @@ -48,22 +47,10 @@ package addChild(_graphicContext); // initiate controller - _controller = new AppController(_graphicContext, parseFlashVars()); + _controller = new AppController(_graphicContext, loaderInfo.parameters); // add some global listeners stage.addEventListener(Event.RESIZE, _controller.onStageResize); loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, _controller.onUncaughtError); } - - /** - * parse all flashvars into object - */ - private function parseFlashVars():Object - { - var options:Object = new Object(); - for (var s:String in loaderInfo.parameters) { - options[s] = loaderInfo.parameters[s]; - } - return options; - } } -} \ No newline at end of file +} diff --git a/flash/core/src/ru/mail/commands/ResizeFileCommand.as b/flash/core/src/ru/mail/commands/ResizeFileCommand.as index 2405a7d2..0a9d6136 100644 --- a/flash/core/src/ru/mail/commands/ResizeFileCommand.as +++ b/flash/core/src/ru/mail/commands/ResizeFileCommand.as @@ -22,8 +22,8 @@ package ru.mail.commands * * file must be loaded before transforming. * - * Only JPG or PNG images. - * Performing transform on gif or bmp will result in returning the original image data. + * JPG and PNG will keep their extensions after transform. + * GIF and BMP will be encoded as PNG, so uploaded filename will be .png * * The possible solution is to transform them but save as PNG, but we also have to change the uploaded file extension to png. * @@ -47,18 +47,16 @@ package ru.mail.commands { if( !file.imageData ) { complete(false, null, new ErrorVO("ResizeImageCommand - cannot resize file because it has not been succesfully loaded") ); + return; } if (!needResize()) { LoggerJS.log('ResizeImageCommand no need to resize'); complete(true, file.fileData); + return; } var fileType:String = file.fileType; - if (fileType == "gif" || fileType == "bmp") { - // TODO: scale but save jpg - complete(true, file.fileData) - } checkTransform(); @@ -143,15 +141,12 @@ package ru.mail.commands if (imageTransform.multiPassResize && maxScale < 0.5) { - trace ("multi-step "); - var curWidth:Number = currentImageMap.width; var curHeight:Number = currentImageMap.height; var mapToScale:BitmapData; // multi-step while(maxScale < 0.5) { - trace ("step ", maxScale); // series if x2 scalings // temp bitmapdata diff --git a/flash/core/src/ru/mail/communication/JSCaller.as b/flash/core/src/ru/mail/communication/JSCaller.as index f69691cb..675105cc 100644 --- a/flash/core/src/ru/mail/communication/JSCaller.as +++ b/flash/core/src/ru/mail/communication/JSCaller.as @@ -1,6 +1,7 @@ package ru.mail.communication { import flash.external.ExternalInterface; + import flash.utils.ByteArray; import ru.mail.data.vo.ErrorVO; import ru.mail.data.vo.FileVO; @@ -67,7 +68,6 @@ package ru.mail.communication _call(_callback, data, data2); } catch (e:Error) { - trace ("callJS caused an exception", e); } } @@ -82,12 +82,10 @@ package ru.mail.communication var isReady:Boolean = false; try { var r:* = _call(callback, {type:"ready", flashId:flashId}); - trace( "JSCaller.notifyJSAboutAppReady() ", triesCount ); isReady = ( r != null ); } catch ( e:Error ) { - trace ("notifyJSAboutAppReady error", e); } return isReady; @@ -111,7 +109,6 @@ package ru.mail.communication _call(callback, { type:eventType, flashId:flashId }); } catch (e:Error) { - trace ("notifyJSMouseEvents error", e); } } @@ -126,8 +123,6 @@ package ru.mail.communication */ public function notifyJSFilesEvents(eventType:String, filesVector:Vector. = null):void { - trace ("{JSCaller} - notifyJSFilesEvents, eventType", eventType) - var details:Object = new Object(); details.type = eventType; @@ -164,7 +159,6 @@ package ru.mail.communication _call(callback, details); } catch (e:Error) { - trace ("notifyJSFilesEvents error",e); } } @@ -189,7 +183,6 @@ package ru.mail.communication _call(callback, details); } catch (e:Error) { - trace ("notifyJSErrors error",e); } } @@ -204,7 +197,6 @@ package ru.mail.communication _call(callback, { type:'camera', error:error, flashId:flashId }); } catch (e:Error) { - trace ("notifyCameraStatus error", e); } } @@ -222,13 +214,34 @@ package ru.mail.communication _call(callback, {type:"error", message:errorVO.getError(), flashId:flashId}); } catch (e:Error) { - trace ("notifyJSErrors error",e); } } - + + private function clone(source:Object):* { + var myBA:ByteArray = new ByteArray(); + myBA.writeObject(source); + myBA.position = 0; + return(myBA.readObject()); + } + + private function _escape(data:*):* { + if (typeof data === 'string') { + return data.replace(/\\/g, '\\\\'); + } else if (typeof data === 'object') { + var ret:* = clone(data); + for (var i:String in data) { + ret[i] = _escape(data[i]); + } + return ret; + } + return data; + } + private function _call(callback:String, data:Object, data2:Object = null):* { + data = _escape(data); if ( callback.match(/^FileAPI\.Flash\.(onEvent|_fn\.fileapi\d+)$/) ) { if (data2) { + data2 = _escape(data2); return ExternalInterface.call(callback, data, data2); } else { @@ -240,4 +253,4 @@ package ru.mail.communication } } } -} \ No newline at end of file +} diff --git a/flash/core/src/ru/mail/data/vo/FileVO.as b/flash/core/src/ru/mail/data/vo/FileVO.as index eda1ccf7..3834a579 100644 --- a/flash/core/src/ru/mail/data/vo/FileVO.as +++ b/flash/core/src/ru/mail/data/vo/FileVO.as @@ -75,7 +75,7 @@ package ru.mail.data.vo if ( fileNameParts.length < 2 ) return fileName; - return fileNameParts[0] + 'png'; + return fileNameParts[0] + '.png'; } } @@ -84,4 +84,4 @@ package ru.mail.data.vo super(); } } -} \ No newline at end of file +} diff --git a/lib/FileAPI.Camera.js b/lib/FileAPI.Camera.js index 42df39aa..d97eb983 100644 --- a/lib/FileAPI.Camera.js +++ b/lib/FileAPI.Camera.js @@ -64,7 +64,11 @@ // }); // Set camera stream - video.src = URL.createObjectURL(stream); + try { + video.src = URL.createObjectURL(stream); + } catch (err) { + video.srcObject = stream; + } // Note: onloadedmetadata doesn't fire in Chrome when using it with getUserMedia. // See crbug.com/110938. @@ -91,8 +95,19 @@ try { this._active = false; this.video.pause(); - this.stream.stop(); - } catch( err ){ } + + try { + this.stream.stop(); + } catch (err) { + api.each(this.stream.getTracks(), function (track) { + track.stop(); + }); + } + + this.stream = null; + } catch( err ){ + api.log('[FileAPI.Camera] stop:', err); + } }, @@ -167,7 +182,7 @@ el.style.height = _px(options.height); - if( api.html5 && html5 ){ + if( api.html5 && html5 && !api.insecureChrome ){ // Create video element var video = document.createElement('video'); @@ -198,6 +213,38 @@ callback('not_support_camera'); }; + Camera.checkAlreadyCaptured = (function () { + var mediaDevices = navigator.mediaDevices, + MediaStreamTrack = window.MediaStreamTrack, + navigatorEnumerateDevices = navigator.enumerateDevices, + enumerateDevices; + + if (mediaDevices && mediaDevices.enumerateDevices) { + enumerateDevices = function (callback) { + mediaDevices.enumerateDevices().then(callback); + }; + } else if (MediaStreamTrack && MediaStreamTrack.getSources) { + enumerateDevices = MediaStreamTrack.getSources.bind(MediaStreamTrack); + } else if (navigatorEnumerateDevices) { + enumerateDevices = navigatorEnumerateDevices.bind(navigator); + } else { + enumerateDevices = function (fn) { + fn([]); + }; + } + + return function (callback) { + enumerateDevices(function (devices) { + var deviceExists = devices.some(function (device) { + return (device.kind === 'videoinput' || device.kind === 'video') && device.label; + }); + + callback(deviceExists); + }); + }; + + })(); + /** * @class FileAPI.Camera.Shot @@ -237,7 +284,9 @@ ctx.drawImage(video, 0, 0, 1, 1); res = ctx.getImageData(0, 0, 1, 1).data[4] != 255; } - catch( e ){} + catch( err ){ + api.log('[FileAPI.Camera] detectVideoSignal:', err); + } return res; } diff --git a/lib/FileAPI.Flash.Camera.js b/lib/FileAPI.Flash.Camera.js index 8a0539bd..ddf97e65 100644 --- a/lib/FileAPI.Flash.Camera.js +++ b/lib/FileAPI.Flash.Camera.js @@ -11,7 +11,7 @@ var _each = api.each, _cameraQueue = []; - if (api.support.flash && (api.media && (!api.support.media || !api.html5))) { + if (api.support.flash && (api.media && (!api.support.media || !api.html5 || api.insecureChrome))) { (function () { function _wrap(fn) { var id = fn.wid = api.uid(); diff --git a/lib/FileAPI.Flash.js b/lib/FileAPI.Flash.js index 71fe2b17..6ec95736 100644 --- a/lib/FileAPI.Flash.js +++ b/lib/FileAPI.Flash.js @@ -44,6 +44,7 @@ || !api.html5 || !api.support.html5 || (api.cors && !api.support.cors) || (api.media && !api.support.media) + || api.insecureChrome ) && (function (){ var @@ -77,7 +78,7 @@ , width: 5 , height: 5 , position: 'absolute' - , zIndex: 1e6+'' // set max zIndex + , zIndex: 2147483647+'' // set max zIndex }); child.parentNode.insertBefore(dummy, child); @@ -188,7 +189,7 @@ , left: 0 , width: target.offsetWidth , height: target.offsetHeight - , zIndex: 1e6+'' // set max zIndex + , zIndex: 2147483647+'' // set max zIndex , position: 'absolute' }); diff --git a/lib/FileAPI.Form.js b/lib/FileAPI.Form.js index 3d974f75..b89bac37 100644 --- a/lib/FileAPI.Form.js +++ b/lib/FileAPI.Form.js @@ -58,7 +58,13 @@ }); this.each(function (file){ - next(file, data, queue, arg); + try{ + next(file, data, queue, arg); + } + catch( err ){ + api.log('FileAPI.Form._to: ' + err.message); + complete(err); + } }); queue.check(); diff --git a/lib/FileAPI.XHR.js b/lib/FileAPI.XHR.js index cb1e6994..d4f2472b 100644 --- a/lib/FileAPI.XHR.js +++ b/lib/FileAPI.XHR.js @@ -71,9 +71,14 @@ var _this = this, options = this.options; FormData.toData(function (data){ - // Start uploading - options.upload(options, _this); - _this._send.call(_this, options, data); + if( data instanceof Error ){ + _this.end(0, data.message); + } + else{ + // Start uploading + options.upload(options, _this); + _this._send.call(_this, options, data); + } }, options); }, @@ -171,7 +176,11 @@ // send _this.readyState = 2; // loaded - form.submit(); + try { + form.submit(); + } catch (err) { + api.log('iframe.error: ' + err); + } form = null; } else { @@ -189,9 +198,11 @@ url += (url.indexOf('?') < 0 ? "?" : "&") + data.params.join("&"); } - xhr.open('POST', url, true); + xhr.open(options.uploadMethod || 'POST', url, true); - if( api.withCredentials ){ + if (typeof options.uploadCredentials === 'boolean') { + xhr.withCredentials = options.uploadCredentials ? 'true' : null; + } else if( api.withCredentials ){ xhr.withCredentials = "true"; } diff --git a/lib/FileAPI.core.js b/lib/FileAPI.core.js index 7648b9be..14c7b467 100644 --- a/lib/FileAPI.core.js +++ b/lib/FileAPI.core.js @@ -11,6 +11,9 @@ document = window.document, doctype = document.doctype || {}, userAgent = window.navigator.userAgent, + safari = /safari\//i.test(userAgent) && !/chrome\//i.test(userAgent), + iemobile = /iemobile\//i.test(userAgent), + insecureChrome = !safari && /chrome\//i.test(userAgent) && window.location.protocol === 'http:', // https://github.com/blueimp/JavaScript-Load-Image/blob/master/load-image.js#L48 apiURL = (window.createObjectURL && window) || (window.URL && URL.revokeObjectURL && URL) || (window.webkitURL && webkitURL), @@ -25,12 +28,14 @@ jQuery = window.jQuery, html5 = !!(File && (FileReader && (window.Uint8Array || FormData || XMLHttpRequest.prototype.sendAsBinary))) - && !(/safari\//i.test(userAgent) && !/chrome\//i.test(userAgent) && /windows/i.test(userAgent)), // BugFix: https://github.com/mailru/FileAPI/issues/25 + && !(safari && /windows/i.test(userAgent) && !iemobile), // BugFix: https://github.com/mailru/FileAPI/issues/25 cors = html5 && ('withCredentials' in (new XMLHttpRequest)), chunked = html5 && !!Blob && !!(Blob.prototype.webkitSlice || Blob.prototype.mozSlice || Blob.prototype.slice), + normalize = ('' + ''.normalize).indexOf('[native code]') > 0, + // https://github.com/blueimp/JavaScript-Canvas-to-Blob dataURLtoBlob = window.dataURLtoBlob, @@ -42,6 +47,8 @@ _rdata = /^data:[^,]+,/, _toString = {}.toString, + _supportConsoleLog, + _supportConsoleLogApply, Math = window.Math, @@ -186,13 +193,14 @@ * FileAPI (core object) */ api = { - version: '2.0.10', + version: '2.1.1', cors: false, html5: true, media: false, formData: true, multiPassResize: true, + insecureChrome: insecureChrome, debug: false, pingUrl: false, @@ -246,8 +254,8 @@ }, log: function (){ - if( api.debug && window.console && console.log ){ - if( console.log.apply ){ + if( api.debug && _supportConsoleLog ){ + if( _supportConsoleLogApply ){ console.log.apply(console, arguments); } else { @@ -608,7 +616,7 @@ * @param {Boolean} [progress] */ readAsImage: function (file, fn, progress){ - if( api.isFile(file) ){ + if( api.isBlob(file) ){ if( apiURL ){ /** @namespace apiURL.createObjectURL */ var data = apiURL.createObjectURL(file); @@ -701,28 +709,84 @@ getDropFiles: function (evt, callback){ var files = [] + , all = [] + , items , dataTransfer = _getDataTransfer(evt) - , entrySupport = _isArray(dataTransfer.items) && dataTransfer.items[0] && _getAsEntry(dataTransfer.items[0]) - , queue = api.queue(function (){ callback(files); }) + , transFiles = dataTransfer.files + , transItems = dataTransfer.items + , entrySupport = _isArray(transItems) && transItems[0] && _getAsEntry(transItems[0]) + , queue = api.queue(function (){ callback(files, all); }) ; - _each((entrySupport ? dataTransfer.items : dataTransfer.files) || [], function (item){ + if( entrySupport ){ + if( normalize && transFiles ){ + var + i = transFiles.length + , file + , entry + ; + + items = new Array(i); + while( i-- ){ + file = transFiles[i]; + + try { + entry = _getAsEntry(transItems[i]); + } + catch( err ){ + api.log('[err] getDropFiles: ', err); + entry = null; + } + + if( _isEntry(entry) ){ + // OSX filesystems use Unicode Normalization Form D (NFD), + // and entry.file(…) can't read the files with the same names + if( entry.isDirectory || (entry.isFile && file.name == file.name.normalize('NFC')) ){ + items[i] = entry; + } + else { + items[i] = file; + } + } + else { + items[i] = file; + } + } + } + else { + items = transItems; + } + } + else { + items = transFiles; + } + + _each(items || [], function (item){ queue.inc(); try { - if( entrySupport ){ - _readEntryAsFiles(item, function (err, entryFiles){ + if( entrySupport && _isEntry(item) ){ + _readEntryAsFiles(item, function (err, entryFiles, allEntries){ if( err ){ api.log('[err] getDropFiles:', err); } else { files.push.apply(files, entryFiles); } + all.push.apply(all, allEntries); + queue.next(); }); } else { - _isRegularFile(item, function (yes){ - yes && files.push(item); + _isRegularFile(item, function (yes, err){ + if( yes ){ + files.push(item); + } + else { + item.error = err; + } + all.push(item); + queue.next(); }); } @@ -833,7 +897,7 @@ getInfo: function (file, fn){ var info = {}, readers = _infoReader.concat(); - if( api.isFile(file) ){ + if( api.isBlob(file) ){ (function _next(){ var reader = readers.shift(); if( reader ){ @@ -1213,7 +1277,13 @@ queue.inc(); file.toData(function (err, image){ - // @todo: error + // @todo: требует рефакторинга и обработки ошибки + if (file.file) { + image.type = file.file.type; + image.quality = file.matrix.quality; + filename = file.file && file.file.name; + } + filename = filename || (new Date).getTime()+'.png'; _addFile(image); @@ -1443,26 +1513,31 @@ function _isRegularFile(file, callback){ // http://stackoverflow.com/questions/8856628/detecting-folders-directories-in-javascript-filelist-objects - if( !file.type && (file.size % 4096) === 0 && (file.size <= 102400) ){ + if( !file.type && (safari || ((file.size % 4096) === 0 && (file.size <= 102400))) ){ if( FileReader ){ try { - var Reader = new FileReader(); + var reader = new FileReader(); - _one(Reader, _readerEvents, function (evt){ + _one(reader, _readerEvents, function (evt){ var isFile = evt.type != 'error'; - callback(isFile); if( isFile ){ - Reader.abort(); + if ( reader.readyState == null || reader.readyState === reader.LOADING ) { + reader.abort(); + } + callback(isFile); + } + else { + callback(false, reader.error); } }); - Reader.readAsDataURL(file); + reader.readAsDataURL(file); } catch( err ){ - callback(false); + callback(false, err); } } else { - callback(null); + callback(null, new Error('FileReader is not supported')); } } else { @@ -1471,6 +1546,11 @@ } + function _isEntry(item){ + return item && (item.isFile || item.isDirectory); + } + + function _getAsEntry(item){ var entry; if( item.getAsEntry ){ entry = item.getAsEntry(); } @@ -1482,34 +1562,52 @@ function _readEntryAsFiles(entry, callback){ if( !entry ){ // error - callback('invalid entry'); + var err = new Error('invalid entry'); + entry = new Object(entry); + entry.error = err; + callback(err.message, [], [entry]); } else if( entry.isFile ){ // Read as file - entry.file(function(file){ + entry.file(function (file){ // success file.fullPath = entry.fullPath; - callback(false, [file]); + callback(false, [file], [file]); }, function (err){ // error - callback('FileError.code: '+err.code); + entry.error = err; + callback('FileError.code: ' + err.code, [], [entry]); }); } else if( entry.isDirectory ){ - var reader = entry.createReader(), result = []; - - var onerror = function() { + var + reader = entry.createReader() + , firstAttempt = true + , files = [] + , all = [entry] + ; + + var onerror = function (err){ // error - callback('directory_reader'); + entry.error = err; + callback('DirectoryError.code: ' + err.code, files, all); }; - var ondone = function ondone(entries) { + var ondone = function ondone(entries){ + if( firstAttempt ){ + firstAttempt = false; + if( !entries.length ){ + entry.error = new Error('directory is empty'); + } + } + // success - if ( entries.length ) { + if( entries.length ){ api.afor(entries, function (next, entry){ - _readEntryAsFiles(entry, function (err, files){ + _readEntryAsFiles(entry, function (err, entryFiles, allEntries){ if( !err ){ - result = result.concat(files); + files = files.concat(entryFiles); } + all = all.concat(allEntries); if( next ){ next(); @@ -1521,7 +1619,7 @@ }); } else { - callback(false, result); + callback(false, files, all); } }; @@ -1644,11 +1742,12 @@ evt[preventDefault](); _type = 0; - onHover.call(evt[currentTarget], false, evt); - api.getDropFiles(evt, function (files){ - onDrop.call(evt[currentTarget], files, evt); + api.getDropFiles(evt, function (files, all){ + onDrop.call(evt[currentTarget], files, all, evt); }); + + onHover.call(evt[currentTarget], false, evt); }); } else { @@ -1702,7 +1801,13 @@ }); - // @configuration + // Configuration + try { + _supportConsoleLog = !!console.log; + _supportConsoleLogApply = !!console.log.apply; + } + catch (err) {} + if( !api.flashUrl ){ api.flashUrl = api.staticPath + 'FileAPI.flash.swf'; } if( !api.flashImageUrl ){ api.flashImageUrl = api.staticPath + 'FileAPI.flash.image.swf'; } if( !api.flashWebcamUrl ){ api.flashWebcamUrl = api.staticPath + 'FileAPI.flash.camera.swf'; } diff --git a/node/file-api.js b/node/file-api.js new file mode 100644 index 00000000..5d9fd6c5 --- /dev/null +++ b/node/file-api.js @@ -0,0 +1,62 @@ +var fs = require('fs'); +var qs = require('qs'); +var imageSize = require('image-size'); + +function convertToBase64(buffer, mimetype) { + return 'data:' + mimetype + ';base64,' + buffer.toString('base64'); +} + +function fileApi() { + return function (req, res, next) { + var queryString = ''; + + req.files = {}; + req.images = {}; + + req.busboy.on('file', function (fieldname, file, filename, encoding, mimetype) { + var buffersArray = []; + + file.on('data', function (data) { + buffersArray.push(data); + }); + + file.on('end', function () { + var bufferResult = Buffer.concat(buffersArray); + var fileObj = { + name: filename, + type: mimetype, + mime: mimetype, + size: bufferResult.length, + dataURL: convertToBase64(bufferResult, mimetype) + }; + + req.files[fieldname] = fileObj; + + if (mimetype.indexOf('image/') === 0) { + fs.writeFileSync(filename, bufferResult); + + var size = imageSize(filename); + + fileObj.width = size.width; + fileObj.height = size.height; + + req.images[fieldname] = fileObj; + + fs.unlinkSync(filename); + } + }); + }); + + req.busboy.on('field', function (key, value) { + queryString += encodeURIComponent(key) + '=' + encodeURIComponent(value) + '&'; + }); + + req.busboy.on('finish', function () { + req.body = qs.parse(queryString); + + next(); + }); + }; +} + +module.exports = fileApi; diff --git a/node/server.js b/node/server.js new file mode 100644 index 00000000..119dddae --- /dev/null +++ b/node/server.js @@ -0,0 +1,59 @@ +var express = require('express'); +var busboy = require('connect-busboy'); +var fileApi = require('./file-api'); +var app = express(); + +app.use(express.static('.', {index: 'index.html'})); + +app.use(function (req, res, next) { + // Enable CORS for non static files + var origin = req.get('Origin'); + + if (origin) { + res.set({ + 'Access-Control-Allow-Origin': origin, + 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS', + 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Range, Content-Disposition, Content-Type, X-Foo, X-Rnd', + 'Access-Control-Allow-Credentials': 'true' + }); + } + next(); +}); + +var uploadPath = '/upload'; + +app.options(uploadPath, function (req, res) { + res.end(); +}); + +app.post( + uploadPath, + busboy({immediate: true}), // parse post data + fileApi(), // prepare req.body, req.files and req.images + function (req, res) { + var jsonp = req.query.callback || null; + + res[jsonp ? 'jsonp' : 'json']({ + status: 200, + statusText: 'OK', + images: req.images, + data: { + HEADERS: req.headers, + _REQUEST: req.body, + _FILES: req.files + } + }); + } +); + +// Export +module.exports.createServer = function (port, callback) { + var server = app.listen(port, function () { + var host = server.address().address; + var port = server.address().port; + + console.log('Test server listening at http://%s:%s', host, port); + + callback(server); + }); +}; diff --git a/package.json b/package.json index ae336561..8f4707c9 100644 --- a/package.json +++ b/package.json @@ -1,27 +1,43 @@ { "name": "fileapi", "exportName": "FileAPI", - "version": "2.0.10", + "version": "2.2.0", "devDependencies": { - "grunt": "~0.4.5", - "grunt-version": "~0.3.0", - "grunt-contrib-jshint": "~0.10.0", + "connect-busboy": "~0.0.2", + "eventemitter2": "~0.4.13", + "express": "~4.12.3", + "flex-sdk": "^4.6.0-0", + "grunt": "^0.4.5", + "grunt-cli": "^1.3.2", + "grunt-contrib-compress": "~0.9.1", "grunt-contrib-concat": "~0.4.0", + "grunt-contrib-connect": "~0.8.0", + "grunt-contrib-jshint": "~0.10.0", "grunt-contrib-uglify": "~0.5.0", "grunt-contrib-watch": "~0.6.1", - "grunt-contrib-connect": "~0.8.0", - "eventemitter2": "~0.4.13", - "semver": "~2.3.1 ", - "temporary": "~0.0.8", + "grunt-curl": "~2.0.2", + "grunt-mxmlc": "~0.5.2", + "grunt-version": "~0.3.0", + "image-size": "~0.3.5", "phantomjs": "~1.9.7-9", - "grunt-curl": "~2.0.2", - "grunt-mxmlc": "~0.5.1", - "grunt-contrib-compress": "~0.9.1" + "qs": "~2.4.1", + "semver": "~5.0.0", + "temporary": "~0.0.8" }, + "peerDependencies": {}, "description": "FileAPI — a set of javascript tools for working with files. Multiupload, drag'n'drop and chunked file upload. Images: crop, resize and auto orientation by EXIF.", "main": "dist/FileAPI.js", + "files": [ + "dist", + "plugins", + "*.js" + ], + "jam": { + "name": "FileAPI" + }, "scripts": { - "test": "grunt tests --verbose" + "test": "grunt tests --verbose", + "build": "grunt build" }, "repository": { "type": "git", @@ -38,7 +54,8 @@ "contributors": [ "Vladimir Demidov ", "Ilya Lebedev ", - "Mikhail Bezoyan " + "Mikhail Bezoyan " ], - "license": "BSD" + "license": "BSD", + "dependencies": {} } diff --git a/tests/files/big.jpg b/tests/files/big.jpg new file mode 100644 index 00000000..d0dc3b17 Binary files /dev/null and b/tests/files/big.jpg differ diff --git a/tests/index.html b/tests/index.html index e7f2ea70..5cdabe36 100644 --- a/tests/index.html +++ b/tests/index.html @@ -33,7 +33,7 @@
-
1px.gif --
+
1px.gif --
big.jpg --
hello.txt --
image.jpg --
diff --git a/tests/tests.js b/tests/tests.js index 9172eac3..4352c815 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -14,6 +14,7 @@ module('FileAPI'); } + var controllerUrl = 'http://127.0.0.1:8000/upload'; var uploadForm = document.forms.upload; var base64_1px_gif = 'R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=='; var browser = (navigator.userAgent.match(/(phantomjs|safari|firefox|chrome)/i) || ['', 'chrome'])[1].toLowerCase(); @@ -136,9 +137,10 @@ module('FileAPI'); return fail; } + console.log('\nStart testing\n'); test('1px.gif', function (){ - var file = FileAPI.getFiles(uploadForm['1px.gif'])[0]; + var file = FileAPI.getFiles(uploadForm['1px_gif'])[0]; // File checkFile(file, '1px.gif', 'image/gif', 34); @@ -205,23 +207,20 @@ module('FileAPI'); }); stop(); - FileAPI.upload({ - url: 'http://rubaxa.org/FileAPI/server/ctrl.php', - files: { image: file }, - imageTransform: { - width: 1024, - height: 768, - type: 'image/jpeg' - }, - complete: function (err, res){ - start(); - } - }); - + FileAPI.upload({ + url: controllerUrl, + files: { image: file }, + imageTransform: { + width: 1024, + height: 768, + type: 'image/jpeg' + }, + complete: function (err, res){ + start(); + } + }); }); -// if (false) { - test('hello.txt', function (){ var file = FileAPI.getFiles(uploadForm['hello.txt'])[0]; @@ -238,7 +237,6 @@ module('FileAPI'); } }); - test('image.jpg', function (){ var file = FileAPI.getFiles(uploadForm['image.jpg'])[0]; @@ -259,7 +257,6 @@ module('FileAPI'); }); }); - test('filterFiles', function (){ var files = FileAPI.getFiles(uploadForm['multiple']); @@ -279,14 +276,11 @@ module('FileAPI'); }) }); - - - test('upload without files', function (){ stop(); FileAPI.upload({ - url: 'http://rubaxa.org/FileAPI/server/ctrl.php', + url: controllerUrl, data: { str: 'foo', num: 1, array: [1, 2, 3], object: { foo: 'bar' } }, headers: { 'x-foo': 'bar' }, complete: function (err, xhr){ @@ -294,10 +288,10 @@ module('FileAPI'); var headers = err ? err : FileAPI.parseJSON(xhr.responseText).data.HEADERS; start(); - ok(!err, 'upload done') + ok(!err, 'upload done'); equal(res.str, 'foo', 'string'); equal(res.num, '1', 'number'); - equal(headers['X-Foo'], 'bar', 'headers.X-Foo'); + equal(headers['x-foo'], 'bar', 'headers.x-foo'); if( !FileAPI.html5 || !FileAPI.support.html5 ){ deepEqual(res.array, { "0": '1', "1": '2', "2": '3' }, 'array'); @@ -311,18 +305,16 @@ module('FileAPI'); }) }); - - test('upload input', function (){ var rnd = Math.random(); expect(15); stop(); FileAPI.upload({ - url: 'http://rubaxa.org/FileAPI/server/ctrl.php', + url: controllerUrl, data: { foo: 'bar' }, headers: { 'x-foo': 'bar', 'x-rnd': rnd }, - files: uploadForm['1px.gif'], + files: uploadForm['1px_gif'], upload: function (){ ok(true, 'upload event'); }, @@ -339,13 +331,15 @@ module('FileAPI'); equal(res.data._REQUEST.foo, 'bar'); equal(res.data._REQUEST.bar, 'qux'); - equal(res.data.HEADERS['X-Foo'], 'bar', 'headers.X-Foo'); - equal(res.data.HEADERS['X-Rnd'], rnd, 'headers.X-Rnd'); + equal(res.data.HEADERS['x-foo'], 'bar', 'headers.x-foo'); + equal(res.data.HEADERS['x-rnd'], rnd, 'headers.x-rnd'); if( res.data._FILES['1px_gif'] ){ var type = res.data._FILES['1px_gif'].type; equal(res.data._FILES['1px_gif'].name, '1px.gif', 'file.name'); equal(type, /application/.test(type) ? 'application/octet-stream' : 'image/gif', 'file.type'); + } else { + ok(false, "res.data._FILES['1px_gif'] not found"); } if( res.images['1px_gif'] ){ @@ -353,6 +347,8 @@ module('FileAPI'); equal(res.images['1px_gif'].mime, 'image/gif', 'mime'); equal(res.images['1px_gif'].width, 1, 'width'); equal(res.images['1px_gif'].height, 1, 'height'); + } else { + ok(false, "res.images['1px_gif'] not found"); } }, complete: function (err, xhr){ @@ -362,14 +358,12 @@ module('FileAPI'); }); }); - - test('upload file', function (){ var _progressFail = false, _progress = 0; stop(); FileAPI.upload({ - url: 'http://rubaxa.org/FileAPI/server/ctrl.php', + url: controllerUrl, files: { text: FileAPI.getFiles(uploadForm['hello.txt']) }, progress: function (evt){ _progressFail = _progressFail || _checkProgressEvent(evt); @@ -389,8 +383,6 @@ module('FileAPI'); }); }); - - test('multiupload', function (){ stop(); var @@ -402,7 +394,7 @@ module('FileAPI'); ; FileAPI.upload({ - url: 'http://rubaxa.org/FileAPI/server/ctrl.php', + url: controllerUrl, files: uploadForm['multiple'], fileupload: function (){ _start++; @@ -434,7 +426,6 @@ module('FileAPI'); }); }); - FileAPI.html5 && test('upload FileAPI.Image', function (){ var file = FileAPI.getFiles(uploadForm['dino.png'])[0]; var image = FileAPI.Image(file).rotate(90+360).preview(100); @@ -447,7 +438,7 @@ module('FileAPI'); stop(); FileAPI.upload({ - url: 'http://rubaxa.org/FileAPI/server/ctrl.php', + url: controllerUrl, headers: { 'x-foo': 'bar' }, files: { image: image }, progress: function (evt){ @@ -477,7 +468,7 @@ module('FileAPI'); equal(err, _filecompleteErr, 'filecomplete.err'); equal(res.responseText, _filecomplete, 'filecomplete.response'); - equal(json.data.HEADERS['X-Foo'], 'bar', 'X-Foo'); + equal(json.data.HEADERS['x-foo'], 'bar', 'x-foo'); imageEqual(json.images.image.dataURL, 'files/samples/'+browser+'-dino-90deg-100x100.png?1', 'dino 90deg 100x100', function (){ start(); @@ -486,8 +477,6 @@ module('FileAPI'); }); }); - - FileAPI.html5 && test('upload + imageTransform (min, max, preview)', function (){ var file = FileAPI.getFiles(uploadForm['image.jpg'])[0]; var queue = FileAPI.queue(start); @@ -497,7 +486,7 @@ module('FileAPI'); // strategy: 'min' queue.inc(); FileAPI.upload({ - url: 'http://rubaxa.org/FileAPI/server/ctrl.php', + url: controllerUrl, files: { image: file }, imageTransform: { width: 100, height: 100, strategy: 'min' }, complete: function (err, res){ @@ -511,7 +500,7 @@ module('FileAPI'); // strategy: 'max' queue.inc(); FileAPI.upload({ - url: 'http://rubaxa.org/FileAPI/server/ctrl.php', + url: controllerUrl, files: { image: file }, imageTransform: { width: 100, height: 100, strategy: 'max' }, complete: function (err, res){ @@ -525,7 +514,7 @@ module('FileAPI'); // strategy: 'height' queue.inc(); FileAPI.upload({ - url: 'http://rubaxa.org/FileAPI/server/ctrl.php', + url: controllerUrl, files: { image: file }, imageTransform: { width: 100, height: 100, strategy: 'height' }, complete: function (err, res){ @@ -539,7 +528,7 @@ module('FileAPI'); // strategy: 'width' queue.inc(); FileAPI.upload({ - url: 'http://rubaxa.org/FileAPI/server/ctrl.php', + url: controllerUrl, files: { image: file }, imageTransform: { width: 100, height: 100, strategy: 'width' }, complete: function (err, res){ @@ -553,7 +542,7 @@ module('FileAPI'); // preview queue.inc(); FileAPI.upload({ - url: 'http://rubaxa.org/FileAPI/server/ctrl.php', + url: controllerUrl, files: { image: file }, imageTransform: { width: 100, height: 100, rotate: 'auto', preview: true }, complete: function (err, res){ @@ -566,7 +555,6 @@ module('FileAPI'); }); }); - test('upload + autoOrientation', function (){ var file = FileAPI.getFiles(uploadForm['image.jpg'])[0]; var queue = FileAPI.queue(start); @@ -581,7 +569,7 @@ module('FileAPI'); queue.inc(); FileAPI.upload({ - url: 'http://rubaxa.org/FileAPI/server/ctrl.php', + url: controllerUrl, files: { image: file }, imageAutoOrientation: true, complete: check.bind('imageAutoOrientation') @@ -589,7 +577,7 @@ module('FileAPI'); queue.inc(); FileAPI.upload({ - url: 'http://rubaxa.org/FileAPI/server/ctrl.php', + url: controllerUrl, files: { image: file }, imageTransform: { rotate: 'auto' }, complete: check.bind('imageTransform.rotate.auto') @@ -597,13 +585,12 @@ module('FileAPI'); queue.inc(); FileAPI.upload({ - url: 'http://rubaxa.org/FileAPI/server/ctrl.php', + url: controllerUrl, files: { image: FileAPI.Image(file).rotate('auto') }, complete: check.bind('FileAPI.Image.fn.rotate.auto') }); }); - FileAPI.html5 && test('upload + CamanJS', function (){ stop(); FileAPI.Image(FileAPI.getFiles(uploadForm['dino.png'])[0]) @@ -613,7 +600,7 @@ module('FileAPI'); equal(canvas.nodeName.toLowerCase(), 'canvas'); FileAPI.upload({ - url: 'http://rubaxa.org/FileAPI/server/ctrl.php', + url: controllerUrl, files: { image: { name: 'my-file', @@ -631,13 +618,12 @@ module('FileAPI'); ; }); - - FileAPI.html5 && test('upload + multi imageTransform', function (){ + 0 && FileAPI.html5 && test('upload + multi imageTransform', function (){ var file = FileAPI.getFiles(uploadForm['dino.png'])[0]; stop(); FileAPI.upload({ - url: 'http://rubaxa.org/FileAPI/server/ctrl.php', + url: controllerUrl, files: { image: file }, imageTransform: { 'jpeg': { @@ -668,13 +654,12 @@ module('FileAPI'); }); }); - FileAPI.html5 && test('upload + imageTransform with postName', function (){ var file = FileAPI.getFiles(uploadForm['dino.png'])[0]; stop(); FileAPI.upload({ - url: 'http://rubaxa.org/FileAPI/server/ctrl.php', + url: controllerUrl, files: { image: file }, imageTransform: { '180deg': { @@ -695,8 +680,7 @@ module('FileAPI'); }); }); - - test('iframe', function (){ + 0 && test('iframe', function (){ var html5 = FileAPI.support.html5; var queue = FileAPI.queue(function (){ start(); @@ -709,7 +693,7 @@ module('FileAPI'); // default callback queue.inc(); FileAPI.upload({ - url: 'http://rubaxa.org/FileAPI/server/ctrl.php', + url: controllerUrl, complete: function (err, xhr){ var json = FileAPI.parseJSON(xhr.responseText); equal(json.jsonp, 'callback', 'default'); @@ -739,7 +723,6 @@ module('FileAPI'); }); }); - FileAPI.html5 && test('WebCam', function (){ stop(); FileAPI.Camera.publish(document.getElementById('web-cam'), function (err, cam){ @@ -751,7 +734,7 @@ module('FileAPI'); var shot = cam.shot(); FileAPI.upload({ - url: 'http://rubaxa.org/FileAPI/server/ctrl.php', + url: controllerUrl, files: { shot: shot }, complete: function (err, res){ var res = FileAPI.parseJSON(res.responseText); @@ -764,5 +747,5 @@ module('FileAPI'); } }); }); -// } + })(); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy