uploadcare-rails 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -17,5 +17,8 @@ module Uploadcare::Rails::Inject
17
17
  def self.try_inject
18
18
  ActiveRecord::Base.send(:include, Uploadcare::Rails::ActiveRecord) if defined? ActiveRecord
19
19
  ActionView::Helpers::FormBuilder.send(:include, Uploadcare::Rails::FormBuilder) if defined? ActionView
20
+ if defined? SimpleForm::Inputs
21
+ require 'uploadcare-rails/simple_form'
22
+ end
20
23
  end
21
24
  end
@@ -0,0 +1,22 @@
1
+ require 'uploadcare-rails'
2
+
3
+ module SimpleForm::Inputs
4
+ class UploadcareInput < Base
5
+ def input
6
+ config = ::Uploadcare::Rails.config
7
+ options = {}
8
+ options[:role] ||= case config["widget_type"]
9
+ when "plain"
10
+ "uploadcare-plain-uploader"
11
+ when "line"
12
+ "uploadcare-line-uploader"
13
+ else
14
+ "uploadcare-plain-uploader"
15
+ end
16
+ options["data-public-key"] ||= config["public_key"]
17
+ options[:type] ||= "hidden"
18
+
19
+ "#{@builder.input_field(attribute_name, input_html_options.merge(options))}".html_safe
20
+ end
21
+ end
22
+ end
@@ -1,5 +1,5 @@
1
1
  module Uploadcare
2
2
  module Rails
3
- VERSION = "0.1.0"
3
+ VERSION = "0.1.1"
4
4
  end
5
5
  end
@@ -0,0 +1,1777 @@
1
+ /*
2
+ * Copyright (c) 2011 UploadCare
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+ ;(function () {
24
+ "use strict";
25
+
26
+ window.UploadCare = {
27
+
28
+ // Function, which are waiting UploadCare initializing.
29
+ _readyCallbacks: [],
30
+
31
+ // jQuery version for UploadCare.
32
+ _jQueryMinVersion: [1, 5, 0],
33
+
34
+ // URL to get jQuery from CDN.
35
+ _jQueryCDN: 'http://ajax.googleapis.com/ajax/libs/' +
36
+ 'jquery/1.6.2/jquery.js',
37
+
38
+ // Is UploadCare initialized.
39
+ initialized: false,
40
+
41
+ // jQuery object for UploadCare.
42
+ jQuery: null,
43
+
44
+ // API public key.
45
+ publicKey: null,
46
+
47
+ //Base URL
48
+ uploadBaseUrl: "http://upload.uploadcare.com",
49
+
50
+ //URLs for widget internals. Set before initialization.
51
+ urls: {
52
+ byIframe: {
53
+ upload: "",
54
+ },
55
+ byUrl: {
56
+ upload: "",
57
+ status: ""
58
+ },
59
+ byXHR2: {
60
+ upload: ""
61
+ },
62
+ fileInfo: ""
63
+ },
64
+
65
+ instances: {},
66
+
67
+ // Call `callback`, when HTML is loaded.
68
+ _domReady: function (callback) {
69
+ var self = this;
70
+ var isLoaded = false;
71
+ var unbind = null;
72
+ var loaded = function () {
73
+ if ( isLoaded ) {
74
+ return;
75
+ }
76
+ isLoaded = true;
77
+ unbind();
78
+ callback.call(self)
79
+ }
80
+
81
+ if ( document.readyState === 'complete' ) {
82
+ callback.call(this);
83
+ return;
84
+ } else if ( document.addEventListener ) {
85
+ unbind = function () {
86
+ document.removeEventListener('DOMContentLoaded', loaded, false);
87
+ }
88
+ document.addEventListener('DOMContentLoaded', loaded, false);
89
+ window.addEventListener('load', loaded, false);
90
+ } else {
91
+ unbind = function () {
92
+ document.detachEvent('onreadystatechange', loaded, false);
93
+ }
94
+ document.attachEvent('onreadystatechange', loaded, false);
95
+ window.attachEvent('load', loaded, false);
96
+ }
97
+ },
98
+
99
+ // Call all callbacks, which were added by `ready` method.
100
+ _callReadyCallbacks: function () {
101
+ this.initialized = true;
102
+ for (var i = 0; i < this._readyCallbacks.length; i++) {
103
+ this._readyCallbacks[i].call(this, this.jQuery);
104
+ }
105
+ },
106
+
107
+ // Generate UUID for upload file ID.
108
+ // Taken from http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
109
+ _uuid: function () {
110
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.
111
+ replace(/[xy]/g, function(c) {
112
+ var r = Math.random() * 16|0,
113
+ v = (c == 'x' ? r : (r&0x3|0x8));
114
+ return v.toString(16);
115
+ });
116
+ },
117
+
118
+ // Check, that jQuery loaded and have correct version. `noCallback` will be
119
+ // call, if page doesn’t have jQuery, `versionCallback` – if page have
120
+ // wrong version of jQuery.
121
+ _checkJQuery: function (jQuery, noCallback, versionCallback) {
122
+ if ( !jQuery || typeof(jQuery) === "undefined" ) {
123
+ noCallback.call(this);
124
+ return;
125
+ }
126
+ var require, subversion, version = jQuery.fn.jquery.split('.');
127
+ for (var i = 0; i < this._jQueryMinVersion.length; i++) {
128
+ require = this._jQueryMinVersion[i]
129
+ subversion = parseInt(version[i]);
130
+ if ( require > subversion ) {
131
+ versionCallback.call(this);
132
+ return;
133
+ } else if ( require < subversion ) {
134
+ this._getJQuery();
135
+ return;
136
+ }
137
+ }
138
+ this._getJQuery();
139
+ },
140
+
141
+ // Copy jQuery to UploadCare object and run all callbacks.
142
+ _getJQuery: function () {
143
+ if ( typeof(window.jQuery) !== "undefined" ) {
144
+ this.jQuery = window.jQuery;
145
+ }
146
+ this._callReadyCallbacks();
147
+ },
148
+
149
+ // Load own jQuery for UploadCare.
150
+ _loadJQuery: function () {
151
+ var script = document.createElement('script');
152
+ script.src = this._jQueryCDN;
153
+ script.onload = script.onreadystatechange = function () {
154
+ if ( typeof(window.jQuery) !== "undefined" ) {
155
+ window.jQuery.noConflict();
156
+ UploadCare.jQuery = window.jQuery;
157
+ window.jQuery = UploadCare._originjQuery;
158
+ delete UploadCare._originjQuery;
159
+ UploadCare._callReadyCallbacks();
160
+ }
161
+ };
162
+
163
+ var head = document.getElementsByTagName('head')[0];
164
+ if ( !head ) {
165
+ head = document.body;
166
+ }
167
+
168
+ if ( typeof(window.jQuery) !== "undefined" ) {
169
+ this._originjQuery = window.jQuery;
170
+ }
171
+
172
+ head.appendChild(script);
173
+ },
174
+
175
+ // Get user public key from current script tag.
176
+ // If no key presents, try to get public key from input tag.
177
+ _getPublicKey: function () {
178
+ var scripts = document.getElementsByTagName('script');
179
+ var current = scripts[scripts.length - 1];
180
+ this.publicKey = current.getAttribute('data-public-key');
181
+
182
+ if ( UploadCare.publicKey === void 0 || UploadCare.publicKey === null ) {
183
+ UploadCare.ready(function($) {
184
+ $(document).ready(function() {
185
+ var input = $('input[data-public-key]');
186
+ UploadCare.publicKey = input.attr('data-public-key');
187
+ });
188
+ });
189
+ }
190
+ },
191
+
192
+ // Return init method for widget. It will try to find inputs with some
193
+ // `role` in DOM or jQuery node and call widget’s `enlive` method.
194
+ _widgetInit: function (role) {
195
+ return function (base) {
196
+ var widget = this;
197
+ UploadCare.ready(function ($) {
198
+ var inputs = null;
199
+ var $ = UploadCare.jQuery;
200
+ if ( typeof(base.jquery) == 'undefined' ) {
201
+ if ( base.tagName == 'INPUT') {
202
+ inputs = $(base);
203
+ }
204
+ } else {
205
+ if ( base.is('input') ) {
206
+ inputs = base;
207
+ }
208
+ }
209
+ if ( inputs === null ) {
210
+ inputs = $('[role~=' + role + ']', base);
211
+ }
212
+
213
+ inputs.each(function (_, input) {
214
+ var instanceId = UploadCare._id();
215
+
216
+ if ( typeof(UploadCare.instances[instanceId]) === 'undefined' ) {
217
+ UploadCare.instances[instanceId] = {};
218
+ }
219
+ input.setAttribute('data-instance-id', instanceId);
220
+
221
+ if ( input.getAttribute('data-upload-base-url') !== null ) {
222
+ UploadCare.instances[instanceId].uploadBaseUrl = input.getAttribute('data-upload-base-url');
223
+ UploadCare.setUrls(input.getAttribute('data-upload-base-url'));
224
+ } else {
225
+ UploadCare.instances[instanceId].uploadBaseUrl = UploadCare.uploadBaseUrl;
226
+ }
227
+
228
+ UploadCare.instances[instanceId].urls = UploadCare.makeUrls( UploadCare.instances[instanceId].uploadBaseUrl );
229
+
230
+ if( input.getAttribute('data-public-key') !== null ) {
231
+ UploadCare.instances[instanceId].publicKey = input.getAttribute('data-public-key');
232
+ } else {
233
+ UploadCare.instances[instanceId].publicKey = UploadCare.publicKey;
234
+ }
235
+
236
+ if( input.getAttribute('data-override-style') !== null ) {
237
+ UploadCare.instances[instanceId].overrideStyle = input.getAttribute('data-override-style');
238
+ }
239
+
240
+ if( input.getAttribute('data-only-images') !== null ) {
241
+ UploadCare.instances[instanceId].onlyImages = parseInt( input.getAttribute('data-only-images') );
242
+ }
243
+
244
+ UploadCare._makeStateful(UploadCare.instances[instanceId]);
245
+
246
+ widget.enlive(input);
247
+ });
248
+ });
249
+ }
250
+ },
251
+
252
+ // Add `translation` in some `locale` as `widget` messages.
253
+ //
254
+ // Instead of replace `widget.messages` it will doesn’t change object link,
255
+ // so you can copy `widget.messages` to `t` variable shortcut in
256
+ // widget code, before add translation.
257
+ //
258
+ // Also it will set `messages.locale` with current locale code.
259
+ _translate: function (widget, locale, translation) {
260
+ widget.messages.locale = locale;
261
+ for ( var name in translation ) {
262
+ widget.messages[name] = translation[name];
263
+ }
264
+ },
265
+
266
+ // Create Deferred promise object and add jQuery AJAX like proxy callbacks.
267
+ _promise: function (deferred, extend) {
268
+ if ( typeof(extend) == 'undefined' ) {
269
+ extend = {
270
+ progress: function () {}
271
+ };
272
+ }
273
+
274
+ if ( typeof(deferred.state) == 'undefined' ) {
275
+ deferred.state = function() {
276
+ return deferred.isResolved() ? "resolved" : (deferred.isRejected() ? "rejected" : "pending");
277
+ }
278
+ }
279
+
280
+ var promise = deferred.promise(extend);
281
+ promise.success = promise.done;
282
+ promise.error = promise.fail;
283
+ promise.complete = promise.always;
284
+ return promise;
285
+ },
286
+
287
+ // Return upload params by options hash.
288
+ _params: function (options) {
289
+ if ( typeof(options) == 'undefined' ) {
290
+ options = { };
291
+ }
292
+
293
+ var params = {
294
+ UPLOADCARE_PUB_KEY: options.publicKey || this.publicKey,
295
+ };
296
+ if ( options.meduim ) {
297
+ params.UPLOADCARE_MEDIUM = options.meduim;
298
+ }
299
+ if ( options.instanceId ) {
300
+ params.UPLOADCARE_INSTANCE_ID = options.instanceId;
301
+ }
302
+
303
+ return params;
304
+ },
305
+
306
+ _makeStateful: function(object) {
307
+ object.state = {};
308
+
309
+ var stateful = {
310
+ current: 'idle',
311
+ previous: null,
312
+ callbacks: {},
313
+ set: function(state) {
314
+ this.previous = this.current;
315
+ this.current = state;
316
+ //console.log('State set to ' + state + ' from ' + this.previous);
317
+ this.runCallbacks(state);
318
+ },
319
+ get: function() {
320
+ return this.current;
321
+ },
322
+ setCallback: function(state, callback) {
323
+ if ( typeof(this.callbacks[state]) == 'undefined' ) {
324
+ this.callbacks[state] = [];
325
+ }
326
+ this.callbacks[state].push(callback);
327
+
328
+ if ( this.get() == state ) {
329
+ this.runCallbacks(state);
330
+ }
331
+
332
+ return this;
333
+ },
334
+ runCallbacks: function(state) {
335
+ var $ = UploadCare.jQuery;
336
+ var prev = this.previous;
337
+ if ( typeof(this.callbacks[state]) !== 'undefined' && this.callbacks[state].length > 0 ) {
338
+ var callbacks = this.callbacks[state];
339
+ $(callbacks).each(function() {
340
+ this($, prev);
341
+ });
342
+ }
343
+ },
344
+ clearCallbacks: function(state) {
345
+ delete this.callbacks[state];
346
+ }
347
+ }
348
+
349
+ object.state = stateful;
350
+ },
351
+
352
+ _id: function() {
353
+ return 'id' + parseInt(Math.random() * (100000 - 1) + 1);
354
+ },
355
+
356
+ // Initialize jQuery object and call all function added by `ready`.
357
+ init: function () {
358
+ var _jq;
359
+
360
+ if ( typeof(window.jQuery) !== "undefined" ) {
361
+ _jq = window.jQuery;
362
+ }
363
+
364
+ this._checkJQuery(_jq,
365
+ function () {
366
+ this._domReady(function () {
367
+ this._checkJQuery(_jq,
368
+ this._loadJQuery, this._loadJQuery);
369
+ });
370
+ },
371
+ this._loadJQuery);
372
+ },
373
+
374
+ // Call `callback` when UploadCare will be initialized. First argument will
375
+ // by jQuery object.
376
+ ready: function (callback) {
377
+ if ( this.initialized ) {
378
+ callback.call(this, this.jQuery);
379
+ } else {
380
+ this._readyCallbacks.push(callback)
381
+ }
382
+ },
383
+
384
+ // Upload file to UploadCare and return jQuery Deferred promise.
385
+ // UUID for uploaded file will be send to `done` callback.
386
+ //
387
+ // If `file` will be file input, `upload` will use iframe method to upload
388
+ // file from user.
389
+ //
390
+ // If `file` will be string, `upload` will request UploadCare servers to
391
+ // upload file from this URL. In this case promise will contain `progress`
392
+ // function to add callbacks to uploading status.
393
+ upload: function (file, options) {
394
+ var params = this._params(options);
395
+
396
+ if ( typeof(file) == 'string' ) {
397
+ return this.byUrl.upload(file, params);
398
+ } else {
399
+ return this.byIframe.upload(file, params);
400
+ }
401
+ },
402
+
403
+ makeUrls: function(uploadBaseUrl) {
404
+ uploadBaseUrl = typeof(uploadBaseUrl) === "undefined" ? this.uploadBaseUrl : uploadBaseUrl;
405
+
406
+ if ( uploadBaseUrl.slice(-1) === "/" ) {
407
+ uploadBaseUrl = uploadBaseUrl.slice(0, -1);
408
+ }
409
+
410
+ var urls = {
411
+ byUrl: {
412
+ upload: "" + uploadBaseUrl + "/from_url/",
413
+ status: "" + uploadBaseUrl + "/status/"
414
+ },
415
+ byIframe: {
416
+ upload: "" + uploadBaseUrl + "/iframe/"
417
+ },
418
+ byXHR2: {
419
+ upload: "" + uploadBaseUrl + "/iframe/"
420
+ },
421
+ fileInfo: "" + uploadBaseUrl + "/info/"
422
+ }
423
+
424
+ return urls;
425
+ },
426
+
427
+ setUrls: function(uploadBaseUrl) {
428
+ this.urls = this.makeUrls(uploadBaseUrl);
429
+ },
430
+
431
+ getInstance: function(instanceId) {
432
+ return UploadCare.instances[instanceId];
433
+ },
434
+
435
+ getInstanceOptions: function(instanceId) {
436
+ var opts = { };
437
+ if ( typeof(UploadCare.instances[instanceId]) !== 'undefined' ) {
438
+ opts = UploadCare.instances[instanceId];
439
+ }
440
+ return opts;
441
+ }
442
+ };
443
+
444
+ // Driver to upload file by iframe.
445
+ UploadCare.byIframe = {
446
+ // ID counter to have unique iframe IDs.
447
+ _lastIframeId: 0,
448
+
449
+ // Create iframe to upload file by AJAX.
450
+ _createIframe: function (instanceId) {
451
+ this._lastIframeId += 1;
452
+ var id = 'uploadcareIframe' + this._lastIframeId;
453
+ var iframe = UploadCare.jQuery('<iframe />').attr({ id: id, name: id });
454
+ iframe.css('position', 'absolute').css('top', '-9999px');
455
+
456
+ if ( instanceId !== void(0) ) {
457
+ iframe.addClass(instanceId);
458
+ }
459
+
460
+ iframe.appendTo('body');
461
+ return iframe;
462
+ },
463
+
464
+ _getUploadUrl: function() {
465
+ return UploadCare.urls.byIframe.upload;
466
+ },
467
+
468
+ // Create form, link it action to `iframe` and clone `file` inside.
469
+ _createFormForIframe: function (iframe, file, instanceId) {
470
+ var uploadUrl = this._getUploadUrl();
471
+
472
+ if ( instanceId ) {
473
+ uploadUrl = UploadCare.getInstanceOptions( instanceId ).urls.byIframe.upload;
474
+ }
475
+
476
+ var form = UploadCare.jQuery('<form />').attr({
477
+ method: 'POST',
478
+ action: uploadUrl,
479
+ enctype: 'multipart/form-data',
480
+ target: iframe.attr('id')
481
+ });
482
+ form.css('position', 'absolute').css('top', '-9999px');
483
+
484
+ var next = file.clone(true);
485
+ next.insertBefore(file);
486
+ form.appendTo('body');
487
+ file.appendTo(form);
488
+
489
+ return form;
490
+ },
491
+
492
+ // Upload file to UploadCare by iframe method and return jQuery Deferred.
493
+ upload: function (file, params) {
494
+ var id = UploadCare._uuid();
495
+ var instanceId = null;
496
+ var iframe = null;
497
+ var form = null;
498
+ var onlyImages = false;
499
+
500
+ if( typeof(params.UPLOADCARE_INSTANCE_ID) !== 'undefined' ) {
501
+ instanceId = params.UPLOADCARE_INSTANCE_ID;
502
+ delete params.UPLOADCARE_INSTANCE_ID;
503
+ }
504
+
505
+ iframe = this._createIframe(instanceId);
506
+ form = this._createFormForIframe(iframe, file, instanceId);
507
+
508
+ if ( instanceId ) {
509
+ params.UPLOADCARE_PUB_KEY = UploadCare.getInstanceOptions( instanceId ).publicKey;
510
+ }
511
+
512
+ params.UPLOADCARE_FILE_ID = id;
513
+ for ( var name in params ) {
514
+ UploadCare.jQuery('<input type="hidden" />').
515
+ attr('name', name).val(params[name]).appendTo(form);
516
+ }
517
+
518
+ var deferred = UploadCare.jQuery.Deferred();
519
+ var complete = function () {
520
+ iframe.remove();
521
+ form.remove();
522
+ };
523
+
524
+ var submit = function () {
525
+ iframe.bind('load', function (e) {
526
+ e.preventDefault();
527
+ deferred.resolve(id);
528
+ complete();
529
+ });
530
+ iframe.bind('error', function () {
531
+ deferred.reject();
532
+ complete();
533
+ });
534
+
535
+ form.submit();
536
+ };
537
+
538
+ if ( instanceId ) {
539
+ onlyImages = UploadCare.getInstanceOptions( instanceId ).onlyImages === 1 ? true : false;
540
+ }
541
+
542
+ if ( onlyImages ) {
543
+ if ( /(jpg|jpeg|bmp|gif|png)/.test( file.val().split('.')[1] ) === false ) {
544
+ deferred.reject('onlyImages');
545
+ complete();
546
+ } else {
547
+ submit();
548
+ }
549
+ } else {
550
+ submit();
551
+ }
552
+
553
+ return UploadCare._promise(deferred);
554
+ }
555
+ };
556
+
557
+ // Driver to upload file from Internet by URL.
558
+ UploadCare.byUrl = {
559
+ // Period in miliseconds to check uploading progress.
560
+ checkEvery: 1000,
561
+
562
+ _getUploadUrl: function() {
563
+ return UploadCare.urls.byUrl.upload;
564
+ },
565
+
566
+ _getStatusUrl: function() {
567
+ return UploadCare.urls.byUrl.status;
568
+ },
569
+
570
+ // Send request to start uploading from Internet.
571
+ upload: function (url, params) {
572
+ var deferred = UploadCare.jQuery.Deferred();
573
+
574
+ var watchers = [];
575
+ var promise = UploadCare._promise(deferred, {
576
+ progress: function (callback) {
577
+ watchers.push(callback);
578
+ return this;
579
+ }
580
+ });
581
+
582
+ var instanceId = null;
583
+ var uploadUrl = this._getUploadUrl() + "?";
584
+ var checking = null;
585
+ var check = function (token) {
586
+ UploadCare.byUrl.progress(token).
587
+ success(function (data) {
588
+ if ( data.status == 'failure' ) {
589
+ deferred.reject();
590
+ return;
591
+ }
592
+ for ( var i = 0; i < watchers.length; i++ ) {
593
+ watchers[i](data);
594
+ }
595
+ if ( data.status == 'success' ) {
596
+ deferred.resolve(data.file_id);
597
+ }
598
+ }).
599
+ error(function () {
600
+ deferred.reject();
601
+ })
602
+ };
603
+
604
+ if( typeof(params.UPLOADCARE_INSTANCE_ID) !== 'undefined' ) {
605
+ instanceId = params.UPLOADCARE_INSTANCE_ID;
606
+ delete params.UPLOADCARE_INSTANCE_ID;
607
+ }
608
+
609
+ params.pub_key = params.UPLOADCARE_PUB_KEY;
610
+ params.source_url = url;
611
+
612
+ if ( instanceId ) {
613
+ uploadUrl = UploadCare.getInstanceOptions( instanceId ).urls.byUrl.upload + "?";
614
+ params.pub_key = UploadCare.getInstanceOptions( instanceId ).publicKey;
615
+ }
616
+
617
+ delete params.UPLOADCARE_PUB_KEY;
618
+
619
+ for ( var name in params ) {
620
+ uploadUrl = "" + uploadUrl + "" + name + "=" + params[name] + "&";
621
+ }
622
+
623
+ uploadUrl = "" + uploadUrl + "jsoncallback=?";
624
+
625
+ if ( url.length == 0 ) {
626
+ deferred.reject('badFileUrl');
627
+ } else {
628
+ UploadCare.jQuery.ajax(uploadUrl, {dataType: "jsonp"}).
629
+ success(function (data) {
630
+ checking = setInterval(function () {
631
+ check(data.token);
632
+ }, UploadCare.byUrl.checkEvery);
633
+ }).
634
+ error(function () {
635
+ deferred.reject();
636
+ });
637
+ }
638
+
639
+ promise.complete(function() {
640
+ clearInterval(checking);
641
+ })
642
+ return promise;
643
+ },
644
+
645
+ // Request UploadCare about uploading status and return AJAX promise.
646
+ progress: function (token) {
647
+ var statusUrl = "" + this._getStatusUrl() + "?token=" + token + "&jsoncallback=?";
648
+ return UploadCare.jQuery.ajax(statusUrl, {dataType: "jsonp"});
649
+ },
650
+ };
651
+
652
+ UploadCare._getPublicKey();
653
+ UploadCare.setUrls();
654
+ UploadCare.init();
655
+
656
+ })();
657
+ /*
658
+ * Copyright (c) 2011 UploadCare
659
+ *
660
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
661
+ * of this software and associated documentation files (the "Software"), to deal
662
+ * in the Software without restriction, including without limitation the rights
663
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
664
+ * copies of the Software, and to permit persons to whom the Software is
665
+ * furnished to do so, subject to the following conditions:
666
+ *
667
+ * The above copyright notice and this permission notice shall be included in
668
+ * all copies or substantial portions of the Software.
669
+ *
670
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
671
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
672
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
673
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
674
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
675
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
676
+ * SOFTWARE.
677
+ */
678
+
679
+ ;(function () {
680
+ "use strict";
681
+
682
+ // Plain uploader widget without any style.
683
+ //
684
+ // It create simple file input before every hidden input with
685
+ // `uploadcare-plain-uploader` role. When user select file, widget will upload
686
+ // it by AJAX and set file ID to hidden input value.
687
+ //
688
+ // Widget will block form submit during file uploading.
689
+ //
690
+ // Don’t forget to add loading styles, when widget will upload files. Widget
691
+ // add `uploadcare-loading` to closes block with `uploadcare-container` role
692
+ // or to closest form.
693
+ //
694
+ // If you will add AJAX content and want to enlive new hidden inputs, call
695
+ // `UploadCare.Plain.init` with new content:
696
+ //
697
+ // $.get('/next/page', function (html) {
698
+ // var newContent = $(html).appendTo('.list');
699
+ // UploadCare.Plain.init(newContent);
700
+ // });
701
+ //
702
+ // You can add input for upload file from Internal by URL. Just set to hidden
703
+ // input `data-uploadcare-from-url` attribute with jQuery selector. On URL input
704
+ // you can set `data-uploadcare-submit` with selector to submit button.
705
+ // Or you can use `fromUrl` and `fromUrlSubmit` enlive’s options with jQuery
706
+ // objects.
707
+ UploadCare.Plain = {
708
+
709
+ // Add widgets to inputs inside `base`. You can pass DOM node or jQuery
710
+ // objects.
711
+ init: UploadCare._widgetInit('uploadcare-plain-uploader'),
712
+
713
+ // Add file input after hidden `input` to upload file to UploadCare.
714
+ //
715
+ // You can set widget name as `meduim` option.
716
+ enlive: function (input, options) {
717
+ var $ = UploadCare.jQuery;
718
+ var instance, instanceId;
719
+
720
+ if ( typeof(options) == 'undefined' ) {
721
+ options = { };
722
+ }
723
+
724
+ instanceId = $(input).attr('data-instance-id');
725
+
726
+ if ( instanceId ) {
727
+ instance = UploadCare.getInstance( instanceId );
728
+ }
729
+
730
+ if ( instance ) {
731
+ instance.state.set('startEnlive');
732
+ }
733
+
734
+ var hidden = $(input);
735
+ var file = $('<input type="file" name="file" />');
736
+ file.addClass('uploadcare-uploader');
737
+ file.insertAfter(hidden);
738
+
739
+ var upload = function (uploader) {
740
+ var form = uploader.closest('form');
741
+ var contain = uploader.closest('[role~=uploadcare-container]');
742
+ if ( contain.length == 0 ) {
743
+ contain = form;
744
+ }
745
+ contain.addClass('uploadcare-loading');
746
+
747
+ if ( instance ) {
748
+ if ( instance.state.current.match(/fromUrlEnter/) ) {
749
+ instance.state.set('fromUrlBeforeUpload');
750
+ } else {
751
+ instance.state.set('beforeUpload');
752
+ }
753
+
754
+ }
755
+
756
+ var submitBlocking = false;
757
+ form.bind('submit.uploadcare', function() {
758
+ submitBlocking = true;
759
+ return false;
760
+ })
761
+
762
+ var uploadOptions = { meduim: options.meduim || 'plain' };
763
+
764
+ var publicKey = hidden.data('public-key');
765
+ if ( publicKey ) {
766
+ uploadOptions.publicKey = publicKey;
767
+ }
768
+
769
+ if ( instanceId ) {
770
+ uploadOptions.instanceId = instanceId;
771
+ }
772
+
773
+ var uploadFrom = uploader;
774
+ if ( !uploader.is(':file') ) {
775
+ uploadFrom = uploader.val();
776
+ }
777
+
778
+ hidden.trigger('uploadcare-start');
779
+
780
+ if ( instance ) {
781
+ if ( instance.state.current.match(/fromUrl/) ) {
782
+ instance.state.set('fromUrlUpload');
783
+ } else {
784
+ instance.state.set('upload');
785
+ }
786
+ }
787
+
788
+ var uploading = UploadCare.upload(uploadFrom, uploadOptions);
789
+
790
+ uploading.progress(function (data) {
791
+ hidden.trigger('uploadcare-progress', data);
792
+ });
793
+ uploading.error(function (errorCode) {
794
+ errorCode = (void 0 === errorCode || null === errorCode) ? 'network' : errorCode;
795
+ hidden.trigger('uploadcare-error', errorCode);
796
+ hidden.trigger('uploadcare-complete');
797
+ });
798
+ uploading.success(function (id) {
799
+ if ( hidden.val() !== void(0) && hidden.val().length > 0 && hidden.attr('data-barebone') ) {
800
+ var vals = hidden.val().substr(1, hidden.val().length - 2).split(',');
801
+ vals.push(id);
802
+ hidden.val('[' + vals.join(',') + ']');
803
+ } else {
804
+ if (hidden.attr('data-barebone')) {
805
+ hidden.val('['+id+']');
806
+ } else {
807
+ hidden.val(id);
808
+ }
809
+ }
810
+
811
+ hidden.trigger('uploadcare-success', id);
812
+ hidden.trigger('uploadcare-complete');
813
+
814
+ contain.removeClass('uploadcare-loading');
815
+
816
+ if ( instance ) {
817
+ if ( instance.state.current.match(/fromUrl/) ) {
818
+ instance.state.set('fromUrlAfterUpload');
819
+ } else {
820
+ instance.state.set('afterUpload');
821
+ }
822
+
823
+ }
824
+
825
+ form.unbind('submit.uploadcare');
826
+ if ( submitBlocking ) {
827
+ form.submit();
828
+ }
829
+ });
830
+ }
831
+
832
+ var fromUrl = options.fromUrl;
833
+ if ( !fromUrl && hidden.data('uploadcare-from-url') ) {
834
+ var fromUrl = $(hidden.data('uploadcare-from-url'));
835
+ }
836
+ if ( fromUrl ) {
837
+ fromUrl.keypress(function (e) {
838
+ if ( e.keyCode == '13' ) { // Enter
839
+ upload(fromUrl);
840
+ e.preventDefault();
841
+ }
842
+ });
843
+
844
+ var submit = options.fromUrlSubmit;
845
+ if ( !submit && fromUrl.data('uploadcare-submit') ) {
846
+ submit = $(fromUrl.data('uploadcare-submit'));
847
+ }
848
+ if ( submit ) {
849
+ submit.click(function (e) {
850
+ upload(fromUrl);
851
+ e.preventDefault();
852
+ });
853
+ }
854
+ }
855
+
856
+ file.change(function () {
857
+ var file = $(this);
858
+ upload(file);
859
+ });
860
+
861
+ if ( instance ) {
862
+ instance.state.set('endEnlive');
863
+ }
864
+
865
+ return file;
866
+ }
867
+
868
+ };
869
+
870
+ })();
871
+ /*
872
+ * Copyright (c) 2011 UploadCare
873
+ *
874
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
875
+ * of this software and associated documentation files (the "Software"), to deal
876
+ * in the Software without restriction, including without limitation the rights
877
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
878
+ * copies of the Software, and to permit persons to whom the Software is
879
+ * furnished to do so, subject to the following conditions:
880
+ *
881
+ * The above copyright notice and this permission notice shall be included in
882
+ * all copies or substantial portions of the Software.
883
+ *
884
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
885
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
886
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
887
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
888
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
889
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
890
+ * SOFTWARE.
891
+ */
892
+
893
+ ;(function () {
894
+ "use strict";
895
+
896
+ var $;
897
+
898
+ UploadCare.ready(function (jQuery) {
899
+ $ = jQuery;
900
+
901
+ // Animation easing from jQuery Easing plugin by George McGinley Smith.
902
+ $.extend($.easing, {
903
+ easeInOutQuad: function (x, t, b, c, d) {
904
+ if ((t/=d/2) < 1) return c/2*t*t + b;
905
+ return -c/2 * ((--t)*(t-2) - 1) + b;
906
+ },
907
+ easeOutBounce: function (x, t, b, c, d) {
908
+ if ((t/=d) < (1/2.75)) {
909
+ return c*(7.5625*t*t) + b;
910
+ } else if (t < (2/2.75)) {
911
+ return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
912
+ } else if (t < (2.5/2.75)) {
913
+ return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
914
+ } else {
915
+ return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
916
+ }
917
+ }
918
+ });
919
+ });
920
+
921
+ // Default one line upload widget.
922
+ //
923
+ // It create widget before every hidden input with `uploadcare-line-uploader`
924
+ // role. When user select file, widget will upload it by AJAX and set file ID
925
+ // to hidden input value.
926
+ //
927
+ // Widget will block form submit during file uploading.
928
+ //
929
+ // If you will add AJAX content and want to enlive new hidden inputs, call
930
+ // `UploadCare.Line.init` with new content:
931
+ //
932
+ // $.get('/next/page', function (html) {
933
+ // var newContent = $(html).appendTo('.list');
934
+ // UploadCare.Line.init(newContent);
935
+ // });
936
+ UploadCare.Line = {
937
+
938
+ // Text messages. It will be set in translation, see `i18n/` dir.
939
+ messages: { },
940
+
941
+ // CSS for widget. Will be copied from `line-style.sass` by build script.
942
+ style: '',
943
+
944
+ // HTML structure of widget. Will be copied from `line-template.html`
945
+ // by build script.
946
+ html: '',
947
+
948
+ //Stylesheet for IE support
949
+ ie_css_url: 'http://static.uploadcare.com/assets/compat/stylesheets/ie.css',
950
+ //ie_css_url: null,
951
+
952
+ // Add widgets to inputs inside `base`. You can pass DOM node or jQuery
953
+ // objects.
954
+ init: UploadCare._widgetInit('uploadcare-line-uploader'),
955
+
956
+ // Return transition by `path` in messages.
957
+ message: function (path) {
958
+ var node = UploadCare.Line.messages;
959
+ var names = path.split('.');
960
+ for (var i = 0; i < names.length; i++) {
961
+ node = node[names[i]];
962
+ if ( typeof(node) == 'undefined' ) {
963
+ throw('There is no translation for `' + path + '`');
964
+ }
965
+ }
966
+ return node;
967
+ },
968
+
969
+ // Add widget after hidden `input` to upload file to UploadCare.
970
+ enlive: function (input) {
971
+ var hidden = $(input);
972
+
973
+ if ( !($.support.opacity && $.support.htmlSerialize) && (/6.0/.test(navigator.userAgent) || /7.0/.test(navigator.userAgent)) ) {
974
+ if ( this.ie_css_url != null) {
975
+ var link = $('<link />').attr({
976
+ rel: "stylesheet",
977
+ type: "text/css",
978
+ href: this.ie_css_url
979
+ });
980
+ link.appendTo($('head'));
981
+ }
982
+
983
+ $('a.uploadcare-line-computer').click(function() {
984
+ $('input.uploadcare-uploader').click();
985
+ });
986
+ }
987
+
988
+ var html = this.html.replace(/{([^}]+)}/g, function (_, name) {
989
+ if ( name == 'style' ) {
990
+ return UploadCare.Line.style;
991
+ } else if ( name == 'file' ) {
992
+ return '<div data-replace="file"></div>';
993
+ } else if ( name.match(/^t /) ) {
994
+ return UploadCare.Line.message(name.substr(2));
995
+ }
996
+ });
997
+
998
+ var widget = $(html).insertAfter(hidden);
999
+
1000
+ var instanceId = hidden.attr('data-instance-id');
1001
+ var instance;
1002
+
1003
+ if ( instanceId ) {
1004
+ instance = UploadCare.getInstance( instanceId );
1005
+ }
1006
+
1007
+ if ( instance ) {
1008
+ var toggleTab = function(blocks, positive) {
1009
+ var elems = [];
1010
+ $(blocks).each(function() {
1011
+ elems = $.merge(elems, $('a', this));
1012
+ elems = $.merge(elems, $('input', this));
1013
+ });
1014
+
1015
+ if ( positive === void(0) ) {
1016
+ positive = true;
1017
+ }
1018
+
1019
+ $( elems ).each(function() {
1020
+ var tab = $(this).attr('tabindex');
1021
+
1022
+ if ( !tab ) {
1023
+ tab = -1;
1024
+ }
1025
+ if ( tab && tab < 0 && positive ) {
1026
+ $(this).attr('tabindex', '1');
1027
+ } else {
1028
+ $(this).attr('tabindex', '-1');
1029
+ }
1030
+ });
1031
+ }
1032
+
1033
+ var reset = function() {
1034
+ toggleTab(['.uploadcare-line-uploader'], false);
1035
+ }
1036
+
1037
+ var mainWindow = function() {
1038
+ var blocks = ['.uploadcare-line-error-wrapper', '.uploadcare-line-uploading', '.uploadcare-line-filedata', '.uploadcare-line-from-url'];
1039
+
1040
+ if ( widget ) {
1041
+ widget.data('fromUrl', false);
1042
+ }
1043
+
1044
+ toggleTab(['.uploadcare-line-upload']);
1045
+ toggleTab(blocks, false);
1046
+ };
1047
+ var fromUrlWindow = function() {
1048
+ reset();
1049
+ toggleTab(['.uploadcare-line-from-url']);
1050
+ };
1051
+ var uploadingWindow = function() {
1052
+ reset();
1053
+ toggleTab(['.uploadcare-line-uploading']);
1054
+ };
1055
+ var fileInfoWindow = function() {
1056
+ reset();
1057
+ toggleTab(['.uploadcare-line-filedata']);
1058
+ };
1059
+ var fromUrlExit = function($, prev) {
1060
+ var fromUrl = widget.data('fromUrl');
1061
+ if ( fromUrl ) {
1062
+ instance.state.set('fromUrlEnter');
1063
+ } else {
1064
+ instance.state.set('mainWindow');
1065
+ }
1066
+ widget.data('fromUrl', false);
1067
+ };
1068
+ var fromUrlUpload = function() {
1069
+ if ( widget ) {
1070
+ widget.data('fromUrl', true);
1071
+ }
1072
+ }
1073
+
1074
+ widget.data('fromUrl', false);
1075
+
1076
+ instance.state.setCallback('idle', reset);
1077
+ instance.state.setCallback('startEnlive', mainWindow).setCallback('mainWindow', mainWindow).setCallback('upload', uploadingWindow).setCallback('afterUpload', fileInfoWindow);
1078
+ instance.state.setCallback('fromUrlEnter', fromUrlWindow).setCallback('fromUrlUpload', uploadingWindow).setCallback('fromUrlAfterUpload', fileInfoWindow);
1079
+ instance.state.setCallback('fromUrlUpload', fromUrlUpload);
1080
+ instance.state.setCallback('reloadToBase', fromUrlExit);
1081
+ }
1082
+
1083
+ var file = UploadCare.Plain.enlive(hidden, {
1084
+ meduim: 'line',
1085
+ fromUrl: $('.uploadcare-line-url', widget),
1086
+ fromUrlSubmit: $('.uploadcare-line-url-submit', widget)
1087
+ });
1088
+ file.detach().replaceAll($('[data-replace=file]', widget));
1089
+
1090
+ widget.data('info_loaded', false);
1091
+ widget.data('instance', instance);
1092
+ widget.addClass(instanceId);
1093
+
1094
+ $('a', widget).click(false);
1095
+ //$('a', widget).attr({ "tabindex": "-1" });
1096
+ //$('input', widget).attr({ "tabindex": "-1" });
1097
+
1098
+ this.uploadingEvents(widget, hidden);
1099
+ this.fromUrlEvents(widget, hidden);
1100
+
1101
+ hidden.bind('uploadcare-error', function (ev, errorCode) {
1102
+ var fixable = false;
1103
+
1104
+ errorCode = (void 0 === errorCode || null === errorCode) ? 'network' : errorCode;
1105
+ fixable = errorCode === 'onlyImages' ? true : false;
1106
+ UploadCare.Line.showError(widget, errorCode, fixable, function () {
1107
+ UploadCare.Line.hideUploading(widget);
1108
+ });
1109
+ });
1110
+
1111
+ hidden.bind('uploadcare-success', function() {
1112
+ var promise = UploadCare.FileData.fetch(hidden.val(), instanceId);
1113
+
1114
+ promise.success(function(data) {
1115
+ UploadCare.Line.showFileData(data);
1116
+ });
1117
+ promise.error(function(errorCode) {
1118
+ errorCode = (void 0 === errorCode || null === errorCode) ? 'network' : errorCode;
1119
+ hidden.trigger('uploadcare-error', errorCode);
1120
+ });
1121
+ });
1122
+
1123
+ if ( hidden.attr('data-override-style') !== void 0 ) {
1124
+ var overrideStyle = hidden.attr('data-override-style');
1125
+ var styleTag = $('style', widget);
1126
+ var styleContent = styleTag.html();
1127
+
1128
+ styleContent = "" + styleContent + "." + instanceId + "{" + overrideStyle + "}";
1129
+ styleTag.html(styleContent);
1130
+ }
1131
+
1132
+ $(document).trigger('enlive');
1133
+ },
1134
+
1135
+ // Add events for uploading status and animate progress bar.
1136
+ uploadingEvents: function (widget, hidden) {
1137
+ var progress = $('.uploadcare-line-progress div', widget);
1138
+ var end = progress.parent().width() - progress.width();
1139
+ var toLeft = function () {
1140
+ progress.animate({ left: -1 }, 800, 'easeInOutQuad', toRight);
1141
+ }
1142
+ var toRight = function () {
1143
+ progress.animate({ left: end }, 800, 'easeInOutQuad', toLeft);
1144
+ }
1145
+ var instance = widget.data('instance');
1146
+
1147
+ hidden.bind('uploadcare-start', function () {
1148
+ widget.addClass('uploadcare-uploading');
1149
+ widget.find('.uploadcare-line-slider').css({
1150
+ "margin-top": -30
1151
+ });
1152
+ toRight();
1153
+ });
1154
+
1155
+ var total = $('.uploadcare-line-progress').outerWidth();
1156
+
1157
+ progress.data('width', progress.width());
1158
+ hidden.bind('uploadcare-progress', function (e, data) {
1159
+ var percentage = data.done / data.total;
1160
+ progress.stop().css({ left: -1 });
1161
+ progress.width(total * percentage);
1162
+ });
1163
+
1164
+ var uploading = $('.uploadcare-line-uploading', widget);
1165
+ var slider = $('.uploadcare-line-slider', widget);
1166
+
1167
+ $('.uploadcare-line-cancel', uploading).click(function () {
1168
+ slider.css({
1169
+ "margin-top": 0
1170
+ });
1171
+ var iframe = $('iframe[class="' + hidden.attr('data-instance-id') + '"]');
1172
+ if ( iframe.length !== 0 ) {
1173
+ iframe.remove();
1174
+ }
1175
+ UploadCare.Line.hideUploading(widget);
1176
+ });
1177
+
1178
+ var filedata = $('.uploadcare-line-filedata', widget);
1179
+
1180
+ $('.uploadcare-line-filedata-close', filedata).click(function() {
1181
+ hidden.val('');
1182
+ filedata.css({
1183
+ top: 1
1184
+ });
1185
+ slider.css({
1186
+ "margin-top": 0
1187
+ });
1188
+
1189
+ if ( instance ) {
1190
+ instance.state.set('reloadToBase');
1191
+ }
1192
+
1193
+ UploadCare.Line.hideUploading(widget);
1194
+ });
1195
+
1196
+ },
1197
+
1198
+ fromUrlEvents: function (widget, hidden) {
1199
+ var instance, instanceId;
1200
+
1201
+ if ( hidden ) {
1202
+ instanceId = hidden.attr('data-instance-id');
1203
+ instance = UploadCare.getInstance(instanceId);
1204
+ };
1205
+ $('.uploadcare-line-web', widget).click(function () {
1206
+ if ( instance ) {
1207
+ instance.state.set('fromUrlEnter');
1208
+ }
1209
+
1210
+ widget.addClass('uploadcare-from-url');
1211
+ setTimeout(function () {
1212
+ $('.uploadcare-line-url').focus();
1213
+ }, 300);
1214
+ });
1215
+
1216
+ var fromUrl = $('.uploadcare-line-from-url', widget);
1217
+ $('.uploadcare-line-cancel', fromUrl).click(function () {
1218
+ if ( instance ) {
1219
+ instance.state.set('reloadToBase');
1220
+ }
1221
+ widget.removeClass('uploadcare-from-url');
1222
+ $('.uploadcare-line-url').val('');
1223
+ });
1224
+ },
1225
+
1226
+ // Hide uploading status and move progress to start position.
1227
+ hideUploading: function (widget) {
1228
+ var progress = $('.uploadcare-line-progress div', widget);
1229
+ progress.stop().css({ left: -1, width: progress.data('width') });
1230
+ widget.removeClass('uploadcare-uploading');
1231
+ },
1232
+
1233
+ // Show error with some `code` by widget. If you set `fixable` argument,
1234
+ // error message willn contain back button.
1235
+ //
1236
+ // Method will be get error text from translation by `code`.
1237
+ showError: function (widget, code, fixable, callback) {
1238
+ var text = this.message('errors.' + code);
1239
+ var error = $('.uploadcare-line-error', widget);
1240
+ $('.uploadcare-line-error-text', error).html(text);
1241
+
1242
+ var wrapper = error.parent().show();
1243
+ var height = error.show().outerHeight();
1244
+ error.css({ top: -height }).
1245
+ animate({ top: 0 }, 600, 'easeOutBounce', function () {
1246
+ widget.addClass('uploadcare-error');
1247
+ callback();
1248
+ });
1249
+
1250
+ var back = $('.uploadcare-line-error-back', error).toggle(fixable);
1251
+ if ( fixable ) {
1252
+ var _this = this;
1253
+ back.one('click', function () {
1254
+ error.animate({ top: -height }, 400, 'easeInOutQuad',
1255
+ function () {
1256
+ wrapper.hide();
1257
+ widget.removeClass('uploadcare-error');
1258
+ });
1259
+ _this.hideUploading(widget);
1260
+ $('.uploadcare-line-slider', widget).css({ "margin-top": 0 });
1261
+ });
1262
+ }
1263
+ },
1264
+
1265
+ showFileData: function(fileData) {
1266
+ var widget = $('input[value=' + fileData.file_id + ']').next();
1267
+ var uploadPane = $('.uploadcare-line-slider', widget);
1268
+ var fileDataPane = $('.uploadcare-line-filedata', widget);
1269
+ var filename = $('.uploadcare-line-filedata-filename', widget);
1270
+ var filesize = $('.uploadcare-line-filedata-filesize', widget);
1271
+ var human_size = Math.ceil(fileData.size / 1024) + "kb";
1272
+ var human_filename = fileData.original_filename;
1273
+
1274
+ if ( human_filename.length > 16 ) {
1275
+ human_filename = human_filename.slice(0, 8) + '...' + human_filename.slice(-8);
1276
+ }
1277
+
1278
+ filename.html(human_filename);
1279
+ filename.innerHTML = human_filename;
1280
+ filesize.innerHTML = human_size;
1281
+ filesize.html(human_size);
1282
+ fileDataPane.animate({top: 0});
1283
+ uploadPane.css({ "margin-top": -60 });
1284
+
1285
+ widget.data('info_loaded', true);
1286
+ }
1287
+
1288
+ };
1289
+
1290
+ })();
1291
+ ;(function() {
1292
+ UploadCare.FileData = {
1293
+ timeout: 15000,
1294
+
1295
+ fetch: function(uuid, instanceId) {
1296
+ var requestUrl = this._getRequestUrl();
1297
+ var pubKey = UploadCare.publicKey
1298
+
1299
+ if ( instanceId ) {
1300
+ requestUrl = UploadCare.getInstanceOptions( instanceId ).urls.fileInfo;
1301
+ pubKey = UploadCare.getInstanceOptions( instanceId ).publicKey;
1302
+ }
1303
+
1304
+ // Barebone support
1305
+ if ( uuid.indexOf('[') != -1 ) {
1306
+ console.log('here');
1307
+ var vals = uuid.substr(1, uuid.length - 2).split(',');
1308
+ uuid = vals[vals.length - 1];
1309
+ }
1310
+
1311
+ requestUrl = "" + requestUrl + ("?pub_key=" + pubKey);
1312
+
1313
+ if ( typeof uuid === void 0 ) {
1314
+ throw "UUID must be specified";
1315
+ }
1316
+
1317
+ requestUrl = "" + requestUrl + "&file_id=" + uuid + "&jsoncallback=?";
1318
+
1319
+ try {
1320
+ var $ = UploadCare.jQuery;
1321
+ var _$ = $(this);
1322
+ var deferred = $.Deferred();
1323
+ var xhr = $.ajax( requestUrl, {
1324
+ dataType: "jsonp",
1325
+ global: true,
1326
+ beforeSend: function(jqXHR, settings) {
1327
+ _$.data('_xhr', jqXHR);
1328
+
1329
+ jqXHR.state = function() {
1330
+ return jqXHR.isResolved() ? "resolved" : (jqXHR.isRejected() ? "rejected" : "pending");
1331
+ }
1332
+
1333
+ $(_$).bind('start-timeout', function(ev, t) {
1334
+ var tries = 0;
1335
+
1336
+ t = ( t === void 0 || typeof(t) == "undefined" ) ? _$.timeout : t;
1337
+
1338
+ if ( jqXHR.readyState != 4 && (void 0 === jqXHR.status || jqXHR.status >= 400) ) {
1339
+ var timer = setInterval(function() {
1340
+ switch( jqXHR.state() ) {
1341
+ case "resolved":
1342
+ case "rejected":
1343
+ void( 0 );
1344
+ break;
1345
+ case "pending":
1346
+ if ( tries < 3 ) {
1347
+ tries += 1;
1348
+ } else {
1349
+ clearInterval(timer);
1350
+ jqXHR.abort();
1351
+ }
1352
+ break;
1353
+ }
1354
+ }, t);
1355
+ }
1356
+ });
1357
+
1358
+ return true;
1359
+ }
1360
+ }).success( function(data) {
1361
+ deferred.resolve(data);
1362
+ }).error( function(e) {
1363
+ deferred.reject('misconfiguration');
1364
+ });
1365
+ } catch( error ) {
1366
+ deferred.reject('misconfiguration');
1367
+ } finally {
1368
+ if ( !deferred.isResolved() ) {
1369
+ if ( !xhr || xhr === void 0 ) {
1370
+ xhr = _$.data('_xhr');
1371
+ }
1372
+
1373
+ if ( !xhr.isResolved() ) {
1374
+ _$.triggerHandler('start-timeout', 1000);
1375
+ } else {
1376
+ deferred.resolve(xhr.data('response'));
1377
+ }
1378
+ }
1379
+ }
1380
+
1381
+ return UploadCare._promise(deferred);
1382
+ },
1383
+
1384
+ _getRequestUrl: function() {
1385
+ return UploadCare.urls.fileInfo;
1386
+ }
1387
+ };
1388
+
1389
+ UploadCare.ready(function(jQuery) {
1390
+ jQuery(document).ready(function() {
1391
+ UploadCare.jQuery.ajaxPrefilter( "script", function( s ) {
1392
+ if ( s.cache === undefined ) {
1393
+ s.cache = false;
1394
+ }
1395
+ if ( s.crossDomain ) {
1396
+ s.type = "GET";
1397
+ s.global = true;
1398
+ }
1399
+ });
1400
+ });
1401
+ });
1402
+ })();
1403
+ ;(function() {
1404
+ UploadCare.DragDrop = {
1405
+ useLargeDropZone: false,
1406
+ started: false,
1407
+ eventTimer: false,
1408
+ idle: true,
1409
+
1410
+ selectors: {
1411
+ widget: 'div.uploadcare-line-uploader',
1412
+ cropper: 'div.uploadcare-line-cropper',
1413
+ slider: 'div.uploadcare-line-slider',
1414
+ filedata: 'div.uploadcare-line-filedata'
1415
+ },
1416
+
1417
+ init: function () {
1418
+ return UploadCare.ready(function($) {
1419
+ try {
1420
+ if ( $(UploadCare.DragDrop.selectors.widget).length === 0 ) {
1421
+ throw "Widget block not found. Do you use inline version if widget?";
1422
+ }
1423
+ if ( 'draggable' in document.createElement('span') === false ) {
1424
+ throw "D&D not available, please use modern browser.";
1425
+ }
1426
+ } catch ( error ) {
1427
+ return;
1428
+ } finally {
1429
+ UploadCare.DragDrop.enlive($);
1430
+ }
1431
+ });
1432
+ },
1433
+ enlive: function ($) {
1434
+ var dragzone, dropzone, filedata, hidden, slider, upload, widget, dropbox;
1435
+
1436
+ widget = $(this.selectors.widget);
1437
+ hidden = $(widget).prev();
1438
+ slider = $(this.selectors.slider, widget);
1439
+ filedata = $(this.selectors.filedata, widget);
1440
+ dragzone = $('.uploadcare-line-thumb', slider).first();
1441
+ dropzone = this.createDropZone($, widget);
1442
+ dropbox = $('div.uploadcare-line-thumb-empty', slider);
1443
+
1444
+ this.dragDropEvents(dragzone, dropzone);
1445
+
1446
+ //TODO: Move to separated method
1447
+ dropbox.css({
1448
+ cursor: 'pointer'
1449
+ });
1450
+ dropbox.mouseover(function(e) {
1451
+ UploadCare.DragDrop.onDragOver(e, dragzone, dropzone);
1452
+ });
1453
+ dropzone.mouseleave(function(e) {
1454
+ UploadCare.DragDrop.onDragLeave(e, dragzone, dropzone);
1455
+ }).click(function(e) {
1456
+ e.preventDefault();
1457
+ window.location = 'http://uploadcare.com';
1458
+ }).css({
1459
+ cursor: 'pointer'
1460
+ });
1461
+
1462
+ upload = function (files) {
1463
+ var uploading;
1464
+
1465
+ uploading = UploadCare.DragDrop.process(widget, hidden, files);
1466
+ uploading.success(function (id) {
1467
+ hidden.val(id);
1468
+ hidden.trigger('uploadcare-success', id);
1469
+ hidden.trigger('uploadcare-complete');
1470
+
1471
+ UploadCare.DragDrop.idle = true;
1472
+ });
1473
+
1474
+ uploading.error(function (errorNotReject) {
1475
+ errorNotReject = typeof errorNotReject === void 0 ? false : errorNotReject;
1476
+
1477
+ if (errorNotReject) {
1478
+ UploadCare.Line.showError(widget, 'unknown', true, function() {
1479
+ UploadCare.Line.hideUploading(widget);
1480
+ });
1481
+ } else {
1482
+ filedata.css({
1483
+ top: 1
1484
+ });
1485
+ slider.css({
1486
+ "margin-top": 0
1487
+ });
1488
+ UploadCare.Line.hideUploading(widget);
1489
+ UploadCare.DragDrop.idle = true;
1490
+ }
1491
+ });
1492
+ };
1493
+
1494
+ dropzone.bind('file-drop', function (ev, dev) {
1495
+ var files;
1496
+ files = dev.dataTransfer.files;
1497
+ if ( typeof files !== "undefined" && files !== null && files.length !== 0 ) {
1498
+ UploadCare.DragDrop.idle = false;
1499
+ upload(files);
1500
+ } else {
1501
+ UploadCare.DragDrop.onDragLeave(ev, dragzone, dropzone);
1502
+ }
1503
+ });
1504
+ },
1505
+
1506
+ createDropZone: function ($, widget) {
1507
+ var cropper, dropZoneContainer, dropZoneNode, dropZoneNotification, dndLeftCorner, dndRightCorner, dropZoneDecorator;
1508
+ cropper = $(this.selectors.cropper, widget);
1509
+
1510
+ dropZoneContainer = $('<div/>').attr({
1511
+ "class": this.useLargeDropZone ? "uploadcare-line-largedrop" : "uploadcare-line-tinydrop"
1512
+ });
1513
+
1514
+ dropZoneDecorator = $('<div/>').attr({
1515
+ "class": "uploadcare-line-drop-decoration"
1516
+ }).css({
1517
+ width: widget.width() - 20,
1518
+ height: widget.height()
1519
+ });
1520
+
1521
+ dropZoneArray = $('<span />').attr({
1522
+ "class": "dnd-arrow"
1523
+ });
1524
+ //dropZoneNotification.html('Drop files here');
1525
+ dropZoneArray.appendTo(dropZoneDecorator);
1526
+
1527
+ dropZoneNotification = $('<span />');
1528
+ dropZoneNotification.html('Drop file here');
1529
+ dropZoneNotification.attr({ "class": "droptext"});
1530
+ dropZoneNotification.appendTo(dropZoneDecorator);
1531
+
1532
+ var branding;
1533
+
1534
+ branding = $('<span />');
1535
+ branding.attr({ "class": "branding" });
1536
+ branding.html('Powered by <strong>UploadCare</strong>');
1537
+ branding.appendTo(dropZoneDecorator);
1538
+
1539
+ dndLeftCorner = $('<div />').attr({ "class": "lc" });
1540
+ dndRightCorner = $('<div />').attr({ "class": "rc" });
1541
+
1542
+ dndLeftCorner.appendTo(dropZoneDecorator);
1543
+ dndRightCorner.appendTo(dropZoneDecorator);
1544
+ dropZoneDecorator.appendTo(dropZoneContainer);
1545
+
1546
+ dropZoneNode = $('<div/>').attr({
1547
+ "class": "uploadcare-line-dropzone"
1548
+ });
1549
+ dropZoneNode.css({
1550
+ width: widget.width(),
1551
+ height: widget.height()
1552
+ });
1553
+
1554
+ dropZoneContainer.appendTo(cropper);
1555
+ dropZoneNode.appendTo(dropZoneContainer);
1556
+ return dropZoneNode;
1557
+ },
1558
+
1559
+ dragDropEvents: function (dragzone, dropzone) {
1560
+ var cooldownEvent;
1561
+
1562
+ cooldownEvent = function (ev) {
1563
+ ev.stopPropagation();
1564
+ ev.preventDefault();
1565
+ return ev;
1566
+ };
1567
+
1568
+ var dde = function(event) {
1569
+ if ( UploadCare.DragDrop.eventTimer !== false ) {
1570
+ clearTimeout(UploadCare.DragDrop.eventTimer);
1571
+ UploadCare.DragDrop.eventTimer = false;
1572
+ }
1573
+ if ( UploadCare.DragDrop.idle === true ) {
1574
+ switch(event.type) {
1575
+ case 'drop':
1576
+ UploadCare.DragDrop.started = false;
1577
+ UploadCare.DragDrop.onDragLeave(event, dragzone, dropzone);
1578
+ break;
1579
+ case 'dragleave':
1580
+ UploadCare.DragDrop.eventTimer = setTimeout(function() {
1581
+ UploadCare.DragDrop.started = false;
1582
+ UploadCare.DragDrop.onDragLeave(event, dragzone, dropzone);
1583
+ }, 100);
1584
+ break;
1585
+ case 'dragover':
1586
+ case 'dragenter':
1587
+ if ( UploadCare.DragDrop.started === false ) {
1588
+ UploadCare.DragDrop.started = true;
1589
+ UploadCare.DragDrop.onDragOver(event, dragzone, dropzone);
1590
+ }
1591
+ }
1592
+ }
1593
+ return cooldownEvent(event);
1594
+ }
1595
+
1596
+ UploadCare.jQuery(document).bind('drop', dde).bind('dragenter', dde).bind('dragover', dde).bind('dragleave', dde);
1597
+
1598
+ dropzone[0].ondrop = function (ev) {
1599
+ UploadCare.DragDrop.onDrop(cooldownEvent(ev), dragzone, dropzone);
1600
+ dropzone.trigger('file-drop', ev);
1601
+ };
1602
+
1603
+ return null;
1604
+ },
1605
+
1606
+ process: function (widget, hidden, files) {
1607
+ var deferred, form, getProgress, options, uploading, xhr;
1608
+
1609
+ form = new FormData();
1610
+ deferred = UploadCare.jQuery.Deferred();
1611
+ options = UploadCare._params({
1612
+ pubKey: UploadCare.publicKey,
1613
+ meduim: 'line'
1614
+ });
1615
+
1616
+ options.UPLOADCARE_FILE_ID = UploadCare._uuid();
1617
+
1618
+ hidden.trigger('uploadcare-start');
1619
+
1620
+ getProgress = function (ev) {
1621
+ if (ev.lengthComputable) {
1622
+ hidden.trigger('uploadcare-progress', {
1623
+ done: ev.loaded,
1624
+ total: ev.total
1625
+ });
1626
+ }
1627
+ };
1628
+
1629
+ UploadCare.jQuery.each(options, function(key, value) {
1630
+ return form.append(key, value);
1631
+ });
1632
+
1633
+ form.append('file', files[0]);
1634
+
1635
+ xhr = new XMLHttpRequest;
1636
+
1637
+ xhr.upload.addEventListener('progress', getProgress, false);
1638
+ xhr.addEventListener('abort', function() {
1639
+ return deferred.reject();
1640
+ }, false);
1641
+ xhr.addEventListener('error', function() {
1642
+ return deferred.reject(true);
1643
+ }, false);
1644
+ xhr.addEventListener('load', function() {
1645
+ return deferred.resolve(options.UPLOADCARE_FILE_ID);
1646
+ }, false);
1647
+
1648
+ xhr.open("POST", UploadCare.byIframe._getUploadUrl(), true);
1649
+ xhr.send(form);
1650
+
1651
+ uploading = UploadCare.jQuery('.uploadcare-line-uploading', widget);
1652
+ UploadCare.jQuery('.uploadcare-line-cancel', uploading).click(function() {
1653
+ xhr.abort();
1654
+ });
1655
+ return UploadCare._promise(deferred);
1656
+ },
1657
+
1658
+ onDragOver: function (ev, dragzone, dropzone) {
1659
+ var widget = dragzone.parents(this.selectors.widget);
1660
+
1661
+ widget.addClass('uploadcare-line-uploader-dnd');
1662
+
1663
+ dragzone.parents(this.selectors.slider).css({
1664
+ "margin-top": -90
1665
+ });
1666
+ widget.find(this.selectors.filedata).css({
1667
+ top: -1
1668
+ });
1669
+ // dropzone.prev().animate(dropzone.prev().data('margin'));
1670
+ // widget.animate({
1671
+ // width: 350,
1672
+ // height: 70
1673
+ // }, function() {
1674
+ // dropzone.css({
1675
+ // width: 350,
1676
+ // height: 70
1677
+ // });
1678
+ // });
1679
+
1680
+ return null;
1681
+ },
1682
+
1683
+ onDragLeave: function (ev, dragzone, dropzone) {
1684
+ var widget = dragzone.parents(this.selectors.widget);
1685
+ var slider = dragzone.parents(this.selectors.slider);
1686
+ var filedata = widget.find(this.selectors.filedata);
1687
+
1688
+ widget.removeClass('uploadcare-line-uploader-dnd');
1689
+
1690
+ // dropzone.prev().animate({
1691
+ // "margin-top": 0
1692
+ // });
1693
+ // widget.animate(widget.data('dimensions'), function() {
1694
+ slider.css({
1695
+ "margin-top": 0
1696
+ });
1697
+ filedata.css({
1698
+ top: 1
1699
+ });
1700
+ // });
1701
+
1702
+ return null;
1703
+ },
1704
+
1705
+ onDrop: function (ev, dragzone, dropzone) {
1706
+ var widget = dragzone.parents(this.selectors.widget);
1707
+ var slider = dragzone.parents(this.selectors.slider);
1708
+ var filedata = widget.find(this.selectors.filedata);
1709
+
1710
+ widget.removeClass('uploadcare-line-uploader-dnd');
1711
+
1712
+ // dropzone.prev().animate({
1713
+ // "margin-top": 0
1714
+ // });
1715
+ // widget.animate(widget.data('dimensions'), function() {
1716
+ slider.css({
1717
+ "margin-top": -30
1718
+ });
1719
+ filedata.css({
1720
+ top: 1
1721
+ });
1722
+ // })
1723
+
1724
+ return null;
1725
+ }
1726
+ };
1727
+ })();
1728
+
1729
+ UploadCare.ready(function($) {
1730
+ $(document).bind('enlive', function() {
1731
+ UploadCare.DragDrop.init();
1732
+ });
1733
+ });
1734
+ UploadCare._translate(UploadCare.Line, 'en', {
1735
+ uploadFrom: 'Upload from',
1736
+ computer: 'Computer',
1737
+ web: 'Web',
1738
+ uploading: 'Uploading…',
1739
+ cancel: 'Cancel',
1740
+ back: 'Back',
1741
+ url: 'URL',
1742
+ done: 'Done',
1743
+ errors: {
1744
+ network: 'You have problem with Internet',
1745
+ unknown: 'Something awful happened',
1746
+ misconfiguration: 'Please check your widget config',
1747
+ badFileUrl: 'Incorrect file URL.',
1748
+ onlyImages: 'Only images allowed.'
1749
+ }
1750
+ });
1751
+ UploadCare.Line.html = '<div class="uploadcare-line-uploader"><style scoped="scoped">{style}</style><div class="uploadcare-line-error-wrapper"><div class="uploadcare-line-error"><div class="uploadcare-line-error-cloud"></div><div class="uploadcare-line-error-rain"></div><div class="uploadcare-line-error-text"></div><a href="#" title="{t back}" class="uploadcare-line-error-back"></a></div></div><div class="uploadcare-line-cropper"><div class="uploadcare-line-slider"><div class="uploadcare-line-upload"><div class="uploadcare-line-thumb"><div class="uploadcare-line-thumb-empty"></div></div><div class="uploadcare-line-buttons"><div class="uploadcare-line-file-input">{file}<a href="#" class="uploadcare-line-computer"><div class="uploadcare-line-icon"></div>{t computer}</a></div><a href="#" class="uploadcare-line-web"><div class="uploadcare-line-icon"></div>{t web}</a></div>{t uploadFrom}</div><div class="uploadcare-line-from-url"><div class="uploadcare-line-title">{t url}</div><div class="uploadcare-line-right"><input type="url" class="uploadcare-line-url" /><div class="uploadcare-line-buttons"><a href="#" class="uploadcare-line-url-submit">{t done}</a></div><a href="#" title="{t back}" class="uploadcare-line-cancel"></a></div></div></div><div class="uploadcare-line-uploading"><div class="uploadcare-line-thumb"><div class="uploadcare-line-thumb-empty"></div></div><a href="#" title="{t cancel}" class="uploadcare-line-cancel"></a><div class="uploadcare-line-progress"><div></div></div>{t uploading}</div><div class="uploadcare-line-filedata"><div class="uploadcare-line-filedata-icon-placeholder"><div class="uploadcare-line-filedata-icon-placeholder-icon"></div></div><div class="uploadcare-line-filedata-filename"></div><div class="uploadcare-line-filedata-filesize"></div><div class="uploadcare-line-buttons"><a href="#" title="{t cancel}" class="uploadcare-line-filedata-close">{t cancel}</a></div></div></div></div>';UploadCare.Line.style = '.uploadcare-line-uploader{width:293px;height:30px;line-height:30px;-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;border:1px solid #d8d8d8;background:#f6f6f6;background:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #fcfcfc), color-stop(100%, #ececec));background:-webkit-linear-gradient(#fcfcfc,#ececec);background:-moz-linear-gradient(#fcfcfc,#ececec);background:-o-linear-gradient(#fcfcfc,#ececec);background:-ms-linear-gradient(#fcfcfc,#ececec);background:linear-gradient(#fcfcfc,#ececec);color:#333;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:bold;-webkit-box-shadow:rgba(0,0,0,0.08) 0 1px 3px;-moz-box-shadow:rgba(0,0,0,0.08) 0 1px 3px;box-shadow:rgba(0,0,0,0.08) 0 1px 3px;position:relative}.uploadcare-line-uploader.uploadcare-error{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.uploadcare-line-cropper{position:absolute;top:-1px;left:-1px;height:100%;width:100%;padding:1px;overflow:hidden}.uploadcare-line-thumb{float:left;width:30px;height:30px;border-right:1px solid #d8d8d8;margin-right:9px;position:relative}.uploadcare-line-thumb-empty{position:absolute;top:3px;left:3px;width:25px;height:25px;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAACiklEQVRIx+WWy2sTURjFg6W0SkHd1F22BXERXYsrty1YQYO6shbqQoQu3Ijozv/BjX+AG1015DUhLyfvTMw7MQtj8ZEYFMSJTcr1nGEGk3EyKTiuvHCSzNx7f+fem+/7uC6/338uFArtSZL0PhwOdwKBwIbL1PBuC/0/IBGJRAS/MSeLuQumcRtkkEUm2VpHLBaLp9PpUblcflMqlYqVSuWG2URRlMe5XG5cLBYFVSgUBJ7f1Wq1xclxnEsGWWSSrXVkMpmvjUajJITwQtcgt9kE7zzQI+jJhHagY6Zxbp3hJZNsrQOr+owVBFwONzLJNtzvQetOm5BJtuv/awhFN0LzLUJzn0J4Snh3wlEThK0nlUod5vN5hq5AeH5EqJ46MgAJ9BR6PidSLiBXDpAXolqtCvz+gO/TR+Ymk8nviUSCGXzSxuQ8Ter1uqARdjHXZIqLI1B5DACdsTHxGCbcCU1gZntcU1yct8pSgUl/mPh8Pq02oe+syWS/2+0enxxj8T/+5tqZBIPBB4gqGVuXAT40jguGP+PxeAR9rzHm9lyTdrstoc4oyM5l88Ber7eO0tBkQcS2hWGCAih4FIBkBoPBJSuTKS4+LkNXZpSGleFweLeJRjhNjCMDJD8ej71Wi9PnzuRaDV6C0Z1Wq6UZUZ1Ohwab6Ftwstgtqaq6jQ21sANlNBpdddRgwmgZuskj+CcGf92QkQ2E4TOnuWSSrT3IsvwNRS/qtAmZZGsPSLJ2Nps9iEajL+H+AiX8osVuXxk3FbvbCueSQRaZZGsd/X7/IcKyieT6ghL+CSvYsqhDaT35bG8rnEsGWWSSbUTNKnQL2oXuQ2sWkXXddFOZdVtZ0xm7OnOV738BeS37eGOiGg0AAAAASUVORK5CYII=") no-repeat 50% 50%}.uploadcare-line-buttons{float:right}.uploadcare-line-buttons a{display:block;float:left;height:22px;line-height:22px;margin:3px 3px 0 0;padding:0 7px;border:1px solid #abcddc;border-color:#abcddc #a0c3d3 #92b8c9 #a0c3d3;text-decoration:none;color:#7dadc1;text-shadow:#fff 0 1px 1px;font-size:12px;background:#e6f5fb;background:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f4fbfe), color-stop(100%, #d5eef8));background:-webkit-linear-gradient(#f4fbfe,#d5eef8);background:-moz-linear-gradient(#f4fbfe,#d5eef8);background:-o-linear-gradient(#f4fbfe,#d5eef8);background:-ms-linear-gradient(#f4fbfe,#d5eef8);background:linear-gradient(#f4fbfe,#d5eef8);-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;-webkit-box-shadow:rgba(0,0,0,0.1) 0 1px 1px;-moz-box-shadow:rgba(0,0,0,0.1) 0 1px 1px;box-shadow:rgba(0,0,0,0.1) 0 1px 1px}.uploadcare-line-buttons .uploadcare-line-icon{position:absolute;left:7px}.uploadcare-line-cancel{display:block;float:right;width:8px;height:9px;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAJCAQAAAClWqWlAAAAj0lEQVQI1wXBwQmDMBgG0G8Cbx6zQCFLFDqVdwdwjAxgsFAwUUFQcvgvthsIBsxFzO3re7Cl/bQPAGi1fdsSzo3so9VW93GkcziaJQf66GPgko8GVMlIFgolJ0MF4PuSe+NGuX9PAJ0eolCyZOEQOw0/zVxzMsmseaafcNVhPw0V1WnCftVgwYoKAKhYsfgDIRFiQ7984PoAAAAASUVORK5CYII=") no-repeat 50% 50%;padding:2px;margin:9px 4px 0 1px}.uploadcare-line-slider{-webkit-transition:all,300ms;-moz-transition:all,300ms;-ms-transition:all,300ms;-o-transition:all,300ms;transition:all,300ms;position:relative;margin:0}.uploadcare-line-buttons .uploadcare-line-computer{padding-left:28px;position:relative;margin-top:0}.uploadcare-line-buttons .uploadcare-line-computer .uploadcare-line-icon{top:5px;width:16px;height:13px;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAANCAMAAACXZR4WAAAAP1BMVEUAAAD///////+Qrrytx9OvydeRr72SsL+Tsb+XtsSXt8WZuMeZuciausmcvMufv8+gwtGiw9OkxdWkxtalx9d4pYbSAAAABnRSTlMAWoCz2dmZsTKvAAAAU0lEQVQI162OOxaAIBADAyjIrnzl/md1UcRn7zRJpgoA47aBM+h4PfGX2DG5K7+CfxOBnh8UZFpKOQ1yIouQa2u1v5IsmrEeTUpkjkUyLVD6gzoBORkEIOkz/78AAAAASUVORK5CYII=") no-repeat 50% 50%}.uploadcare-line-buttons .uploadcare-line-web{padding-left:29px;position:relative}.uploadcare-line-buttons .uploadcare-line-web .uploadcare-line-icon{top:2px;width:17px;height:18px;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAASCAYAAAC9+TVUAAAC/UlEQVQ4y41US0wTURStBKPRsFA3khgVt7rSxMQYVixwoTFu1BiWLoiGxIULjTGCiQsWIAK1bbAWCq1QWgXbWkpbpp1+7WdaoD9KQfk0fKRSAWmhn+e9IzUFRX3JyZt359xzz33z3nA4fxgNsoGDjXLtrSaFrgkgeC4frIN1JcSLOP8aQNoDSY+a+6gNkc7RYwlMPAjPLFR7xqdv89TmaHPf0CIIXttVoLFXe+zFO8NHudkrIIQ8BlwGnIotJUpNI5Gz8Hw3sZZ8wlWZCfAkWHC7gFy7j6s0TvA1NpLN5cox1vreON/ST/FhJpjI01hJm85JhEMeItA6CLjt3ibS0m/kqj1hvcLhD0NFtgLM9yW014lJYtqXEhm9pJ0eJp1WP+mgR1ghcFTBCsAelPA1lrQpMIkt3MwLQ/V7r4cYIrEF0l22IHnrHo9J7MGs1BHK4Lrd5CMCjS3Mkvlq+g7afGNiGgrdCQZsCTUT8UXm4m2z8RWuwhke67IGiNQe2pDYQ6yjV3oXujnMkVBuETMRk4GL8rwAfIXjSMAWhAY3Iiq1js6hiMQWzKAIQkR5iVjvOI8iKmdk6lKhC57aQqFdscXP7gP7bB4l2AY6yOVydSiIcRnN3OD00oyix+iuKBRR2EcpFMhXxGQWkBia/dKBm7+QWGtCp4NM+CpH7w3XtipNBA7RkbwIkK6srKfqYa5lW9gSk1r9qxAr2+IcEhpcuVg8UcZJbabPCHXOda6SJoVugHQAZ6VnzJ930u8KufPvobCwx+KLAq8YyUVG/6QKNxAd7TzJnUZmCt3InKG4lPZ5f+2bxpqdW16pKax6oc8VioiNzPJOkY10pqbb5l8CTg2gassFoUaiWliXbCNnstmqD8wYhW3BNSgtKFCMAj9PNvUQ3q9agp+UELv42wXEtgCVwel50UsVPQwJBAF3J4V3B8U7DE5qNZl6Crxzf/0dAOEkoPrb92R9eHZR5IrOdH9e/MpLbqafQfw6YD/nfwd+HcAJwGnAUcDe3bg/ALpRdnZzPzzmAAAAAElFTkSuQmCC") no-repeat 50% 50%}.uploadcare-line-file-input{float:left;overflow:hidden;position:relative;margin-top:3px}.uploadcare-line-file-input input{position:absolute;top:0;left:0;width:100%;height:100%;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=0);opacity:0;cursor:pointer;z-index:2}.uploadcare-line-uploader.uploadcare-from-url .uploadcare-line-slider{left:-293px}.uploadcare-line-from-url{position:absolute;top:0;left:293px;width:293px}.uploadcare-line-title{margin:0 5px 0 10px;float:left}.uploadcare-line-url{float:left;border:1px solid #b9bcbe;border-color:#b9bcbe #bdc0c2 #c1c5c7 #bdc0c2;-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;background:#fff;color:#777;height:22px;width:160px;padding:0 5px;-webkit-box-shadow:rgba(0,0,0,0.15) 0 1px 1px 0 inset;-moz-box-shadow:rgba(0,0,0,0.15) 0 1px 1px 0 inset;box-shadow:rgba(0,0,0,0.15) 0 1px 1px 0 inset;margin:3px 3px 0 0}.uploadcare-line-url:focus{outline:none}.uploadcare-line-right{float:right}.uploadcare-line-right .uploadcare-line-buttons{float:left}.uploadcare-line-right .uploadcare-line-cancel{float:left}.uploadcare-line-uploader.uploadcare-uploading .uploadcare-line-slider{margin-top:-30px}.uploadcare-line-progress{float:right;width:137px;height:4px;margin:12px 4px 0 0;border:1px solid #c9c9c9;border-top-color:#bbb;-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;background:#d8d8d8;-webkit-box-shadow:#d0d0d0 0 1px 0 0 inset;-moz-box-shadow:#d0d0d0 0 1px 0 0 inset;box-shadow:#d0d0d0 0 1px 0 0 inset;position:relative}.uploadcare-line-progress div{position:absolute;width:40px;height:4px;top:-1px;left:-1px;border:1px solid #a9ccdb;-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;background:#b7e2f3 url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAEAQMAAACTPww9AAAABlBMVEWb1u634vNqPjngAAAAEElEQVQI12N4wHCBYQNDAQAMuALRrGb97AAAAABJRU5ErkJggg==");-webkit-box-shadow:rgba(255,255,255,0.3) 0 1px 0 0 inset;-moz-box-shadow:rgba(255,255,255,0.3) 0 1px 0 0 inset;box-shadow:rgba(255,255,255,0.3) 0 1px 0 0 inset}.uploadcare-line-error-wrapper{display:none;position:absolute;top:-1px;left:-1px;overflow:hidden;z-index:10}.uploadcare-line-error{padding:5px 0;line-height:20px;width:293px;border:1px solid #dda1a5;-webkit-border-radius:2px;-moz-border-radius:2px;-ms-border-radius:2px;-o-border-radius:2px;border-radius:2px;color:#d15d62;background:#fff;-webkit-box-shadow:rgba(206,88,93,0.45) 0 0 15px 0 inset;-moz-box-shadow:rgba(206,88,93,0.45) 0 0 15px 0 inset;box-shadow:rgba(206,88,93,0.45) 0 0 15px 0 inset;position:relative;display:inline-block}.uploadcare-line-error-cloud{position:absolute;top:6px;left:9px;width:18px;height:12px;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAMCAYAAABvEu28AAAAsElEQVQoz2NgQAMXY5PYgZgFymYC4iwgvgHE/6H4LxCfAmJvBmwAKCEHxBOA+AwQHwXiEiDOBeLfSIYg4ydAbItuiBIQn8Si+C8OQ2B4ERAzwwxhAeIWAhpw4f1ALIocJkvINGgHEHPBDNIE4otkGvQBiPuAmA9k0DEyDUHGXQx4YoUU/Apk0E8qGPQNZNAXKhh0iAGa8Cgx7AEQO4AM4gDiTCDeBU36pOBVQOwOin0AgvHi6I+GKv8AAAAASUVORK5CYII=") no-repeat 50% 50%}.uploadcare-line-error-rain{position:absolute;top:18px;left:10px;height:8px;width:15px;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAHCAYAAADXhRcnAAAAb0lEQVQY02NggIKLsUmBDFgALvFLMPFLscldQEXzMRVgFweKQcQvxiQxAxlvgQrTUBRAxYE4DU0jqjhQox6SZAeSzXpIbCTxJD1s/jsJxLeJFUf2HxvQqf+Api5GCxg2oMZ/F9HEsdmsh1U8Brs4AKuWR7uentiJAAAAAElFTkSuQmCC") repeat 0 0;animation:uploadcare-line-pulse 1.3s linear infinite;-webkit-animation:uploadcare-line-pulse 1.3s linear infinite;-moz-animation:uploadcare-line-pulse 1.3s linear infinite}.uploadcare-line-error-text{float:left;margin-left:36px;width:225px}.uploadcare-line-error-back{display:block;float:right;padding:2px;margin:4px 4px 0 0;width:8px;height:8px;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIBAMAAAA2IaO4AAAAGFBMVEUAAADRXWLRXWLRXWLRXWLRXWLRXWLRXWJUkwjSAAAAB3RSTlMAFSotur3qBiuZYwAAACZJREFUCNdjEFVgdmQITzYrZTArS09mYE4vMwARChAuWELUgDkQAK1mCNkIwNXGAAAAAElFTkSuQmCC") no-repeat 50% 50%}.uploadcare-line-filedata{position:relative;top:1px;height:30px}.uploadcare-line-filedata a.uploadcare-line-cancel{display:inline-block !important;margin:0;position:relative;top:9px;right:4px}.uploadcare-line-filedata-icon-placeholder{display:inline-block;vertical-align:top;background:-webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f2fdf3), color-stop(100%, #e7f0d5));background:-webkit-linear-gradient(#f2fdf3,#e7f0d5);background:-moz-linear-gradient(#f2fdf3,#e7f0d5);background:-o-linear-gradient(#f2fdf3,#e7f0d5);background:-ms-linear-gradient(#f2fdf3,#e7f0d5);background:linear-gradient(#f2fdf3,#e7f0d5);border-right:1px solid #d8d8d8;width:30px;height:30px}.uploadcare-line-filedata-icon-placeholder-icon{position:relative;display:inline-block;border:0 none;margin-left:6px;margin-top:6px;padding:0;width:18px;height:18px;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QjI4OUZGNDcwQzU0MTFFMTk1MTY5QjU3NDNFQTk4OEQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QjI4OUZGNDgwQzU0MTFFMTk1MTY5QjU3NDNFQTk4OEQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpCMjg5RkY0NTBDNTQxMUUxOTUxNjlCNTc0M0VBOTg4RCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpCMjg5RkY0NjBDNTQxMUUxOTUxNjlCNTc0M0VBOTg4RCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pviw0ewAAAKlSURBVDjLrZTPS1RRFMfvtMpo0aYiiYK2tmlRELRpEdIu6m+IVoWKgoGQoWG7oNzZpGkSmtoimdw4jhqjNpTjDDkDaqkzzjjOvDf317s/3qi3M1MMmP3QcPGBxz2Hzznvex8PGWPQQYCEYkgqjqRmyFEYKa3g2QEE4sKCOi3VHWWjHFtEVKWR0Bi5rkKOu35OFHLHpZv/H1EK6QJHhU11eTkX2rCcpQCcHd2naAGJguURrn0zvOKLvZlpMavW50heLB/bh8hCWCQ8RK01jc2/2Ho12WgiyfdGurhGudyzZ5FbEJXrON7mm3262RmoM9HkiFFbuZh2xQUFvWWR0s5JoWmV1rooOiK1LIugdj5pRwLvPj2xO0bvmo9LA0Zu5cKwyTUNg4tAIwfIFQjta5bFk0xtdAjJKx2JERNZkPKza/a8ty/YbJ77a7cD8S7juBt+pWUVgMoiKjcqsvRb78hcuxmYaTWLmcltqcltRxAPF7kbC5lgsj/4sOD11xgf9GCZGldKnlZKoR0izNMVKSvW0z/VAhNrTO+HJjO36tvkMtsMkrnXwQfGO1YHQx6ZDI0nHEmqhZAIZDtFXOBi0NdTJGoNwkZFWc9Eo5la6NP9063bnYF60z1x34RXho2j16e54IeEgMuQArIVP4QA4g4poRS/lSbR7FCorSTz+mtNV6ABqDe+2WeGqBWT58l2x+HQT3eBOGc/gdtR7E4KR8Tb0GNTzOTleIPpge9l2QqBZNVHuX2CO+xfIoYoxYeV5rUp/MUehEw6Ru+Z8Vi3wWJtIs/SZyjPoj2JGOMIUwvenV1N2NHZIdgsmQ8bwnIXMc0hwmxEGfktv4goHGJECEGQxaUMiyubJ4YpJYiUwH9kl6gkoxSKNmI8X52n6VN/E5RFB/Vj+w6Gzcd8vWkbFQAAAABJRU5ErkJggg==") no-repeat 50% 50%;width:18px;height:18px}.uploadcare-line-filedata-filename{position:relative;display:inline-block;vertical-align:top;padding-left:10px;width:40%;height:30px}.uploadcare-line-filedata-filesize{display:inline-block;vertical-align:baseline;text-align:center;padding-left:7px;font-weight:400;height:30px;width:60px;opacity:0.9;position:relative}.uploadcare-line-filedata-close{position:relative}.uploadcare-line-tinydrop{position:relative;top:1px;height:30px;text-align:center}.uploadcare-line-drop-decoration{position:absolute;left:10px;top:0px;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAeCAIAAAB11XNZAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QjMyMTk5NDgwOUVDMTFFMUEyMTBGMTk4Q0QyMTA1MzQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QjMyMTk5NDkwOUVDMTFFMUEyMTBGMTk4Q0QyMTA1MzQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpCMzIxOTk0NjA5RUMxMUUxQTIxMEYxOThDRDIxMDUzNCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpCMzIxOTk0NzA5RUMxMUUxQTIxMEYxOThDRDIxMDUzNCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PlRlfWQAAADFSURBVCjPzZDLSgNREERP9e0h7hQdiBDw/z9MRCKaiI+JOveWi7hQkUxACdayabrOaa2HF3YmjXZvBFNJICKehs3l8vb+8TkkQ8D87OTivB9rSwA7Qpk5mx1FCbydhA2g1fAKCEWgT0y2q/3RAhjXBvhHl0nSqZU9bCdbDnTj/7j4t6SH+elfcCSQpSxX6+ubu3GsCtkE9KfHi3lfa0vj5lZC3axT14WEAUcpto119bAxpMj44lXtt2ZtWwTV1Nq+EWhP0neQhF0gA0Q2WAAAAABJRU5ErkJggg==") repeat-x 0 0;background-position-x:-1px;z-index:1;text-align:left}.uploadcare-line-drop-decoration span{color:#7391a0;display:inline-block;z-index:5}.uploadcare-line-drop-decoration .droptext{margin-left:10px}.uploadcare-line-drop-decoration .branding{font-size:11px;font-weight:200;opacity:0.9;float:right;text-shadow:1px 0px #fff}.uploadcare-line-drop-decoration .dnd-arrow{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAMCAMAAAEbsuwEAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2ZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpGOTdGMTE3NDA3MjA2ODExOUVFMUM2QTRBRUM4NTYwQiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1NTFCNUNCMTA2NjkxMUUxQUFBRjgzQ0M2RTczQ0U4RSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo1NTFCNUNCMDA2NjkxMUUxQUFBRjgzQ0M2RTczQ0U4RSIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M0IE1hY2ludG9zaCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkY4N0YxMTc0MDcyMDY4MTFCQTE2QUIyNDBEM0NCREEwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkY5N0YxMTc0MDcyMDY4MTE5RUUxQzZBNEFFQzg1NjBCIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+rdynBwAAALdQTFRF////ZoCO////////////vcnPZ4KP////mKu0orS8n7G6aIKQoLK7kqawmq23may2m6632ODj0dre////9vj59ff49/n6////aoSS6+/x6u7w7fHzaYSSaYSSbomXaYWTaYWTcIybhp6qlay4lq25lKu3gJmmjKWzjaazjKWzaYWTaoWTfZmnfZimfZmnd5KgdpOidpSid5SjcYybdpOico+ecpCfc5CgdpSkdpWkd5ameJameJenijMzbQAAADV0Uk5TAAMDBwgJCgwQEBEeKjAwMTI+TVFSU1hbYmRlaXa/wMfIyMvOztHa2trb3eXl5+fo+fr6/f3V8BPSAAAAcElEQVQIHQXBiUIBUQAAwLHkJiT3kbuSYxWx7/3/d5mBUs9eJFKbah7tMlrhwGQRz3PyX+/43heRZlWkWYWPvzAbGIe4KjDaJND4vV1PZfCaxnCsIqd+idnPi5zO9v8Rw/22bJMffoaw7iag0H9L8AQwIgumRuIwGgAAAABJRU5ErkJggg==") no-repeat 0 0;display:inline-block;width:10px;height:12px;margin-bottom:-2px;margin-right:5px;z-index:5}.uploadcare-line-drop-decoration .lc{position:absolute;left:-10px;top:0;width:10px;height:30px;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAeCAIAAACaFxhnAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QjMyMDVDRUYwOUVDMTFFMUEyMTBGMTk4Q0QyMTA1MzQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QjMyMDVDRjAwOUVDMTFFMUEyMTBGMTk4Q0QyMTA1MzQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpCMzIwNUNFRDA5RUMxMUUxQTIxMEYxOThDRDIxMDUzNCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpCMzIwNUNFRTA5RUMxMUUxQTIxMEYxOThDRDIxMDUzNCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PhMgTkcAAAFNSURBVCjPpVPZTgJBEKw+XAQWF4yGN///nzQkRANeEQ/IArsz5cPCcuODnUkmMzXVR/W0PLx83nSaEBw176VNygkQ0EjitHm1CbAoytHbx3Seh8B+L7u9ztxsDauM3j6+80Wn3VJIo5EIBKTXfpYhXrVbd/1e4hYjIsnaOQAzU0WMCBVSeX2dzt0UgKuQCLuZOggQAMpwpATFWfM1+YQs59m6YouM3yeDp/GyLCFSXbJmi8jXLJ/M8qIM29Gcq5c0d/dEIIg7sVnLLget8zpMZXvHlagkup3WZVIkbpAN7gQJkrzJUgFC5PYP2Igajon6P9X+ZBMgVPR++DR4fC6KIJC6vrpuipraBtrKHADRaja+Z/PHl3cwdtM066Rmsqo7kP1uZqo/+aIsY2AgImEynMwu3KqmmYgKAAQyRALwerpIlgcTo0URuNWJvfULcDLD4OsDXUsAAAAASUVORK5CYII=") no-repeat 0 0}.uploadcare-line-drop-decoration .rc{position:absolute;right:-10px;top:0;width:10px;height:30px;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAeCAIAAACaFxhnAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QjMyMTk5NDAwOUVDMTFFMUEyMTBGMTk4Q0QyMTA1MzQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QjMyMTk5NDEwOUVDMTFFMUEyMTBGMTk4Q0QyMTA1MzQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpCMzIwNUNGNTA5RUMxMUUxQTIxMEYxOThDRDIxMDUzNCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpCMzIwNUNGNjA5RUMxMUUxQTIxMEYxOThDRDIxMDUzNCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PlWZRmEAAAE7SURBVCjPtZJLTwJBEISregZBXqKoiR6MN///X9KEqCSrCAbd3e7ysAquUYwH5zCPdHrqq5rh4/oVPw0hC/yxShh2jkyydp8Xi7uHRUoc9vbPT466nQxAgEEi2O3uTUbDQb//tH6dzQsaaQSQBZhxOh6eTIZl7dd3D2VVbS9vlpAUiIAZUkqbMot1+ZklkSTqEAAJGWqhulrnncaErF3VX2PZdJOsqno2L4y4ODtt7OQWV0SxfN7r5GgA+ZWcuZNzznjnZ0ubAGEkv9FuUJt5s/mkLaVk04MBAaMB8BDvn1u/JRmJHaG6/iO177q11SZZVvXN7dyjvrq8AODh7W7CEgNp65uEuxbL1eNqBVpZ+3jQ+wgVWYAQLi/ryB07HPWPxyNXNNqcLV+aNBIJIASXpCaWjwf1kEN/NYY3iBer0LuJJuEAAAAASUVORK5CYII=") no-repeat 0 0}.uploadcare-line-dropzone{position:absolute;left:0;top:0;z-index:10}.uploadcare-line-uploader-dnd{border:1px solid #b2cedc}.uploadcare-line-uploader-dnd .uploadcare-line-tinydrop{top:0px}@keyframes uploadcare-line-pulse{from{background-position:0 0}to{background-position:0 15px}}@-webkit-keyframes uploadcare-line-pulse{from{background-position:0 0}to{background-position:0 15px}}@-moz-keyframes uploadcare-line-pulse{from{background-position:0 0}to{background-position:0 15px}}';/*
1752
+ * Copyright (c) 2011 UploadCare
1753
+ *
1754
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
1755
+ * of this software and associated documentation files (the "Software"), to deal
1756
+ * in the Software without restriction, including without limitation the rights
1757
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1758
+ * copies of the Software, and to permit persons to whom the Software is
1759
+ * furnished to do so, subject to the following conditions:
1760
+ *
1761
+ * The above copyright notice and this permission notice shall be included in
1762
+ * all copies or substantial portions of the Software.
1763
+ *
1764
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1765
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1766
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1767
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1768
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1769
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1770
+ * SOFTWARE.
1771
+ */
1772
+
1773
+ UploadCare.ready(function ($) {
1774
+ $(document).ready(function () {
1775
+ UploadCare.Line.init($('body'));
1776
+ });
1777
+ });