From 7e1762d879fc8b360e877a5828deef42eb14cc3b Mon Sep 17 00:00:00 2001
From: hanbaoshan <hanbaoshan@aiotlink.com>
Date: 星期三, 28 十月 2020 18:28:40 +0800
Subject: [PATCH] 引入simple-uploader源文件并更新assignBrowse方法,标注页面更新,首页分页器样式更新

---
 src/pages/labelMark/components/RightSide.vue                      |  271 ++++++--
 src/pages/desktop/index/components/ToolsEntry.vue                 |    9 
 src/components/subComponents/FileUpload/common/uploader-simple.js | 1612 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/components/subComponents/FileUpload/uploader.vue              |    4 
 src/pages/labelMark/index/App.vue                                 |    2 
 src/components/subComponents/FileUpload/btn.vue                   |    5 
 src/pages/cameraAccess/components/DataStackInfo.vue               |   10 
 7 files changed, 1,826 insertions(+), 87 deletions(-)

diff --git a/src/components/subComponents/FileUpload/btn.vue b/src/components/subComponents/FileUpload/btn.vue
index d624a23..750ad79 100644
--- a/src/components/subComponents/FileUpload/btn.vue
+++ b/src/components/subComponents/FileUpload/btn.vue
@@ -33,7 +33,10 @@
     attrs: {
       handler(n, o) {
         //this.$nextTick(() => {
-          this.uploader.uploader.assignBrowse(this.$refs.btn, this.directory, this.single, n)
+          if(n){
+            this.uploader.uploader.assignBrowse(this.$refs.btn, this.directory, this.single, n)
+          }
+          
         //})
       },
       deep: true
diff --git a/src/components/subComponents/FileUpload/common/uploader-simple.js b/src/components/subComponents/FileUpload/common/uploader-simple.js
new file mode 100644
index 0000000..b0a0d16
--- /dev/null
+++ b/src/components/subComponents/FileUpload/common/uploader-simple.js
@@ -0,0 +1,1612 @@
+/*!
+ * Uploader - Uploader library implements html5 file upload and provides multiple simultaneous, stable, fault tolerant and resumable uploads
+ * @version v0.5.4
+ * @author dolymood <dolymood@gmail.com>
+ * @link https://github.com/simple-uploader/Uploader
+ * @license MIT
+ */
+!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Uploader=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
+    var utils = _dereq_('./utils')
+    
+    function Chunk (uploader, file, offset) {
+      utils.defineNonEnumerable(this, 'uploader', uploader)
+      utils.defineNonEnumerable(this, 'file', file)
+      utils.defineNonEnumerable(this, 'bytes', null)
+      this.offset = offset
+      this.tested = false
+      this.retries = 0
+      this.pendingRetry = false
+      this.preprocessState = 0
+      this.readState = 0
+      this.loaded = 0
+      this.total = 0
+      this.chunkSize = this.uploader.opts.chunkSize
+      this.startByte = this.offset * this.chunkSize
+      this.endByte = this.computeEndByte()
+      this.xhr = null
+    }
+    
+    var STATUS = Chunk.STATUS = {
+      PENDING: 'pending',
+      UPLOADING: 'uploading',
+      READING: 'reading',
+      SUCCESS: 'success',
+      ERROR: 'error',
+      COMPLETE: 'complete',
+      PROGRESS: 'progress',
+      RETRY: 'retry'
+    }
+    
+    utils.extend(Chunk.prototype, {
+    
+      _event: function (evt, args) {
+        args = utils.toArray(arguments)
+        args.unshift(this)
+        this.file._chunkEvent.apply(this.file, args)
+      },
+    
+      computeEndByte: function () {
+        var endByte = Math.min(this.file.size, (this.offset + 1) * this.chunkSize)
+        if (this.file.size - endByte < this.chunkSize && !this.uploader.opts.forceChunkSize) {
+          // The last chunk will be bigger than the chunk size,
+          // but less than 2 * this.chunkSize
+          endByte = this.file.size
+        }
+        return endByte
+      },
+    
+      getParams: function () {
+        return {
+          chunkNumber: this.offset + 1,
+          chunkSize: this.uploader.opts.chunkSize,
+          currentChunkSize: this.endByte - this.startByte,
+          totalSize: this.file.size,
+          identifier: this.file.uniqueIdentifier,
+          filename: this.file.name,
+          relativePath: this.file.relativePath,
+          totalChunks: this.file.chunks.length
+        }
+      },
+    
+      getTarget: function (target, params) {
+        if (!params.length) {
+          return target
+        }
+        if (target.indexOf('?') < 0) {
+          target += '?'
+        } else {
+          target += '&'
+        }
+        return target + params.join('&')
+      },
+    
+      test: function () {
+        this.xhr = new XMLHttpRequest()
+        this.xhr.addEventListener('load', testHandler, false)
+        this.xhr.addEventListener('error', testHandler, false)
+        var testMethod = utils.evalOpts(this.uploader.opts.testMethod, this.file, this)
+        var data = this.prepareXhrRequest(testMethod, true)
+        this.xhr.send(data)
+    
+        var $ = this
+        function testHandler (event) {
+          var status = $.status(true)
+          if (status === STATUS.ERROR) {
+            $._event(status, $.message())
+            $.uploader.uploadNextChunk()
+          } else if (status === STATUS.SUCCESS) {
+            $._event(status, $.message())
+            $.tested = true
+          } else if (!$.file.paused) {
+            // Error might be caused by file pause method
+            // Chunks does not exist on the server side
+            $.tested = true
+            $.send()
+          }
+        }
+      },
+    
+      preprocessFinished: function () {
+        // Compute the endByte after the preprocess function to allow an
+        // implementer of preprocess to set the fileObj size
+        this.endByte = this.computeEndByte()
+        this.preprocessState = 2
+        this.send()
+      },
+    
+      readFinished: function (bytes) {
+        this.readState = 2
+        this.bytes = bytes
+        this.send()
+      },
+    
+      send: function () {
+        var preprocess = this.uploader.opts.preprocess
+        var read = this.uploader.opts.readFileFn
+        if (utils.isFunction(preprocess)) {
+          switch (this.preprocessState) {
+            case 0:
+              this.preprocessState = 1
+              preprocess(this)
+              return
+            case 1:
+              return
+          }
+        }
+        switch (this.readState) {
+          case 0:
+            this.readState = 1
+            read(this.file, this.file.fileType, this.startByte, this.endByte, this)
+            return
+          case 1:
+            return
+        }
+        if (this.uploader.opts.testChunks && !this.tested) {
+          this.test()
+          return
+        }
+    
+        this.loaded = 0
+        this.total = 0
+        this.pendingRetry = false
+    
+        // Set up request and listen for event
+        this.xhr = new XMLHttpRequest()
+        this.xhr.upload.addEventListener('progress', progressHandler, false)
+        this.xhr.addEventListener('load', doneHandler, false)
+        this.xhr.addEventListener('error', doneHandler, false)
+    
+        var uploadMethod = utils.evalOpts(this.uploader.opts.uploadMethod, this.file, this)
+        var data = this.prepareXhrRequest(uploadMethod, false, this.uploader.opts.method, this.bytes)
+        this.xhr.send(data)
+    
+        var $ = this
+        function progressHandler (event) {
+          if (event.lengthComputable) {
+            $.loaded = event.loaded
+            $.total = event.total
+          }
+          $._event(STATUS.PROGRESS, event)
+        }
+    
+        function doneHandler (event) {
+          var msg = $.message()
+          $.processingResponse = true
+          $.uploader.opts.processResponse(msg, function (err, res) {
+            $.processingResponse = false
+            if (!$.xhr) {
+              return
+            }
+            $.processedState = {
+              err: err,
+              res: res
+            }
+            var status = $.status()
+            if (status === STATUS.SUCCESS || status === STATUS.ERROR) {
+              delete this.data
+              $._event(status, res)
+              status === STATUS.ERROR && $.uploader.uploadNextChunk()
+            } else {
+              $._event(STATUS.RETRY, res)
+              $.pendingRetry = true
+              $.abort()
+              $.retries++
+              var retryInterval = $.uploader.opts.chunkRetryInterval
+              if (retryInterval !== null) {
+                setTimeout(function () {
+                  $.send()
+                }, retryInterval)
+              } else {
+                $.send()
+              }
+            }
+          }, $.file, $)
+        }
+      },
+    
+      abort: function () {
+        var xhr = this.xhr
+        this.xhr = null
+        this.processingResponse = false
+        this.processedState = null
+        if (xhr) {
+          xhr.abort()
+        }
+      },
+    
+      status: function (isTest) {
+        if (this.readState === 1) {
+          return STATUS.READING
+        } else if (this.pendingRetry || this.preprocessState === 1) {
+          // if pending retry then that's effectively the same as actively uploading,
+          // there might just be a slight delay before the retry starts
+          return STATUS.UPLOADING
+        } else if (!this.xhr) {
+          return STATUS.PENDING
+        } else if (this.xhr.readyState < 4 || this.processingResponse) {
+          // Status is really 'OPENED', 'HEADERS_RECEIVED'
+          // or 'LOADING' - meaning that stuff is happening
+          return STATUS.UPLOADING
+        } else {
+          var _status
+          if (this.uploader.opts.successStatuses.indexOf(this.xhr.status) > -1) {
+            // HTTP 200, perfect
+            // HTTP 202 Accepted - The request has been accepted for processing, but the processing has not been completed.
+            _status = STATUS.SUCCESS
+          } else if (this.uploader.opts.permanentErrors.indexOf(this.xhr.status) > -1 ||
+              !isTest && this.retries >= this.uploader.opts.maxChunkRetries) {
+            // HTTP 415/500/501, permanent error
+            _status = STATUS.ERROR
+          } else {
+            // this should never happen, but we'll reset and queue a retry
+            // a likely case for this would be 503 service unavailable
+            this.abort()
+            _status = STATUS.PENDING
+          }
+          var processedState = this.processedState
+          if (processedState && processedState.err) {
+            _status = STATUS.ERROR
+          }
+          return _status
+        }
+      },
+    
+      message: function () {
+        return this.xhr ? this.xhr.responseText : ''
+      },
+    
+      progress: function () {
+        if (this.pendingRetry) {
+          return 0
+        }
+        var s = this.status()
+        if (s === STATUS.SUCCESS || s === STATUS.ERROR) {
+          return 1
+        } else if (s === STATUS.PENDING) {
+          return 0
+        } else {
+          return this.total > 0 ? this.loaded / this.total : 0
+        }
+      },
+    
+      sizeUploaded: function () {
+        var size = this.endByte - this.startByte
+        // can't return only chunk.loaded value, because it is bigger than chunk size
+        if (this.status() !== STATUS.SUCCESS) {
+          size = this.progress() * size
+        }
+        return size
+      },
+    
+      prepareXhrRequest: function (method, isTest, paramsMethod, blob) {
+        // Add data from the query options
+        var query = utils.evalOpts(this.uploader.opts.query, this.file, this, isTest)
+        query = utils.extend(this.getParams(), query)
+    
+        // processParams
+        query = this.uploader.opts.processParams(query, this.file, this, isTest)
+    
+        var target = utils.evalOpts(this.uploader.opts.target, this.file, this, isTest)
+        var data = null
+        if (method === 'GET' || paramsMethod === 'octet') {
+          // Add data from the query options
+          var params = []
+          utils.each(query, function (v, k) {
+            params.push([encodeURIComponent(k), encodeURIComponent(v)].join('='))
+          })
+          target = this.getTarget(target, params)
+          data = blob || null
+        } else {
+          // Add data from the query options
+          data = new FormData()
+          utils.each(query, function (v, k) {
+            data.append(k, v)
+          })
+          if (typeof blob !== 'undefined') {
+            data.append(this.uploader.opts.fileParameterName, blob, this.file.name)
+          }
+        }
+    
+        this.xhr.open(method, target, true)
+        this.xhr.withCredentials = this.uploader.opts.withCredentials
+    
+        // Add data from header options
+        utils.each(utils.evalOpts(this.uploader.opts.headers, this.file, this, isTest), function (v, k) {
+          this.xhr.setRequestHeader(k, v)
+        }, this)
+    
+        return data
+      }
+    
+    })
+    
+    module.exports = Chunk
+    
+    },{"./utils":5}],2:[function(_dereq_,module,exports){
+    var each = _dereq_('./utils').each
+    
+    var event = {
+    
+      _eventData: null,
+    
+      on: function (name, func) {
+        if (!this._eventData) this._eventData = {}
+        if (!this._eventData[name]) this._eventData[name] = []
+        var listened = false
+        each(this._eventData[name], function (fuc) {
+          if (fuc === func) {
+            listened = true
+            return false
+          }
+        })
+        if (!listened) {
+          this._eventData[name].push(func)
+        }
+      },
+    
+      off: function (name, func) {
+        if (!this._eventData) this._eventData = {}
+        if (!this._eventData[name] || !this._eventData[name].length) return
+        if (func) {
+          each(this._eventData[name], function (fuc, i) {
+            if (fuc === func) {
+              this._eventData[name].splice(i, 1)
+              return false
+            }
+          }, this)
+        } else {
+          this._eventData[name] = []
+        }
+      },
+    
+      trigger: function (name) {
+        if (!this._eventData) this._eventData = {}
+        if (!this._eventData[name]) return true
+        var args = this._eventData[name].slice.call(arguments, 1)
+        var preventDefault = false
+        each(this._eventData[name], function (fuc) {
+          preventDefault = fuc.apply(this, args) === false || preventDefault
+        }, this)
+        return !preventDefault
+      }
+    }
+    
+    module.exports = event
+    
+    },{"./utils":5}],3:[function(_dereq_,module,exports){
+    var utils = _dereq_('./utils')
+    var event = _dereq_('./event')
+    var File = _dereq_('./file')
+    var Chunk = _dereq_('./chunk')
+    
+    var version = '0.5.4'
+    
+    var isServer = typeof window === 'undefined'
+    
+    // ie10+
+    var ie10plus = isServer ? false : window.navigator.msPointerEnabled
+    var support = (function () {
+      if (isServer) {
+        return false
+      }
+      var sliceName = 'slice'
+      var _support = utils.isDefined(window.File) && utils.isDefined(window.Blob) &&
+                    utils.isDefined(window.FileList)
+      var bproto = null
+      if (_support) {
+        bproto = window.Blob.prototype
+        utils.each(['slice', 'webkitSlice', 'mozSlice'], function (n) {
+          if (bproto[n]) {
+            sliceName = n
+            return false
+          }
+        })
+        _support = !!bproto[sliceName]
+      }
+      if (_support) Uploader.sliceName = sliceName
+      bproto = null
+      return _support
+    })()
+    
+    var supportDirectory = (function () {
+      if (isServer) {
+        return false
+      }
+      var input = window.document.createElement('input')
+      input.type = 'file'
+      var sd = 'webkitdirectory' in input || 'directory' in input
+      input = null
+      return sd
+    })()
+    
+    function Uploader (opts) {
+      this.support = support
+      /* istanbul ignore if */
+      if (!this.support) {
+        return
+      }
+      this.supportDirectory = supportDirectory
+      utils.defineNonEnumerable(this, 'filePaths', {})
+      this.opts = utils.extend({}, Uploader.defaults, opts || {})
+    
+      this.preventEvent = utils.bind(this._preventEvent, this)
+    
+      File.call(this, this)
+    }
+    
+    /**
+     * Default read function using the webAPI
+     *
+     * @function webAPIFileRead(fileObj, fileType, startByte, endByte, chunk)
+     *
+     */
+    var webAPIFileRead = function (fileObj, fileType, startByte, endByte, chunk) {
+      chunk.readFinished(fileObj.file[Uploader.sliceName](startByte, endByte, fileType))
+    }
+    
+    Uploader.version = version
+    
+    Uploader.defaults = {
+      chunkSize: 1024 * 1024,
+      forceChunkSize: false,
+      simultaneousUploads: 3,
+      singleFile: false,
+      fileParameterName: 'file',
+      progressCallbacksInterval: 500,
+      speedSmoothingFactor: 0.1,
+      query: {},
+      headers: {},
+      withCredentials: false,
+      preprocess: null,
+      method: 'multipart',
+      testMethod: 'GET',
+      uploadMethod: 'POST',
+      prioritizeFirstAndLastChunk: false,
+      allowDuplicateUploads: false,
+      target: '/',
+      testChunks: true,
+      generateUniqueIdentifier: null,
+      maxChunkRetries: 0,
+      chunkRetryInterval: null,
+      permanentErrors: [404, 415, 500, 501],
+      successStatuses: [200, 201, 202],
+      onDropStopPropagation: false,
+      initFileFn: null,
+      readFileFn: webAPIFileRead,
+      checkChunkUploadedByResponse: null,
+      initialPaused: false,
+      processResponse: function (response, cb) {
+        cb(null, response)
+      },
+      processParams: function (params) {
+        return params
+      }
+    }
+    
+    Uploader.utils = utils
+    Uploader.event = event
+    Uploader.File = File
+    Uploader.Chunk = Chunk
+    
+    // inherit file
+    Uploader.prototype = utils.extend({}, File.prototype)
+    // inherit event
+    utils.extend(Uploader.prototype, event)
+    utils.extend(Uploader.prototype, {
+    
+      constructor: Uploader,
+    
+      _trigger: function (name) {
+        var args = utils.toArray(arguments)
+        var preventDefault = !this.trigger.apply(this, arguments)
+        if (name !== 'catchAll') {
+          args.unshift('catchAll')
+          preventDefault = !this.trigger.apply(this, args) || preventDefault
+        }
+        return !preventDefault
+      },
+    
+      _triggerAsync: function () {
+        var args = arguments
+        utils.nextTick(function () {
+          this._trigger.apply(this, args)
+        }, this)
+      },
+    
+      addFiles: function (files, evt) {
+        var _files = []
+        var oldFileListLen = this.fileList.length
+        utils.each(files, function (file) {
+          // Uploading empty file IE10/IE11 hangs indefinitely
+          // Directories have size `0` and name `.`
+          // Ignore already added files if opts.allowDuplicateUploads is set to false
+          if ((!ie10plus || ie10plus && file.size > 0) && !(file.size % 4096 === 0 && (file.name === '.' || file.fileName === '.'))) {
+            var uniqueIdentifier = this.generateUniqueIdentifier(file)
+            if (this.opts.allowDuplicateUploads || !this.getFromUniqueIdentifier(uniqueIdentifier)) {
+              var _file = new File(this, file, this)
+              _file.uniqueIdentifier = uniqueIdentifier
+              if (this._trigger('fileAdded', _file, evt)) {
+                _files.push(_file)
+              } else {
+                File.prototype.removeFile.call(this, _file)
+              }
+            }
+          }
+        }, this)
+        // get new fileList
+        var newFileList = this.fileList.slice(oldFileListLen)
+        if (this._trigger('filesAdded', _files, newFileList, evt)) {
+          utils.each(_files, function (file) {
+            if (this.opts.singleFile && this.files.length > 0) {
+              this.removeFile(this.files[0])
+            }
+            this.files.push(file)
+          }, this)
+          this._trigger('filesSubmitted', _files, newFileList, evt)
+        } else {
+          utils.each(newFileList, function (file) {
+            File.prototype.removeFile.call(this, file)
+          }, this)
+        }
+      },
+    
+      addFile: function (file, evt) {
+        this.addFiles([file], evt)
+      },
+    
+      cancel: function () {
+        for (var i = this.fileList.length - 1; i >= 0; i--) {
+          this.fileList[i].cancel()
+        }
+      },
+    
+      removeFile: function (file) {
+        File.prototype.removeFile.call(this, file)
+        this._trigger('fileRemoved', file)
+      },
+    
+      generateUniqueIdentifier: function (file) {
+        var custom = this.opts.generateUniqueIdentifier
+        if (utils.isFunction(custom)) {
+          return custom(file)
+        }
+        /* istanbul ignore next */
+        // Some confusion in different versions of Firefox
+        var relativePath = file.relativePath || file.webkitRelativePath || file.fileName || file.name
+        /* istanbul ignore next */
+        return file.size + '-' + relativePath.replace(/[^0-9a-zA-Z_-]/img, '')
+      },
+    
+      getFromUniqueIdentifier: function (uniqueIdentifier) {
+        var ret = false
+        utils.each(this.files, function (file) {
+          if (file.uniqueIdentifier === uniqueIdentifier) {
+            ret = file
+            return false
+          }
+        })
+        return ret
+      },
+    
+      uploadNextChunk: function (preventEvents) {
+        var found = false
+        var pendingStatus = Chunk.STATUS.PENDING
+        var checkChunkUploaded = this.uploader.opts.checkChunkUploadedByResponse
+        if (this.opts.prioritizeFirstAndLastChunk) {
+          utils.each(this.files, function (file) {
+            if (file.paused) {
+              return
+            }
+            if (checkChunkUploaded && !file._firstResponse && file.isUploading()) {
+              // waiting for current file's first chunk response
+              return
+            }
+            if (file.chunks.length && file.chunks[0].status() === pendingStatus) {
+              file.chunks[0].send()
+              found = true
+              return false
+            }
+            if (file.chunks.length > 1 && file.chunks[file.chunks.length - 1].status() === pendingStatus) {
+              file.chunks[file.chunks.length - 1].send()
+              found = true
+              return false
+            }
+          })
+          if (found) {
+            return found
+          }
+        }
+    
+        // Now, simply look for the next, best thing to upload
+        utils.each(this.files, function (file) {
+          if (!file.paused) {
+            if (checkChunkUploaded && !file._firstResponse && file.isUploading()) {
+              // waiting for current file's first chunk response
+              return
+            }
+            utils.each(file.chunks, function (chunk) {
+              if (chunk.status() === pendingStatus) {
+                chunk.send()
+                found = true
+                return false
+              }
+            })
+          }
+          if (found) {
+            return false
+          }
+        })
+        if (found) {
+          return true
+        }
+    
+        // The are no more outstanding chunks to upload, check is everything is done
+        var outstanding = false
+        utils.each(this.files, function (file) {
+          if (!file.isComplete()) {
+            outstanding = true
+            return false
+          }
+        })
+        // should check files now
+        // if now files in list
+        // should not trigger complete event
+        if (!outstanding && !preventEvents && this.files.length) {
+          // All chunks have been uploaded, complete
+          this._triggerAsync('complete')
+        }
+        return outstanding
+      },
+    
+      upload: function (preventEvents) {
+        // Make sure we don't start too many uploads at once
+        var ret = this._shouldUploadNext()
+        if (ret === false) {
+          return
+        }
+        !preventEvents && this._trigger('uploadStart')
+        var started = false
+        for (var num = 1; num <= this.opts.simultaneousUploads - ret; num++) {
+          started = this.uploadNextChunk(!preventEvents) || started
+          if (!started && preventEvents) {
+            // completed
+            break
+          }
+        }
+        if (!started && !preventEvents) {
+          this._triggerAsync('complete')
+        }
+      },
+    
+      /**
+       * should upload next chunk
+       * @function
+       * @returns {Boolean|Number}
+       */
+      _shouldUploadNext: function () {
+        var num = 0
+        var should = true
+        var simultaneousUploads = this.opts.simultaneousUploads
+        var uploadingStatus = Chunk.STATUS.UPLOADING
+        utils.each(this.files, function (file) {
+          utils.each(file.chunks, function (chunk) {
+            if (chunk.status() === uploadingStatus) {
+              num++
+              if (num >= simultaneousUploads) {
+                should = false
+                return false
+              }
+            }
+          })
+          return should
+        })
+        // if should is true then return uploading chunks's length
+        return should && num
+      },
+    
+      /**
+       * Assign a browse action to one or more DOM nodes.
+       * @function
+       * @param {Element|Array.<Element>} domNodes
+       * @param {boolean} isDirectory Pass in true to allow directories to
+       * @param {boolean} singleFile prevent multi file upload
+       * @param {Object} attributes set custom attributes:
+       *  http://www.w3.org/TR/html-markup/input.file.html#input.file-attributes
+       *  eg: accept: 'image/*'
+       * be selected (Chrome only).
+       */
+      assignBrowse: function (domNodes, isDirectory, singleFile, attributes) {
+        if (typeof domNodes.length === 'undefined') {
+          domNodes = [domNodes]
+        }
+    
+        utils.each(domNodes, function (domNode) {
+          var input
+          if (domNode.tagName === 'INPUT' && domNode.type === 'file') {
+            input = domNode
+          } else {
+            input = document.createElement('input')
+            input.setAttribute('type', 'file')
+            // display:none - not working in opera 12
+            utils.extend(input.style, {
+              visibility: 'hidden',
+              position: 'absolute',
+              width: '1px',
+              height: '1px'
+            })
+            // for opera 12 browser, input must be assigned to a document
+            Array.from(domNode.children).forEach(function(child){
+              if(child.type=='file'){
+                  console.log(child)
+                  domNode.removeChild(child)
+              }
+            })
+            domNode.appendChild(input)
+            // https://developer.mozilla.org/en/using_files_from_web_applications)
+            // event listener is executed two times
+            // first one - original mouse click event
+            // second - input.click(), input is inside domNode
+            domNode.addEventListener('click', function (e) {
+              if (domNode.tagName.toLowerCase() === 'label') {
+                return
+              }
+              input.click()
+            }, false)
+          }
+          if (!this.opts.singleFile && !singleFile) {
+            input.setAttribute('multiple', 'multiple')
+          }
+          if (isDirectory) {
+            input.setAttribute('webkitdirectory', 'webkitdirectory')
+          }
+          attributes && utils.each(attributes, function (value, key) {
+            input.setAttribute(key, value)
+          })
+          // When new files are added, simply append them to the overall list
+          var that = this
+          input.addEventListener('change', function (e) {
+            that._trigger(e.type, e)
+            if (e.target.value) {
+              that.addFiles(e.target.files, e)
+              e.target.value = ''
+            }
+          }, false)
+        }, this)
+      },
+    
+      onDrop: function (evt) {
+        this._trigger(evt.type, evt)
+        if (this.opts.onDropStopPropagation) {
+          evt.stopPropagation()
+        }
+        evt.preventDefault()
+        this._parseDataTransfer(evt.dataTransfer, evt)
+      },
+    
+      _parseDataTransfer: function (dataTransfer, evt) {
+        if (dataTransfer.items && dataTransfer.items[0] &&
+          dataTransfer.items[0].webkitGetAsEntry) {
+          this.webkitReadDataTransfer(dataTransfer, evt)
+        } else {
+          this.addFiles(dataTransfer.files, evt)
+        }
+      },
+    
+      webkitReadDataTransfer: function (dataTransfer, evt) {
+        var self = this
+        var queue = dataTransfer.items.length
+        var files = []
+        utils.each(dataTransfer.items, function (item) {
+          var entry = item.webkitGetAsEntry()
+          if (!entry) {
+            decrement()
+            return
+          }
+          if (entry.isFile) {
+            // due to a bug in Chrome's File System API impl - #149735
+            fileReadSuccess(item.getAsFile(), entry.fullPath)
+          } else {
+            readDirectory(entry.createReader())
+          }
+        })
+        function readDirectory (reader) {
+          reader.readEntries(function (entries) {
+            if (entries.length) {
+              queue += entries.length
+              utils.each(entries, function (entry) {
+                if (entry.isFile) {
+                  var fullPath = entry.fullPath
+                  entry.file(function (file) {
+                    fileReadSuccess(file, fullPath)
+                  }, readError)
+                } else if (entry.isDirectory) {
+                  readDirectory(entry.createReader())
+                }
+              })
+              readDirectory(reader)
+            } else {
+              decrement()
+            }
+          }, readError)
+        }
+        function fileReadSuccess (file, fullPath) {
+          // relative path should not start with "/"
+          file.relativePath = fullPath.substring(1)
+          files.push(file)
+          decrement()
+        }
+        function readError (fileError) {
+          throw fileError
+        }
+        function decrement () {
+          if (--queue === 0) {
+            self.addFiles(files, evt)
+          }
+        }
+      },
+    
+      _assignHelper: function (domNodes, handles, remove) {
+        if (typeof domNodes.length === 'undefined') {
+          domNodes = [domNodes]
+        }
+        var evtMethod = remove ? 'removeEventListener' : 'addEventListener'
+        utils.each(domNodes, function (domNode) {
+          utils.each(handles, function (handler, name) {
+            domNode[evtMethod](name, handler, false)
+          }, this)
+        }, this)
+      },
+    
+      _preventEvent: function (e) {
+        utils.preventEvent(e)
+        this._trigger(e.type, e)
+      },
+    
+      /**
+       * Assign one or more DOM nodes as a drop target.
+       * @function
+       * @param {Element|Array.<Element>} domNodes
+       */
+      assignDrop: function (domNodes) {
+        this._onDrop = utils.bind(this.onDrop, this)
+        this._assignHelper(domNodes, {
+          dragover: this.preventEvent,
+          dragenter: this.preventEvent,
+          dragleave: this.preventEvent,
+          drop: this._onDrop
+        })
+      },
+    
+      /**
+       * Un-assign drop event from DOM nodes
+       * @function
+       * @param domNodes
+       */
+      unAssignDrop: function (domNodes) {
+        this._assignHelper(domNodes, {
+          dragover: this.preventEvent,
+          dragenter: this.preventEvent,
+          dragleave: this.preventEvent,
+          drop: this._onDrop
+        }, true)
+        this._onDrop = null
+      }
+    })
+    
+    module.exports = Uploader
+    
+    },{"./chunk":1,"./event":2,"./file":4,"./utils":5}],4:[function(_dereq_,module,exports){
+    var utils = _dereq_('./utils')
+    var Chunk = _dereq_('./chunk')
+    
+    function File (uploader, file, parent) {
+      utils.defineNonEnumerable(this, 'uploader', uploader)
+      this.isRoot = this.isFolder = uploader === this
+      utils.defineNonEnumerable(this, 'parent', parent || null)
+      utils.defineNonEnumerable(this, 'files', [])
+      utils.defineNonEnumerable(this, 'fileList', [])
+      utils.defineNonEnumerable(this, 'chunks', [])
+      utils.defineNonEnumerable(this, '_errorFiles', [])
+      utils.defineNonEnumerable(this, 'file', null)
+      this.id = utils.uid()
+    
+      if (this.isRoot || !file) {
+        this.file = null
+      } else {
+        if (utils.isString(file)) {
+          // folder
+          this.isFolder = true
+          this.file = null
+          this.path = file
+          if (this.parent.path) {
+            file = file.substr(this.parent.path.length)
+          }
+          this.name = file.charAt(file.length - 1) === '/' ? file.substr(0, file.length - 1) : file
+        } else {
+          this.file = file
+          this.fileType = this.file.type
+          this.name = file.fileName || file.name
+          this.size = file.size
+          this.relativePath = file.relativePath || file.webkitRelativePath || this.name
+          this._parseFile()
+        }
+      }
+    
+      this.paused = uploader.opts.initialPaused
+      this.error = false
+      this.allError = false
+      this.aborted = false
+      this.completed = false
+      this.averageSpeed = 0
+      this.currentSpeed = 0
+      this._lastProgressCallback = Date.now()
+      this._prevUploadedSize = 0
+      this._prevProgress = 0
+    
+      this.bootstrap()
+    }
+    
+    utils.extend(File.prototype, {
+    
+      _parseFile: function () {
+        var ppaths = parsePaths(this.relativePath)
+        if (ppaths.length) {
+          var filePaths = this.uploader.filePaths
+          utils.each(ppaths, function (path, i) {
+            var folderFile = filePaths[path]
+            if (!folderFile) {
+              folderFile = new File(this.uploader, path, this.parent)
+              filePaths[path] = folderFile
+              this._updateParentFileList(folderFile)
+            }
+            this.parent = folderFile
+            folderFile.files.push(this)
+            if (!ppaths[i + 1]) {
+              folderFile.fileList.push(this)
+            }
+          }, this)
+        } else {
+          this._updateParentFileList()
+        }
+      },
+    
+      _updateParentFileList: function (file) {
+        if (!file) {
+          file = this
+        }
+        var p = this.parent
+        if (p) {
+          p.fileList.push(file)
+        }
+      },
+    
+      _eachAccess: function (eachFn, fileFn) {
+        if (this.isFolder) {
+          utils.each(this.files, function (f, i) {
+            return eachFn.call(this, f, i)
+          }, this)
+          return
+        }
+        fileFn.call(this, this)
+      },
+    
+      bootstrap: function () {
+        if (this.isFolder) return
+        var opts = this.uploader.opts
+        if (utils.isFunction(opts.initFileFn)) {
+          opts.initFileFn.call(this, this)
+        }
+    
+        this.abort(true)
+        this._resetError()
+        // Rebuild stack of chunks from file
+        this._prevProgress = 0
+        var round = opts.forceChunkSize ? Math.ceil : Math.floor
+        var chunks = Math.max(round(this.size / opts.chunkSize), 1)
+        for (var offset = 0; offset < chunks; offset++) {
+          this.chunks.push(new Chunk(this.uploader, this, offset))
+        }
+      },
+    
+      _measureSpeed: function () {
+        var smoothingFactor = this.uploader.opts.speedSmoothingFactor
+        var timeSpan = Date.now() - this._lastProgressCallback
+        if (!timeSpan) {
+          return
+        }
+        var uploaded = this.sizeUploaded()
+        // Prevent negative upload speed after file upload resume
+        this.currentSpeed = Math.max((uploaded - this._prevUploadedSize) / timeSpan * 1000, 0)
+        this.averageSpeed = smoothingFactor * this.currentSpeed + (1 - smoothingFactor) * this.averageSpeed
+        this._prevUploadedSize = uploaded
+        if (this.parent && this.parent._checkProgress()) {
+          this.parent._measureSpeed()
+        }
+      },
+    
+      _checkProgress: function (file) {
+        return Date.now() - this._lastProgressCallback >= this.uploader.opts.progressCallbacksInterval
+      },
+    
+      _chunkEvent: function (chunk, evt, message) {
+        var uploader = this.uploader
+        var STATUS = Chunk.STATUS
+        var that = this
+        var rootFile = this.getRoot()
+        var triggerProgress = function () {
+          that._measureSpeed()
+          uploader._trigger('fileProgress', rootFile, that, chunk)
+          that._lastProgressCallback = Date.now()
+        }
+        switch (evt) {
+          case STATUS.PROGRESS:
+            if (this._checkProgress()) {
+              triggerProgress()
+            }
+            break
+          case STATUS.ERROR:
+            this._error()
+            this.abort(true)
+            uploader._trigger('fileError', rootFile, this, message, chunk)
+            break
+          case STATUS.SUCCESS:
+            this._updateUploadedChunks(message, chunk)
+            if (this.error) {
+              return
+            }
+            clearTimeout(this._progeressId)
+            this._progeressId = 0
+            var timeDiff = Date.now() - this._lastProgressCallback
+            if (timeDiff < uploader.opts.progressCallbacksInterval) {
+              this._progeressId = setTimeout(triggerProgress, uploader.opts.progressCallbacksInterval - timeDiff)
+            }
+            if (this.isComplete()) {
+              clearTimeout(this._progeressId)
+              triggerProgress()
+              this.currentSpeed = 0
+              this.averageSpeed = 0
+              uploader._trigger('fileSuccess', rootFile, this, message, chunk)
+              if (rootFile.isComplete()) {
+                uploader._trigger('fileComplete', rootFile, this)
+              }
+            } else if (!this._progeressId) {
+              triggerProgress()
+            }
+            break
+          case STATUS.RETRY:
+            uploader._trigger('fileRetry', rootFile, this, chunk)
+            break
+        }
+      },
+    
+      _updateUploadedChunks: function (message, chunk) {
+        var checkChunkUploaded = this.uploader.opts.checkChunkUploadedByResponse
+        if (checkChunkUploaded) {
+          var xhr = chunk.xhr
+          utils.each(this.chunks, function (_chunk) {
+            if (!_chunk.tested) {
+              var uploaded = checkChunkUploaded.call(this, _chunk, message)
+              if (_chunk === chunk && !uploaded) {
+                // fix the first chunk xhr status
+                // treated as success but checkChunkUploaded is false
+                // so the current chunk should be uploaded again
+                _chunk.xhr = null
+              }
+              if (uploaded) {
+                // first success and other chunks are uploaded
+                // then set xhr, so the uploaded chunks
+                // will be treated as success too
+                _chunk.xhr = xhr
+              }
+              _chunk.tested = true
+            }
+          }, this)
+          if (!this._firstResponse) {
+            this._firstResponse = true
+            this.uploader.upload(true)
+          } else {
+            this.uploader.uploadNextChunk()
+          }
+        } else {
+          this.uploader.uploadNextChunk()
+        }
+      },
+    
+      _error: function () {
+        this.error = this.allError = true
+        var parent = this.parent
+        while (parent && parent !== this.uploader) {
+          parent._errorFiles.push(this)
+          parent.error = true
+          if (parent._errorFiles.length === parent.files.length) {
+            parent.allError = true
+          }
+          parent = parent.parent
+        }
+      },
+    
+      _resetError: function () {
+        this.error = this.allError = false
+        var parent = this.parent
+        var index = -1
+        while (parent && parent !== this.uploader) {
+          index = parent._errorFiles.indexOf(this)
+          parent._errorFiles.splice(index, 1)
+          parent.allError = false
+          if (!parent._errorFiles.length) {
+            parent.error = false
+          }
+          parent = parent.parent
+        }
+      },
+    
+      isComplete: function () {
+        if (!this.completed) {
+          var outstanding = false
+          this._eachAccess(function (file) {
+            if (!file.isComplete()) {
+              outstanding = true
+              return false
+            }
+          }, function () {
+            var STATUS = Chunk.STATUS
+            utils.each(this.chunks, function (chunk) {
+              var status = chunk.status()
+              if (status === STATUS.PENDING || status === STATUS.UPLOADING || status === STATUS.READING || chunk.preprocessState === 1 || chunk.readState === 1) {
+                outstanding = true
+                return false
+              }
+            })
+          })
+          this.completed = !outstanding
+        }
+        return this.completed
+      },
+    
+      isUploading: function () {
+        var uploading = false
+        this._eachAccess(function (file) {
+          if (file.isUploading()) {
+            uploading = true
+            return false
+          }
+        }, function () {
+          var uploadingStatus = Chunk.STATUS.UPLOADING
+          utils.each(this.chunks, function (chunk) {
+            if (chunk.status() === uploadingStatus) {
+              uploading = true
+              return false
+            }
+          })
+        })
+        return uploading
+      },
+    
+      resume: function () {
+        this._eachAccess(function (f) {
+          f.resume()
+        }, function () {
+          this.paused = false
+          this.aborted = false
+          this.uploader.upload()
+        })
+        this.paused = false
+        this.aborted = false
+      },
+    
+      pause: function () {
+        this._eachAccess(function (f) {
+          f.pause()
+        }, function () {
+          this.paused = true
+          this.abort()
+        })
+        this.paused = true
+      },
+    
+      cancel: function () {
+        this.uploader.removeFile(this)
+      },
+    
+      retry: function (file) {
+        var fileRetry = function (file) {
+          if (file.error) {
+            file.bootstrap()
+          }
+        }
+        if (file) {
+          file.bootstrap()
+        } else {
+          this._eachAccess(fileRetry, function () {
+            this.bootstrap()
+          })
+        }
+        this.uploader.upload()
+      },
+    
+      abort: function (reset) {
+        if (this.aborted) {
+          return
+        }
+        this.currentSpeed = 0
+        this.averageSpeed = 0
+        this.aborted = !reset
+        var chunks = this.chunks
+        if (reset) {
+          this.chunks = []
+        }
+        var uploadingStatus = Chunk.STATUS.UPLOADING
+        utils.each(chunks, function (c) {
+          if (c.status() === uploadingStatus) {
+            c.abort()
+            this.uploader.uploadNextChunk()
+          }
+        }, this)
+      },
+    
+      progress: function () {
+        var totalDone = 0
+        var totalSize = 0
+        var ret = 0
+        this._eachAccess(function (file, index) {
+          totalDone += file.progress() * file.size
+          totalSize += file.size
+          if (index === this.files.length - 1) {
+            ret = totalSize > 0 ? totalDone / totalSize : this.isComplete() ? 1 : 0
+          }
+        }, function () {
+          if (this.error) {
+            ret = 1
+            return
+          }
+          if (this.chunks.length === 1) {
+            this._prevProgress = Math.max(this._prevProgress, this.chunks[0].progress())
+            ret = this._prevProgress
+            return
+          }
+          // Sum up progress across everything
+          var bytesLoaded = 0
+          utils.each(this.chunks, function (c) {
+            // get chunk progress relative to entire file
+            bytesLoaded += c.progress() * (c.endByte - c.startByte)
+          })
+          var percent = bytesLoaded / this.size
+          // We don't want to lose percentages when an upload is paused
+          this._prevProgress = Math.max(this._prevProgress, percent > 0.9999 ? 1 : percent)
+          ret = this._prevProgress
+        })
+        return ret
+      },
+    
+      getSize: function () {
+        var size = 0
+        this._eachAccess(function (file) {
+          size += file.size
+        }, function () {
+          size += this.size
+        })
+        return size
+      },
+    
+      getFormatSize: function () {
+        var size = this.getSize()
+        return utils.formatSize(size)
+      },
+    
+      getRoot: function () {
+        if (this.isRoot) {
+          return this
+        }
+        var parent = this.parent
+        while (parent) {
+          if (parent.parent === this.uploader) {
+            // find it
+            return parent
+          }
+          parent = parent.parent
+        }
+        return this
+      },
+    
+      sizeUploaded: function () {
+        var size = 0
+        this._eachAccess(function (file) {
+          size += file.sizeUploaded()
+        }, function () {
+          utils.each(this.chunks, function (chunk) {
+            size += chunk.sizeUploaded()
+          })
+        })
+        return size
+      },
+    
+      timeRemaining: function () {
+        var ret = 0
+        var sizeDelta = 0
+        var averageSpeed = 0
+        this._eachAccess(function (file, i) {
+          if (!file.paused && !file.error) {
+            sizeDelta += file.size - file.sizeUploaded()
+            averageSpeed += file.averageSpeed
+          }
+          if (i === this.files.length - 1) {
+            ret = calRet(sizeDelta, averageSpeed)
+          }
+        }, function () {
+          if (this.paused || this.error) {
+            ret = 0
+            return
+          }
+          var delta = this.size - this.sizeUploaded()
+          ret = calRet(delta, this.averageSpeed)
+        })
+        return ret
+        function calRet (delta, averageSpeed) {
+          if (delta && !averageSpeed) {
+            return Number.POSITIVE_INFINITY
+          }
+          if (!delta && !averageSpeed) {
+            return 0
+          }
+          return Math.floor(delta / averageSpeed)
+        }
+      },
+    
+      removeFile: function (file) {
+        if (file.isFolder) {
+          while (file.files.length) {
+            var f = file.files[file.files.length - 1]
+            this._removeFile(f)
+          }
+        }
+        this._removeFile(file)
+      },
+    
+      _delFilePath: function (file) {
+        if (file.path && this.filePaths) {
+          delete this.filePaths[file.path]
+        }
+        utils.each(file.fileList, function (file) {
+          this._delFilePath(file)
+        }, this)
+      },
+    
+      _removeFile: function (file) {
+        if (!file.isFolder) {
+          utils.each(this.files, function (f, i) {
+            if (f === file) {
+              this.files.splice(i, 1)
+              return false
+            }
+          }, this)
+          file.abort()
+          var parent = file.parent
+          var newParent
+          while (parent && parent !== this) {
+            newParent = parent.parent
+            parent._removeFile(file)
+            parent = newParent
+          }
+        }
+        file.parent === this && utils.each(this.fileList, function (f, i) {
+          if (f === file) {
+            this.fileList.splice(i, 1)
+            return false
+          }
+        }, this)
+        if (!this.isRoot && this.isFolder && !this.files.length) {
+          this.parent._removeFile(this)
+          this.uploader._delFilePath(this)
+        }
+        file.parent = null
+      },
+    
+      getType: function () {
+        if (this.isFolder) {
+          return 'folder'
+        }
+        return this.file.type && this.file.type.split('/')[1]
+      },
+    
+      getExtension: function () {
+        if (this.isFolder) {
+          return ''
+        }
+        return this.name.substr((~-this.name.lastIndexOf('.') >>> 0) + 2).toLowerCase()
+      }
+    
+    })
+    
+    module.exports = File
+    
+    function parsePaths (path) {
+      var ret = []
+      var paths = path.split('/')
+      var len = paths.length
+      var i = 1
+      paths.splice(len - 1, 1)
+      len--
+      if (paths.length) {
+        while (i <= len) {
+          ret.push(paths.slice(0, i++).join('/') + '/')
+        }
+      }
+      return ret
+    }
+    
+    },{"./chunk":1,"./utils":5}],5:[function(_dereq_,module,exports){
+    var oproto = Object.prototype
+    var aproto = Array.prototype
+    var serialize = oproto.toString
+    
+    var isFunction = function (fn) {
+      return serialize.call(fn) === '[object Function]'
+    }
+    
+    var isArray = Array.isArray || /* istanbul ignore next */ function (ary) {
+      return serialize.call(ary) === '[object Array]'
+    }
+    
+    var isPlainObject = function (obj) {
+      return serialize.call(obj) === '[object Object]' && Object.getPrototypeOf(obj) === oproto
+    }
+    
+    var i = 0
+    var utils = {
+      uid: function () {
+        return ++i
+      },
+      noop: function () {},
+      bind: function (fn, context) {
+        return function () {
+          return fn.apply(context, arguments)
+        }
+      },
+      preventEvent: function (evt) {
+        evt.preventDefault()
+      },
+      stop: function (evt) {
+        evt.preventDefault()
+        evt.stopPropagation()
+      },
+      nextTick: function (fn, context) {
+        setTimeout(utils.bind(fn, context), 0)
+      },
+      toArray: function (ary, start, end) {
+        if (start === undefined) start = 0
+        if (end === undefined) end = ary.length
+        return aproto.slice.call(ary, start, end)
+      },
+    
+      isPlainObject: isPlainObject,
+      isFunction: isFunction,
+      isArray: isArray,
+      isObject: function (obj) {
+        return Object(obj) === obj
+      },
+      isString: function (s) {
+        return typeof s === 'string'
+      },
+      isUndefined: function (a) {
+        return typeof a === 'undefined'
+      },
+      isDefined: function (a) {
+        return typeof a !== 'undefined'
+      },
+    
+      each: function (ary, func, context) {
+        if (utils.isDefined(ary.length)) {
+          for (var i = 0, len = ary.length; i < len; i++) {
+            if (func.call(context, ary[i], i, ary) === false) {
+              break
+            }
+          }
+        } else {
+          for (var k in ary) {
+            if (func.call(context, ary[k], k, ary) === false) {
+              break
+            }
+          }
+        }
+      },
+    
+      /**
+       * If option is a function, evaluate it with given params
+       * @param {*} data
+       * @param {...} args arguments of a callback
+       * @returns {*}
+       */
+      evalOpts: function (data, args) {
+        if (utils.isFunction(data)) {
+          // `arguments` is an object, not array, in FF, so:
+          args = utils.toArray(arguments)
+          data = data.apply(null, args.slice(1))
+        }
+        return data
+      },
+    
+      extend: function () {
+        var options
+        var name
+        var src
+        var copy
+        var copyIsArray
+        var clone
+        var target = arguments[0] || {}
+        var i = 1
+        var length = arguments.length
+        var force = false
+    
+        // 濡傛灉绗竴涓弬鏁颁负甯冨皵,鍒ゅ畾鏄惁娣辨嫹璐�
+        if (typeof target === 'boolean') {
+          force = target
+          target = arguments[1] || {}
+          i++
+        }
+    
+        // 纭繚鎺ュ彈鏂逛负涓�涓鏉傜殑鏁版嵁绫诲瀷
+        if (typeof target !== 'object' && !isFunction(target)) {
+          target = {}
+        }
+    
+        // 濡傛灉鍙湁涓�涓弬鏁帮紝閭d箞鏂版垚鍛樻坊鍔犱簬 extend 鎵�鍦ㄧ殑瀵硅薄涓�
+        if (i === length) {
+          target = this
+          i--
+        }
+    
+        for (; i < length; i++) {
+          // 鍙鐞嗛潪绌哄弬鏁�
+          if ((options = arguments[i]) != null) {
+            for (name in options) {
+              src = target[name]
+              copy = options[name]
+    
+              // 闃叉鐜紩鐢�
+              if (target === copy) {
+                continue
+              }
+              if (force && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {
+                if (copyIsArray) {
+                  copyIsArray = false
+                  clone = src && isArray(src) ? src : []
+                } else {
+                  clone = src && isPlainObject(src) ? src : {}
+                }
+                target[name] = utils.extend(force, clone, copy)
+              } else if (copy !== undefined) {
+                target[name] = copy
+              }
+            }
+          }
+        }
+        return target
+      },
+    
+      formatSize: function (size) {
+        if (size < 1024) {
+          return size.toFixed(0) + ' bytes'
+        } else if (size < 1024 * 1024) {
+          return (size / 1024.0).toFixed(0) + ' KB'
+        } else if (size < 1024 * 1024 * 1024) {
+          return (size / 1024.0 / 1024.0).toFixed(1) + ' MB'
+        } else {
+          return (size / 1024.0 / 1024.0 / 1024.0).toFixed(1) + ' GB'
+        }
+      },
+    
+      defineNonEnumerable: function (target, key, value) {
+        Object.defineProperty(target, key, {
+          enumerable: false,
+          configurable: true,
+          writable: true,
+          value: value
+        })
+      }
+    }
+    
+    module.exports = utils
+    
+    },{}]},{},[3])
+    (3)
+    });
\ No newline at end of file
diff --git a/src/components/subComponents/FileUpload/uploader.vue b/src/components/subComponents/FileUpload/uploader.vue
index ddcedb9..fafa33e 100644
--- a/src/components/subComponents/FileUpload/uploader.vue
+++ b/src/components/subComponents/FileUpload/uploader.vue
@@ -14,7 +14,9 @@
 </template>
 
 <script>
-import Uploader from 'simple-uploader.js'
+//import Uploader from 'simple-uploader.js'
+//require('./common/uploader-simple')
+import './common/uploader-simple'
 import { kebabCase } from './common/utils'
 import UploaderBtn from './btn.vue'
 import UploaderDrop from './drop.vue'
diff --git a/src/pages/cameraAccess/components/DataStackInfo.vue b/src/pages/cameraAccess/components/DataStackInfo.vue
index fffe4d0..94a4cb9 100644
--- a/src/pages/cameraAccess/components/DataStackInfo.vue
+++ b/src/pages/cameraAccess/components/DataStackInfo.vue
@@ -50,7 +50,7 @@
               <li>
                 <info-card
                   style="width: 100%;min-width: 440px"
-                  :realtime="PollData.RealTimeSum"
+                  :realtime="PollData.RealTimeValidCount"
                   :polling="PollData.PollValidCount"
                   :dataStack="PollData.stackChannelCount"
                 ></info-card>
@@ -143,7 +143,7 @@
             </el-image>
             <el-image
               v-if="row.type==2"
-              style="width: 30x; height: 30px"
+              style="width: 30x; height: 30px;background:#fff;"
               :src="`/files/${row.path.substr(row.path.lastIndexOf('/')+1)}`"
               fit="fill"
               :preview-src-list="[`/files/${row.path.substr(row.path.lastIndexOf('/')+1)}`]"
@@ -264,8 +264,8 @@
     </div>
 
     <!-- 鏂囦欢涓婁紶缁勪欢 -->
-    <!-- <file-uploader ref="uploader" v-show="activeName === 'uploading'" :attrs="attrs" /> -->
-    <file-uploader ref="uploader" v-show="activeName === 'uploading'" />
+    <file-uploader ref="uploader" v-show="activeName === 'uploading'" :attrs="attrs" />
+    <!-- <file-uploader ref="uploader" v-show="activeName === 'uploading'" /> -->
 
     <!-- 鏂囦欢棰勮 -->
     <el-dialog title="鏌ョ湅鏂囦欢" :visible.sync="previewDialog" width="500px">
@@ -439,7 +439,7 @@
           this.$set(this.attrs, 'accept', ".mp4");
         }else if (n == 2) {
           //鍥剧墖
-          this.$set(this.attrs, 'accept', "image/jpg,image/jpeg,image/png");
+          this.$set(this.attrs, 'accept', ".jpg,.jpeg,.png");
         }
       }
     }
diff --git a/src/pages/desktop/index/components/ToolsEntry.vue b/src/pages/desktop/index/components/ToolsEntry.vue
index d519f72..8612ff5 100644
--- a/src/pages/desktop/index/components/ToolsEntry.vue
+++ b/src/pages/desktop/index/components/ToolsEntry.vue
@@ -1,7 +1,7 @@
 <template>
   <div class="tools-entry">
     <div class="entry-wrap">
-      <el-carousel height="600px" :autoplay="false" >
+      <el-carousel height="600px" :autoplay="false" arrow="never">
         <el-carousel-item v-for="(carousel,index) in carousels" :key="index">
           <div class="app-list clearFix sdk-list" >
             <div v-for="item in carousel" :key="item.id">
@@ -215,6 +215,11 @@
 .el-carousel__arrow--right{
   right: 0 !important;
 }
+.el-carousel__button{
+  width: 12px !important;
+  height: 12px !important;;
+  border-radius: 50% !important;
+}
 .tools-entry {
   //margin-top: 130px;
   position: absolute;
@@ -275,7 +280,7 @@
       text-align: right;
       padding-right: 50px;
       user-select: none;
-      margin-top: -100px;
+      margin-top: -80px;
       img {
         user-select: none;
         -webkit-user-drag: none;
diff --git a/src/pages/labelMark/components/RightSide.vue b/src/pages/labelMark/components/RightSide.vue
index 7e94302..fddcff1 100644
--- a/src/pages/labelMark/components/RightSide.vue
+++ b/src/pages/labelMark/components/RightSide.vue
@@ -1,75 +1,109 @@
 <template>
   <div class="right-side">
     <div class="figure">
-      <div class="action-bar">
-        <el-button
-          class="drawboard-trigger"
-          size="small"
-          @click="isEdit=!isEdit"
-          :icon="isEdit?'el-icon-lock':'el-icon-edit'"
-        >{{isEdit?'閿佸畾':'缂栬緫'}}</el-button>
-      </div>
-      <div class="drawboard">
-        <div class="mask" :class="{'edit-status-mask':isEdit}" ref="editBoard">
-          <div
-            class="label"
-            @click="editLabel(item)"
-            v-for="(item,index) in labels"
-            :key="index"
-            :style="{left:`${item.x}px`, top:`${item.y}px`, backgroundColor: colorPick, width: `${dotSize}px`, height: `${dotSize}px` }"
-          ></div>
-        </div>
-        <img :src="`/httpImage/${snapshot_url}`" alt />
-        <div
-          class="popBox"
-          v-show="isShowPop"
-          :style="`top:${curLabel.y + 22}px;left:${curLabel.x}px`"
-        >
-          <div class="title">鏍囨敞淇℃伅</div>
-          <div class="details">
-            <div class="detail-item">
-              <div class="left">
-                <label for>骞抽潰鍧愭爣X:</label>
-                <span class="fix-width">{{curLabel.x}}</span>
-                <i>px</i>
+      <el-collapse v-model="actPage" @change="chnageActPage">
+        <el-collapse-item title="鎽勫儚鏈烘爣娉�" name="1">
+          <div class="action-bar">
+            <div class="tool-bar">
+              <div>
+                <!-- <input type="color" ref="colorPicker" v-model="color"> -->
+                <label for>鎷捐壊鍣�:</label>
+                <el-color-picker v-model="colorPick" show-alpha size="mini"></el-color-picker>
               </div>
-              <span class="devide"></span>
-              <div class="right">
-                <label for>瀹為檯鍧愭爣X:</label>
-                <el-input type="text" size="mini" style="width:90px" v-model="curLabel.posX"></el-input>
+              <div style="width:250px;">
+                <label for>绗旇Е:</label>
+                <el-slider v-model="dotSize" :min="1" :max="20"></el-slider>
               </div>
-            </div>
-            <div class="detail-item">
-              <div class="left">
-                <label for>骞抽潰鍧愭爣Y:</label>
-                <span class="fix-width">{{curLabel.y}}</span>
-                <i>px</i>
+              <div>
+                <el-button
+                  class="drawboard-trigger"
+                  size="small"
+                  @click="isEdit=!isEdit"
+                  :icon="isEdit?'el-icon-lock':'el-icon-edit'"
+                >{{isEdit?'閿佸畾':'缂栬緫'}}</el-button>
               </div>
-              <span class="devide"></span>
-              <div class="right">
-                <label for>瀹為檯鍧愭爣Y:</label>
-                <el-input type="text" size="mini" style="width:90px" v-model="curLabel.posY"></el-input>
-              </div>
-            </div>
-            <div class="btns">
-              <el-button size="mini" type="danger" @click="deleteLabel">鍒犻櫎</el-button>
-              <el-button size="mini" type="primary" @click="cancle">鍙栨秷</el-button>
-              <el-button size="mini" type="success" @click="submitInfo">纭畾</el-button>
             </div>
           </div>
-        </div>
-      </div>
-    </div>
-    <div class="tool-bar">
-      <div>
-        <!-- <input type="color" ref="colorPicker" v-model="color"> -->
-        <label for>鎷捐壊鍣�:</label>
-        <el-color-picker v-model="colorPick" show-alpha size="mini"></el-color-picker>
-      </div>
-      <div style="width:250px;">
-        <label for>绗旇Е:</label>
-        <el-slider v-model="dotSize" :min="1" :max="20"></el-slider>
-      </div>
+          <div class="drawboard">
+            <div class="mask" :class="{'edit-status-mask':isEdit}" ref="editBoard">
+              <div
+                class="label"
+                @click="editLabel(item)"
+                v-for="(item,index) in labels"
+                :key="index"
+                :style="{left:`${item.x}px`, top:`${item.y}px`, backgroundColor: colorPick, width: `${dotSize}px`, height: `${dotSize}px` }"
+              ></div>
+            </div>
+            <img v-show="snapshot_url" :src="`/httpImage/${snapshot_url}`" alt />
+            <div
+              class="popBox"
+              v-show="isShowPop"
+              :style="`top:${curLabel.y + 22}px;left:${curLabel.x}px`"
+            >
+              <div class="title">鏍囨敞淇℃伅</div>
+              <div class="details">
+                <div class="detail-item">
+                  <div class="left">
+                    <label for>骞抽潰鍧愭爣X:</label>
+                    <span class="fix-width">{{curLabel.x}}</span>
+                    <i>px</i>
+                  </div>
+                  <span class="devide"></span>
+                  <div class="right">
+                    <label for>瀹為檯鍧愭爣X:</label>
+                    <el-input type="text" size="mini" style="width:90px" v-model="curLabel.posX"></el-input>
+                  </div>
+                </div>
+                <div class="detail-item">
+                  <div class="left">
+                    <label for>骞抽潰鍧愭爣Y:</label>
+                    <span class="fix-width">{{curLabel.y}}</span>
+                    <i>px</i>
+                  </div>
+                  <span class="devide"></span>
+                  <div class="right">
+                    <label for>瀹為檯鍧愭爣Y:</label>
+                    <el-input type="text" size="mini" style="width:90px" v-model="curLabel.posY"></el-input>
+                  </div>
+                </div>
+                <div class="btns">
+                  <el-button size="mini" type="danger" @click="deleteLabel">鍒犻櫎</el-button>
+                  <el-button size="mini" type="primary" @click="cancle">鍙栨秷</el-button>
+                  <el-button size="mini" type="success" @click="submitInfo">纭畾</el-button>
+                </div>
+              </div>
+            </div>
+          </div>
+        </el-collapse-item>
+        <el-collapse-item title="杩借釜瀹炴櫙鍧愭爣" name="2">
+          <div class="user-upload">
+            <div class="img-card">
+              <el-upload
+                class="upload-demo"
+                drag
+                action="https://jsonplaceholder.typicode.com/posts/"
+                :http-request="definedUpload"
+                :on-change="onChange"
+                :show-file-list="false"
+              >
+                <el-image
+                  class="preview"
+                  v-if="userImg"
+                  :src="userImg"
+                  fit="contain"
+                  @mousemove="showCurPos"
+                  @mouseout="isShowCurPos=false"
+                ></el-image>
+                <div class="el-upload__text">
+                  灏嗘枃浠舵嫋鍒版澶勶紝鎴�
+                  <em>鐐瑰嚮涓婁紶</em>
+                </div>
+              </el-upload>
+            </div>
+            <div class="info" v-show="isShowCurPos">褰撳墠浣嶇疆:{{traceX}},{{traceY}}</div>
+          </div>
+        </el-collapse-item>
+      </el-collapse>
     </div>
   </div>
 </template>
@@ -78,7 +112,7 @@
 import { getCamerasByServer } from '@/api/pollConfig'
 import TreeDataPool from "@/Pool/TreeData";
 export default {
-  data() {
+  data () {
     return {
       labels: [],
       colorPick: '#79f2fb',
@@ -95,7 +129,12 @@
       },
       baseUrl: '',
       snapshot_url: '',
+      userImg: '',
       cameraData: [],
+      traceX: 0,
+      traceY: 0,
+      isShowCurPos: false,
+      actPage: ['1', '2']
     }
   },
   computed: {
@@ -126,6 +165,29 @@
     }
   },
   methods: {
+    chnageActPage () {
+
+    },
+    showCurPos (e) {
+      console.log(e);
+      this.isShowCurPos = true;
+      this.traceX = e.offsetX;
+      this.traceY = e.offsetY;
+    },
+    onChange (file, fileList) {
+      fileList = [file]
+      //fileList.push(file)
+    },
+    definedUpload (params) {
+      let _file = params.file
+      let fileReader = new FileReader()
+      fileReader.onload = () => {
+        this.userImg = fileReader.result
+      }
+      if (_file) {
+        fileReader.readAsDataURL(_file)
+      }
+    },
     getAllCameraData () {
       getCamerasByServer().then(res => {
         if (res.success) {
@@ -185,25 +247,29 @@
 </script>
 
 <style lang="scss">
-.right-side {
-  height: 100%;
+.el-collapse-item__content{
   background: #d2dcea;
-  .figure{
-    float: left;
+}
+.figure .el-collapse-item__header{
+  padding-left: 14px;
+}
+.right-side {
+  background: #d2dcea;
+  .figure {
   }
   .tool-bar {
-    float: right;
-    width: 40px;
+    //width: 40px;
     height: 100%;
-    padding: 10px 20px;
+    padding: 10px 0 10px 20px;
     box-sizing: border-box;
-    background: rgb(250, 250, 250);
-    margin-bottom: 40px;
+    //background: rgb(250, 250, 250);
+    //margin-bottom: 40px;
     display: flex;
     align-items: center;
+    justify-content: flex-end;
     > div {
       cursor: pointer;
-      background: rgb(245, 245, 245);
+      background: rgba(245, 245, 245, 0.3);
       padding: 0 5px;
       height: 40px;
       margin: 7px;
@@ -221,7 +287,7 @@
   .action-bar {
     width: 960px;
     margin: auto;
-    margin-bottom: 20px;
+    //margin-bottom: 20px;
     text-align: right;
     .drawboard-trigger {
       background: transparent;
@@ -233,8 +299,10 @@
     margin: auto;
     width: 960px;
     height: 540px;
+    margin-bottom: 130px;
     position: relative;
-    background: #fff;
+    //background: #fff;
+    background: #f0ffca;
     box-shadow: 3px 3px 3px 1px rgba(0, 0, 0, 0.1);
     .mask {
       position: absolute;
@@ -258,6 +326,7 @@
     }
     .popBox {
       position: absolute;
+      z-index: 99;
       padding: 14px;
       border-radius: 3px;
       color: #fff;
@@ -302,5 +371,53 @@
       }
     }
   }
+  .user-upload {
+    margin: auto;
+    padding: 50px;
+    display: flex;
+    .img-card{
+      
+    }
+    .upload-demo,
+    .el-upload {
+      height: 100%;
+      width: 100%;
+      margin: 0 auto;
+    }
+    .upload-demo .el-upload__input {
+      visibility: hidden;
+    }
+    .upload-demo .el-upload-dragger {
+      width: 100%;
+      height: 90%;
+      width: 962px;
+      height: 542px;
+      margin: 20px 0 0;
+      background: transparent;
+      /* border: none; */
+      //position: relative;
+      overflow: visible;
+    }
+    .upload-demo .el-upload__text {
+      position: absolute;
+      top: -24px;
+      left: 50%;
+      margin-left: -91px;
+    }
+    .upload-demo .preview {
+      object-fit: contain;
+      //position: relative;
+      // width: 100%;
+      // height: 100%;
+    }
+    .upload-demo .preview img {
+      // position: absolute;
+      // top: 50%;
+      // left: 50%;
+      // transform: translate(-50%, -50%);
+      // width: 100%;
+      // height: 100%;
+    }
+  }
 }
 </style>
\ No newline at end of file
diff --git a/src/pages/labelMark/index/App.vue b/src/pages/labelMark/index/App.vue
index fc31c39..df72374 100644
--- a/src/pages/labelMark/index/App.vue
+++ b/src/pages/labelMark/index/App.vue
@@ -51,7 +51,7 @@
 }
 .column-right {
   height: 100vh;
-  background-color: #eee;
+  background-color: #f5f5f5;
   box-sizing: border-box;
   //overflow: hidden;
   overflow-x: auto;

--
Gitblit v1.8.0