1var sparkMd5 = { 2 exports: {} 3}; 4 5(function(module, exports) { 6 (function(factory) { 7 { 8 module.exports = factory(); 9 } 10 })((function(undefined$1) { 11 var hex_chr = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" ]; 12 function md5cycle(x, k) { 13 var a = x[0], b = x[1], c = x[2], d = x[3]; 14 a += (b & c | ~b & d) + k[0] - 680876936 | 0; 15 a = (a << 7 | a >>> 25) + b | 0; 16 d += (a & b | ~a & c) + k[1] - 389564586 | 0; 17 d = (d << 12 | d >>> 20) + a | 0; 18 c += (d & a | ~d & b) + k[2] + 606105819 | 0; 19 c = (c << 17 | c >>> 15) + d | 0; 20 b += (c & d | ~c & a) + k[3] - 1044525330 | 0; 21 b = (b << 22 | b >>> 10) + c | 0; 22 a += (b & c | ~b & d) + k[4] - 176418897 | 0; 23 a = (a << 7 | a >>> 25) + b | 0; 24 d += (a & b | ~a & c) + k[5] + 1200080426 | 0; 25 d = (d << 12 | d >>> 20) + a | 0; 26 c += (d & a | ~d & b) + k[6] - 1473231341 | 0; 27 c = (c << 17 | c >>> 15) + d | 0; 28 b += (c & d | ~c & a) + k[7] - 45705983 | 0; 29 b = (b << 22 | b >>> 10) + c | 0; 30 a += (b & c | ~b & d) + k[8] + 1770035416 | 0; 31 a = (a << 7 | a >>> 25) + b | 0; 32 d += (a & b | ~a & c) + k[9] - 1958414417 | 0; 33 d = (d << 12 | d >>> 20) + a | 0; 34 c += (d & a | ~d & b) + k[10] - 42063 | 0; 35 c = (c << 17 | c >>> 15) + d | 0; 36 b += (c & d | ~c & a) + k[11] - 1990404162 | 0; 37 b = (b << 22 | b >>> 10) + c | 0; 38 a += (b & c | ~b & d) + k[12] + 1804603682 | 0; 39 a = (a << 7 | a >>> 25) + b | 0; 40 d += (a & b | ~a & c) + k[13] - 40341101 | 0; 41 d = (d << 12 | d >>> 20) + a | 0; 42 c += (d & a | ~d & b) + k[14] - 1502002290 | 0; 43 c = (c << 17 | c >>> 15) + d | 0; 44 b += (c & d | ~c & a) + k[15] + 1236535329 | 0; 45 b = (b << 22 | b >>> 10) + c | 0; 46 a += (b & d | c & ~d) + k[1] - 165796510 | 0; 47 a = (a << 5 | a >>> 27) + b | 0; 48 d += (a & c | b & ~c) + k[6] - 1069501632 | 0; 49 d = (d << 9 | d >>> 23) + a | 0; 50 c += (d & b | a & ~b) + k[11] + 643717713 | 0; 51 c = (c << 14 | c >>> 18) + d | 0; 52 b += (c & a | d & ~a) + k[0] - 373897302 | 0; 53 b = (b << 20 | b >>> 12) + c | 0; 54 a += (b & d | c & ~d) + k[5] - 701558691 | 0; 55 a = (a << 5 | a >>> 27) + b | 0; 56 d += (a & c | b & ~c) + k[10] + 38016083 | 0; 57 d = (d << 9 | d >>> 23) + a | 0; 58 c += (d & b | a & ~b) + k[15] - 660478335 | 0; 59 c = (c << 14 | c >>> 18) + d | 0; 60 b += (c & a | d & ~a) + k[4] - 405537848 | 0; 61 b = (b << 20 | b >>> 12) + c | 0; 62 a += (b & d | c & ~d) + k[9] + 568446438 | 0; 63 a = (a << 5 | a >>> 27) + b | 0; 64 d += (a & c | b & ~c) + k[14] - 1019803690 | 0; 65 d = (d << 9 | d >>> 23) + a | 0; 66 c += (d & b | a & ~b) + k[3] - 187363961 | 0; 67 c = (c << 14 | c >>> 18) + d | 0; 68 b += (c & a | d & ~a) + k[8] + 1163531501 | 0; 69 b = (b << 20 | b >>> 12) + c | 0; 70 a += (b & d | c & ~d) + k[13] - 1444681467 | 0; 71 a = (a << 5 | a >>> 27) + b | 0; 72 d += (a & c | b & ~c) + k[2] - 51403784 | 0; 73 d = (d << 9 | d >>> 23) + a | 0; 74 c += (d & b | a & ~b) + k[7] + 1735328473 | 0; 75 c = (c << 14 | c >>> 18) + d | 0; 76 b += (c & a | d & ~a) + k[12] - 1926607734 | 0; 77 b = (b << 20 | b >>> 12) + c | 0; 78 a += (b ^ c ^ d) + k[5] - 378558 | 0; 79 a = (a << 4 | a >>> 28) + b | 0; 80 d += (a ^ b ^ c) + k[8] - 2022574463 | 0; 81 d = (d << 11 | d >>> 21) + a | 0; 82 c += (d ^ a ^ b) + k[11] + 1839030562 | 0; 83 c = (c << 16 | c >>> 16) + d | 0; 84 b += (c ^ d ^ a) + k[14] - 35309556 | 0; 85 b = (b << 23 | b >>> 9) + c | 0; 86 a += (b ^ c ^ d) + k[1] - 1530992060 | 0; 87 a = (a << 4 | a >>> 28) + b | 0; 88 d += (a ^ b ^ c) + k[4] + 1272893353 | 0; 89 d = (d << 11 | d >>> 21) + a | 0; 90 c += (d ^ a ^ b) + k[7] - 155497632 | 0; 91 c = (c << 16 | c >>> 16) + d | 0; 92 b += (c ^ d ^ a) + k[10] - 1094730640 | 0; 93 b = (b << 23 | b >>> 9) + c | 0; 94 a += (b ^ c ^ d) + k[13] + 681279174 | 0; 95 a = (a << 4 | a >>> 28) + b | 0; 96 d += (a ^ b ^ c) + k[0] - 358537222 | 0; 97 d = (d << 11 | d >>> 21) + a | 0; 98 c += (d ^ a ^ b) + k[3] - 722521979 | 0; 99 c = (c << 16 | c >>> 16) + d | 0; 100 b += (c ^ d ^ a) + k[6] + 76029189 | 0; 101 b = (b << 23 | b >>> 9) + c | 0; 102 a += (b ^ c ^ d) + k[9] - 640364487 | 0; 103 a = (a << 4 | a >>> 28) + b | 0; 104 d += (a ^ b ^ c) + k[12] - 421815835 | 0; 105 d = (d << 11 | d >>> 21) + a | 0; 106 c += (d ^ a ^ b) + k[15] + 530742520 | 0; 107 c = (c << 16 | c >>> 16) + d | 0; 108 b += (c ^ d ^ a) + k[2] - 995338651 | 0; 109 b = (b << 23 | b >>> 9) + c | 0; 110 a += (c ^ (b | ~d)) + k[0] - 198630844 | 0; 111 a = (a << 6 | a >>> 26) + b | 0; 112 d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0; 113 d = (d << 10 | d >>> 22) + a | 0; 114 c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0; 115 c = (c << 15 | c >>> 17) + d | 0; 116 b += (d ^ (c | ~a)) + k[5] - 57434055 | 0; 117 b = (b << 21 | b >>> 11) + c | 0; 118 a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0; 119 a = (a << 6 | a >>> 26) + b | 0; 120 d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0; 121 d = (d << 10 | d >>> 22) + a | 0; 122 c += (a ^ (d | ~b)) + k[10] - 1051523 | 0; 123 c = (c << 15 | c >>> 17) + d | 0; 124 b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0; 125 b = (b << 21 | b >>> 11) + c | 0; 126 a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0; 127 a = (a << 6 | a >>> 26) + b | 0; 128 d += (b ^ (a | ~c)) + k[15] - 30611744 | 0; 129 d = (d << 10 | d >>> 22) + a | 0; 130 c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0; 131 c = (c << 15 | c >>> 17) + d | 0; 132 b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0; 133 b = (b << 21 | b >>> 11) + c | 0; 134 a += (c ^ (b | ~d)) + k[4] - 145523070 | 0; 135 a = (a << 6 | a >>> 26) + b | 0;
vendor: 9,720 bytes, lines 136-424
136 d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0; 137 d = (d << 10 | d >>> 22) + a | 0; 138 c += (a ^ (d | ~b)) + k[2] + 718787259 | 0; 139 c = (c << 15 | c >>> 17) + d | 0; 140 b += (d ^ (c | ~a)) + k[9] - 343485551 | 0; 141 b = (b << 21 | b >>> 11) + c | 0; 142 x[0] = a + x[0] | 0; 143 x[1] = b + x[1] | 0; 144 x[2] = c + x[2] | 0; 145 x[3] = d + x[3] | 0; 146 } 147 function md5blk(s) { 148 var md5blks = [], i; 149 for (i = 0; i < 64; i += 4) { 150 md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24); 151 } 152 return md5blks; 153 } 154 function md5blk_array(a) { 155 var md5blks = [], i; 156 for (i = 0; i < 64; i += 4) { 157 md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24); 158 } 159 return md5blks; 160 } 161 function md51(s) { 162 var n = s.length, state = [ 1732584193, -271733879, -1732584194, 271733878 ], i, length, tail, tmp, lo, hi; 163 for (i = 64; i <= n; i += 64) { 164 md5cycle(state, md5blk(s.substring(i - 64, i))); 165 } 166 s = s.substring(i - 64); 167 length = s.length; 168 tail = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; 169 for (i = 0; i < length; i += 1) { 170 tail[i >> 2] |= s.charCodeAt(i) << (i % 4 << 3); 171 } 172 tail[i >> 2] |= 128 << (i % 4 << 3); 173 if (i > 55) { 174 md5cycle(state, tail); 175 for (i = 0; i < 16; i += 1) { 176 tail[i] = 0; 177 } 178 } 179 tmp = n * 8; 180 tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/); 181 lo = parseInt(tmp[2], 16); 182 hi = parseInt(tmp[1], 16) || 0; 183 tail[14] = lo; 184 tail[15] = hi; 185 md5cycle(state, tail); 186 return state; 187 } 188 function md51_array(a) { 189 var n = a.length, state = [ 1732584193, -271733879, -1732584194, 271733878 ], i, length, tail, tmp, lo, hi; 190 for (i = 64; i <= n; i += 64) { 191 md5cycle(state, md5blk_array(a.subarray(i - 64, i))); 192 } 193 a = i - 64 < n ? a.subarray(i - 64) : new Uint8Array(0); 194 length = a.length; 195 tail = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; 196 for (i = 0; i < length; i += 1) { 197 tail[i >> 2] |= a[i] << (i % 4 << 3); 198 } 199 tail[i >> 2] |= 128 << (i % 4 << 3); 200 if (i > 55) { 201 md5cycle(state, tail); 202 for (i = 0; i < 16; i += 1) { 203 tail[i] = 0; 204 } 205 } 206 tmp = n * 8; 207 tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/); 208 lo = parseInt(tmp[2], 16); 209 hi = parseInt(tmp[1], 16) || 0; 210 tail[14] = lo; 211 tail[15] = hi; 212 md5cycle(state, tail); 213 return state; 214 } 215 function rhex(n) { 216 var s = "", j; 217 for (j = 0; j < 4; j += 1) { 218 s += hex_chr[n >> j * 8 + 4 & 15] + hex_chr[n >> j * 8 & 15]; 219 } 220 return s; 221 } 222 function hex(x) { 223 var i; 224 for (i = 0; i < x.length; i += 1) { 225 x[i] = rhex(x[i]); 226 } 227 return x.join(""); 228 } 229 if (hex(md51("hello")) !== "5d41402abc4b2a76b9719d911017c592") ; 230 if (typeof ArrayBuffer !== "undefined" && !ArrayBuffer.prototype.slice) { 231 (function() { 232 function clamp(val, length) { 233 val = val | 0 || 0; 234 if (val < 0) { 235 return Math.max(val + length, 0); 236 } 237 return Math.min(val, length); 238 } 239 ArrayBuffer.prototype.slice = function(from, to) { 240 var length = this.byteLength, begin = clamp(from, length), end = length, num, target, targetArray, sourceArray; 241 if (to !== undefined$1) { 242 end = clamp(to, length); 243 } 244 if (begin > end) { 245 return new ArrayBuffer(0); 246 } 247 num = end - begin; 248 target = new ArrayBuffer(num); 249 targetArray = new Uint8Array(target); 250 sourceArray = new Uint8Array(this, begin, num); 251 targetArray.set(sourceArray); 252 return target; 253 }; 254 })(); 255 } 256 function toUtf8(str) { 257 if (/[\u0080-\uFFFF]/.test(str)) { 258 str = unescape(encodeURIComponent(str)); 259 } 260 return str; 261 } 262 function utf8Str2ArrayBuffer(str, returnUInt8Array) { 263 var length = str.length, buff = new ArrayBuffer(length), arr = new Uint8Array(buff), i; 264 for (i = 0; i < length; i += 1) { 265 arr[i] = str.charCodeAt(i); 266 } 267 return returnUInt8Array ? arr : buff; 268 } 269 function arrayBuffer2Utf8Str(buff) { 270 return String.fromCharCode.apply(null, new Uint8Array(buff)); 271 } 272 function concatenateArrayBuffers(first, second, returnUInt8Array) { 273 var result = new Uint8Array(first.byteLength + second.byteLength); 274 result.set(new Uint8Array(first)); 275 result.set(new Uint8Array(second), first.byteLength); 276 return returnUInt8Array ? result : result.buffer; 277 } 278 function hexToBinaryString(hex) { 279 var bytes = [], length = hex.length, x; 280 for (x = 0; x < length - 1; x += 2) { 281 bytes.push(parseInt(hex.substr(x, 2), 16)); 282 } 283 return String.fromCharCode.apply(String, bytes); 284 } 285 function SparkMD5() { 286 this.reset(); 287 } 288 SparkMD5.prototype.append = function(str) { 289 this.appendBinary(toUtf8(str)); 290 return this; 291 }; 292 SparkMD5.prototype.appendBinary = function(contents) { 293 this._buff += contents; 294 this._length += contents.length; 295 var length = this._buff.length, i; 296 for (i = 64; i <= length; i += 64) { 297 md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i))); 298 } 299 this._buff = this._buff.substring(i - 64); 300 return this; 301 }; 302 SparkMD5.prototype.end = function(raw) { 303 var buff = this._buff, length = buff.length, i, tail = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], ret; 304 for (i = 0; i < length; i += 1) { 305 tail[i >> 2] |= buff.charCodeAt(i) << (i % 4 << 3); 306 } 307 this._finish(tail, length); 308 ret = hex(this._hash); 309 if (raw) { 310 ret = hexToBinaryString(ret); 311 } 312 this.reset(); 313 return ret; 314 }; 315 SparkMD5.prototype.reset = function() { 316 this._buff = ""; 317 this._length = 0; 318 this._hash = [ 1732584193, -271733879, -1732584194, 271733878 ]; 319 return this; 320 }; 321 SparkMD5.prototype.getState = function() { 322 return { 323 buff: this._buff, 324 length: this._length, 325 hash: this._hash.slice() 326 }; 327 }; 328 SparkMD5.prototype.setState = function(state) { 329 this._buff = state.buff; 330 this._length = state.length; 331 this._hash = state.hash; 332 return this; 333 }; 334 SparkMD5.prototype.destroy = function() { 335 delete this._hash; 336 delete this._buff; 337 delete this._length; 338 }; 339 SparkMD5.prototype._finish = function(tail, length) { 340 var i = length, tmp, lo, hi; 341 tail[i >> 2] |= 128 << (i % 4 << 3); 342 if (i > 55) { 343 md5cycle(this._hash, tail); 344 for (i = 0; i < 16; i += 1) { 345 tail[i] = 0; 346 } 347 } 348 tmp = this._length * 8; 349 tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/); 350 lo = parseInt(tmp[2], 16); 351 hi = parseInt(tmp[1], 16) || 0; 352 tail[14] = lo; 353 tail[15] = hi; 354 md5cycle(this._hash, tail); 355 }; 356 SparkMD5.hash = function(str, raw) { 357 return SparkMD5.hashBinary(toUtf8(str), raw); 358 }; 359 SparkMD5.hashBinary = function(content, raw) { 360 var hash = md51(content), ret = hex(hash); 361 return raw ? hexToBinaryString(ret) : ret; 362 }; 363 SparkMD5.ArrayBuffer = function() { 364 this.reset(); 365 }; 366 SparkMD5.ArrayBuffer.prototype.append = function(arr) { 367 var buff = concatenateArrayBuffers(this._buff.buffer, arr, true), length = buff.length, i; 368 this._length += arr.byteLength; 369 for (i = 64; i <= length; i += 64) { 370 md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i))); 371 } 372 this._buff = i - 64 < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0); 373 return this; 374 }; 375 SparkMD5.ArrayBuffer.prototype.end = function(raw) { 376 var buff = this._buff, length = buff.length, tail = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], i, ret; 377 for (i = 0; i < length; i += 1) { 378 tail[i >> 2] |= buff[i] << (i % 4 << 3); 379 } 380 this._finish(tail, length); 381 ret = hex(this._hash); 382 if (raw) { 383 ret = hexToBinaryString(ret); 384 } 385 this.reset(); 386 return ret; 387 }; 388 SparkMD5.ArrayBuffer.prototype.reset = function() { 389 this._buff = new Uint8Array(0); 390 this._length = 0; 391 this._hash = [ 1732584193, -271733879, -1732584194, 271733878 ]; 392 return this; 393 }; 394 SparkMD5.ArrayBuffer.prototype.getState = function() { 395 var state = SparkMD5.prototype.getState.call(this); 396 state.buff = arrayBuffer2Utf8Str(state.buff); 397 return state; 398 }; 399 SparkMD5.ArrayBuffer.prototype.setState = function(state) { 400 state.buff = utf8Str2ArrayBuffer(state.buff, true); 401 return SparkMD5.prototype.setState.call(this, state); 402 }; 403 SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy; 404 SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish; 405 SparkMD5.ArrayBuffer.hash = function(arr, raw) { 406 var hash = md51_array(new Uint8Array(arr)), ret = hex(hash); 407 return raw ? hexToBinaryString(ret) : ret; 408 }; 409 return SparkMD5; 410 })); 411})(sparkMd5); 412 413var SparkMD5 = sparkMd5.exports; 414 415const fileSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice; 416 417class FileChecksum { 418 static create(file, callback) { 419 const instance = new FileChecksum(file); 420 instance.create(callback); 421 } 422 constructor(file) { 423 this.file = file; 424 this.chunkSize = 2097152;
425 this.chunkCount = Math.ceil(this.file.size / this.chunkSize); 426 this.chunkIndex = 0; 427 } 428 create(callback) { 429 this.callback = callback; 430 this.md5Buffer = new SparkMD5.ArrayBuffer; 431 this.fileReader = new FileReader; 432 this.fileReader.addEventListener("load", (event => this.fileReaderDidLoad(event))); 433 this.fileReader.addEventListener("error", (event => this.fileReaderDidError(event))); 434 this.readNextChunk(); 435 } 436 fileReaderDidLoad(event) { 437 this.md5Buffer.append(event.target.result); 438 if (!this.readNextChunk()) { 439 const binaryDigest = this.md5Buffer.end(true); 440 const base64digest = btoa(binaryDigest); 441 this.callback(null, base64digest); 442 } 443 } 444 fileReaderDidError(event) { 445 this.callback(`Error reading ${this.file.name}`); 446 } 447 readNextChunk() { 448 if (this.chunkIndex < this.chunkCount || this.chunkIndex == 0 && this.chunkCount == 0) { 449 const start = this.chunkIndex * this.chunkSize; 450 const end = Math.min(start + this.chunkSize, this.file.size); 451 const bytes = fileSlice.call(this.file, start, end); 452 this.fileReader.readAsArrayBuffer(bytes); 453 this.chunkIndex++; 454 return true; 455 } else { 456 return false; 457 } 458 } 459} 460 461function getMetaValue(name) { 462 const element = findElement(document.head, `meta[name="${name}"]`); 463 if (element) { 464 return element.getAttribute("content"); 465 } 466} 467 468function findElements(root, selector) { 469 if (typeof root == "string") { 470 selector = root; 471 root = document; 472 } 473 const elements = root.querySelectorAll(selector); 474 return toArray(elements); 475} 476 477function findElement(root, selector) { 478 if (typeof root == "string") { 479 selector = root; 480 root = document; 481 } 482 return root.querySelector(selector); 483} 484 485function dispatchEvent(element, type, eventInit = {}) { 486 const {disabled: disabled} = element;
487 const {bubbles: bubbles, cancelable: cancelable, detail: detail} = eventInit; 488 const event = document.createEvent("Event"); 489 event.initEvent(type, bubbles || true, cancelable || true); 490 event.detail = detail || {}; 491 try { 492 element.disabled = false; 493 element.dispatchEvent(event); 494 } finally { 495 element.disabled = disabled; 496 } 497 return event; 498} 499 500function toArray(value) { 501 if (Array.isArray(value)) { 502 return value; 503 } else if (Array.from) { 504 return Array.from(value); 505 } else { 506 return [].slice.call(value); 507 } 508} 509 510class BlobRecord { 511 constructor(file, checksum, url, customHeaders = {}) { 512 this.file = file; 513 this.attributes = { 514 filename: file.name, 515 content_type: file.type || "application/octet-stream", 516 byte_size: file.size, 517 checksum: checksum 518 }; 519 this.xhr = new XMLHttpRequest; 520 this.xhr.open("POST", url, true); 521 this.xhr.responseType = "json"; 522 this.xhr.setRequestHeader("Content-Type", "application/json"); 523 this.xhr.setRequestHeader("Accept", "application/json"); 524 this.xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 525 Object.keys(customHeaders).forEach((headerKey => { 526 this.xhr.setRequestHeader(headerKey, customHeaders[headerKey]); 527 })); 528 const csrfToken = getMetaValue("csrf-token"); 529 if (csrfToken != undefined) { 530 this.xhr.setRequestHeader("X-CSRF-Token", csrfToken); 531 } 532 this.xhr.addEventListener("load", (event => this.requestDidLoad(event))); 533 this.xhr.addEventListener("error", (event => this.requestDidError(event))); 534 } 535 get status() { 536 return this.xhr.status; 537 } 538 get response() { 539 const {responseType: responseType, response: response} = this.xhr; 540 if (responseType == "json") { 541 return response; 542 } else { 543 return JSON.parse(response); 544 } 545 } 546 create(callback) { 547 this.callback = callback; 548 this.xhr.send(JSON.stringify({ 549 blob: this.attributes 550 })); 551 } 552 requestDidLoad(event) { 553 if (this.status >= 200 && this.status < 300) { 554 const {response: response} = this; 555 const {direct_upload: direct_upload} = response; 556 delete response.direct_upload; 557 this.attributes = response; 558 this.directUploadData = direct_upload; 559 this.callback(null, this.toJSON()); 560 } else { 561 this.requestDidError(event); 562 } 563 } 564 requestDidError(event) { 565 this.callback(`Error creating Blob for "${this.file.name}". Status: ${this.status}`); 566 } 567 toJSON() { 568 const result = {}; 569 for (const key in this.attributes) { 570 result[key] = this.attributes[key]; 571 } 572 return result; 573 } 574} 575 576class BlobUpload { 577 constructor(blob) { 578 this.blob = blob; 579 this.file = blob.file; 580 const {url: url, headers: headers} = blob.directUploadData; 581 this.xhr = new XMLHttpRequest; 582 this.xhr.open("PUT", url, true); 583 this.xhr.responseType = "text"; 584 for (const key in headers) { 585 this.xhr.setRequestHeader(key, headers[key]); 586 } 587 this.xhr.addEventListener("load", (event => this.requestDidLoad(event))); 588 this.xhr.addEventListener("error", (event => this.requestDidError(event))); 589 } 590 create(callback) { 591 this.callback = callback; 592 this.xhr.send(this.file.slice()); 593 } 594 requestDidLoad(event) { 595 const {status: status, response: response} = this.xhr; 596 if (status >= 200 && status < 300) { 597 this.callback(null, response); 598 } else { 599 this.requestDidError(event); 600 } 601 } 602 requestDidError(event) { 603 this.callback(`Error storing "${this.file.name}". Status: ${this.xhr.status}`); 604 } 605} 606 607let id = 0; 608 609class DirectUpload { 610 constructor(file, url, delegate, customHeaders = {}) { 611 this.id = ++id; 612 this.file = file; 613 this.url = url; 614 this.delegate = delegate; 615 this.customHeaders = customHeaders; 616 } 617 create(callback) { 618 FileChecksum.create(this.file, ((error, checksum) => { 619 if (error) { 620 callback(error); 621 return; 622 } 623 const blob = new BlobRecord(this.file, checksum, this.url, this.customHeaders); 624 notify(this.delegate, "directUploadWillCreateBlobWithXHR", blob.xhr); 625 blob.create((error => { 626 if (error) { 627 callback(error); 628 } else { 629 const upload = new BlobUpload(blob); 630 notify(this.delegate, "directUploadWillStoreFileWithXHR", upload.xhr); 631 upload.create((error => { 632 if (error) { 633 callback(error); 634 } else { 635 callback(null, blob.toJSON()); 636 } 637 })); 638 } 639 })); 640 })); 641 } 642} 643 644function notify(object, methodName, ...messages) { 645 if (object && typeof object[methodName] == "function") { 646 return object[methodName](...messages); 647 } 648} 649 650class DirectUploadController { 651 constructor(input, file) { 652 this.input = input; 653 this.file = file; 654 this.directUpload = new DirectUpload(this.file, this.url, this); 655 this.dispatch("initialize"); 656 } 657 start(callback) { 658 const hiddenInput = document.createElement("input"); 659 hiddenInput.type = "hidden"; 660 hiddenInput.name = this.input.name; 661 this.input.insertAdjacentElement("beforebegin", hiddenInput); 662 this.dispatch("start"); 663 this.directUpload.create(((error, attributes) => { 664 if (error) { 665 hiddenInput.parentNode.removeChild(hiddenInput); 666 this.dispatchError(error); 667 } else { 668 hiddenInput.value = attributes.signed_id; 669 } 670 this.dispatch("end"); 671 callback(error); 672 })); 673 } 674 uploadRequestDidProgress(event) { 675 const progress = event.loaded / event.total * 90; 676 if (progress) { 677 this.dispatch("progress", { 678 progress: progress 679 }); 680 } 681 } 682 get url() { 683 return this.input.getAttribute("data-direct-upload-url"); 684 } 685 dispatch(name, detail = {}) { 686 detail.file = this.file; 687 detail.id = this.directUpload.id;
688 return dispatchEvent(this.input, `direct-upload:${name}`, { 689 detail: detail 690 }); 691 } 692 dispatchError(error) { 693 const event = this.dispatch("error", { 694 error: error 695 }); 696 if (!event.defaultPrevented) { 697 alert(error); 698 } 699 } 700 directUploadWillCreateBlobWithXHR(xhr) { 701 this.dispatch("before-blob-request", { 702 xhr: xhr 703 }); 704 } 705 directUploadWillStoreFileWithXHR(xhr) { 706 this.dispatch("before-storage-request", { 707 xhr: xhr 708 }); 709 xhr.upload.addEventListener("progress", (event => this.uploadRequestDidProgress(event))); 710 xhr.upload.addEventListener("loadend", (() => { 711 this.simulateResponseProgress(xhr); 712 })); 713 } 714 simulateResponseProgress(xhr) { 715 let progress = 90; 716 const startTime = Date.now(); 717 const updateProgress = () => { 718 const elapsed = Date.now() - startTime; 719 const estimatedResponseTime = this.estimateResponseTime(); 720 const responseProgress = Math.min(elapsed / estimatedResponseTime, 1); 721 progress = 90 + responseProgress * 9; 722 this.dispatch("progress", { 723 progress: progress 724 }); 725 if (xhr.readyState !== XMLHttpRequest.DONE && progress < 99) { 726 requestAnimationFrame(updateProgress); 727 } 728 }; 729 xhr.addEventListener("loadend", (() => { 730 this.dispatch("progress", { 731 progress: 100 732 }); 733 })); 734 requestAnimationFrame(updateProgress); 735 } 736 estimateResponseTime() { 737 const fileSize = this.file.size; 738 const MB = 1024 * 1024; 739 if (fileSize < MB) { 740 return 1e3; 741 } else if (fileSize < 10 * MB) { 742 return 2e3; 743 } else { 744 return 3e3 + fileSize / MB * 50; 745 } 746 } 747} 748 749const inputSelector = "input[type=file][data-direct-upload-url]:not([disabled])"; 750 751class DirectUploadsController { 752 constructor(form) { 753 this.form = form; 754 this.inputs = findElements(form, inputSelector).filter((input => input.files.length)); 755 } 756 start(callback) { 757 const controllers = this.createDirectUploadControllers(); 758 const startNextController = () => { 759 const controller = controllers.shift(); 760 if (controller) { 761 controller.start((error => { 762 if (error) { 763 callback(error); 764 this.dispatch("end"); 765 } else { 766 startNextController(); 767 } 768 })); 769 } else { 770 callback(); 771 this.dispatch("end"); 772 } 773 }; 774 this.dispatch("start"); 775 startNextController(); 776 } 777 createDirectUploadControllers() { 778 const controllers = []; 779 this.inputs.forEach((input => { 780 toArray(input.files).forEach((file => { 781 const controller = new DirectUploadController(input, file); 782 controllers.push(controller); 783 })); 784 })); 785 return controllers; 786 } 787 dispatch(name, detail = {}) { 788 return dispatchEvent(this.form, `direct-uploads:${name}`, { 789 detail: detail 790 }); 791 } 792} 793 794const processingAttribute = "data-direct-uploads-processing"; 795 796const submitButtonsByForm = new WeakMap; 797 798let started = false; 799 800function start() { 801 if (!started) { 802 started = true; 803 document.addEventListener("click", didClick, true); 804 document.addEventListener("submit", didSubmitForm, true); 805 document.addEventListener("ajax:before", didSubmitRemoteElement); 806 } 807} 808 809function didClick(event) { 810 const button = event.target.closest("button, input"); 811 if (button && button.type === "submit" && button.form) { 812 submitButtonsByForm.set(button.form, button); 813 } 814} 815 816function didSubmitForm(event) { 817 handleFormSubmissionEvent(event); 818} 819 820function didSubmitRemoteElement(event) { 821 if (event.target.tagName == "FORM") { 822 handleFormSubmissionEvent(event); 823 } 824} 825 826function handleFormSubmissionEvent(event) { 827 const form = event.target; 828 if (form.hasAttribute(processingAttribute)) { 829 event.preventDefault(); 830 return; 831 } 832 const controller = new DirectUploadsController(form); 833 const {inputs: inputs} = controller; 834 if (inputs.length) { 835 event.preventDefault(); 836 form.setAttribute(processingAttribute, ""); 837 inputs.forEach(disable); 838 controller.start((error => { 839 form.removeAttribute(processingAttribute); 840 if (error) {
841 inputs.forEach(enable); 842 } else { 843 submitForm(form); 844 } 845 })); 846 } 847} 848 849function submitForm(form) { 850 let button = submitButtonsByForm.get(form) || findElement(form, "input[type=submit], button[type=submit]"); 851 if (button) { 852 const {disabled: disabled} = button; 853 button.disabled = false; 854 button.focus(); 855 button.click(); 856 button.disabled = disabled; 857 } else { 858 button = document.createElement("input"); 859 button.type = "submit"; 860 button.style.display = "none"; 861 form.appendChild(button); 862 button.click(); 863 form.removeChild(button); 864 } 865 submitButtonsByForm.delete(form); 866} 867 868function disable(input) { 869 input.disabled = true; 870} 871 872function enable(input) { 873 input.disabled = false; 874} 875 876function autostart() { 877 if (window.ActiveStorage) { 878 start(); 879 } 880} 881 882setTimeout(autostart, 1); 883 884export { DirectUpload, DirectUploadController, DirectUploadsController, dispatchEvent, start };
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.