PageSourceSearch

https://interfacemedia.ru/netcat/admin/js/min/min_3c762f1a106bb41514de0510c02921bf.js

js interfacemedia.ru collected 2026-10-05 00:03:37 UTC 230,317 bytes, 4,865 lines download raw bytes

vendor: 15,590 bytes, lines 1-545
1/*! jQuery UI - v1.11.1+CommonJS - 2014-09-17
2* http://jqueryui.com
3* Includes: widget.js
4* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
5
6(function( factory ) {
7	if ( typeof define === "function" && define.amd ) {
8
9		// AMD. Register as an anonymous module.
10		define([ "jquery" ], factory );
11
12	} else if (typeof exports === "object") {
13		// Node/CommonJS:
14		factory(require("jquery"));
15
16	} else {
17
18		// Browser globals
19		factory( jQuery );
20	}
21}(function( $ ) {
22/*!
23 * jQuery UI Widget 1.11.1
24 * http://jqueryui.com
25 *
26 * Copyright 2014 jQuery Foundation and other contributors
27 * Released under the MIT license.
28 * http://jquery.org/license
29 *
30 * http://api.jqueryui.com/jQuery.widget/
31 */
32
33
34var widget_uuid = 0,
35	widget_slice = Array.prototype.slice;
36
37$.cleanData = (function( orig ) {
38	return function( elems ) {
39		var events, elem, i;
40		for ( i = 0; (elem = elems[i]) != null; i++ ) {
41			try {
42
43				// Only trigger remove when necessary to save time
44				events = $._data( elem, "events" );
45				if ( events && events.remove ) {
46					$( elem ).triggerHandler( "remove" );
47				}
48
49			// http://bugs.jquery.com/ticket/8235
50			} catch( e ) {}
51		}
52		orig( elems );
53	};
54})( $.cleanData );
55
56$.widget = function( name, base, prototype ) {
57	var fullName, existingConstructor, constructor, basePrototype,
58		// proxiedPrototype allows the provided prototype to remain unmodified
59		// so that it can be used as a mixin for multiple widgets (#8876)
60		proxiedPrototype = {},
61		namespace = name.split( "." )[ 0 ];
62
63	name = name.split( "." )[ 1 ];
64	fullName = namespace + "-" + name;
65
66	if ( !prototype ) {
67		prototype = base;
68		base = $.Widget;
69	}
70
71	// create selector for plugin
72	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
73		return !!$.data( elem, fullName );
74	};
75
76	$[ namespace ] = $[ namespace ] || {};
77	existingConstructor = $[ namespace ][ name ];
78	constructor = $[ namespace ][ name ] = function( options, element ) {
79		// allow instantiation without "new" keyword
80		if ( !this._createWidget ) {
81			return new constructor( options, element );
82		}
83
84		// allow instantiation without initializing for simple inheritance
85		// must use "new" keyword (the code above always passes args)
86		if ( arguments.length ) {
87			this._createWidget( options, element );
88		}
89	};
90	// extend with the existing constructor to carry over any static properties
91	$.extend( constructor, existingConstructor, {
92		version: prototype.version,
93		// copy the object used to create the prototype in case we need to
94		// redefine the widget later
95		_proto: $.extend( {}, prototype ),
96		// track widgets that inherit from this widget in case this widget is
97		// redefined after a widget inherits from it
98		_childConstructors: []
99	});
100
101	basePrototype = new base();
102	// we need to make the options hash a property directly on the new instance
103	// otherwise we'll modify the options hash on the prototype that we're
104	// inheriting from
105	basePrototype.options = $.widget.extend( {}, basePrototype.options );
106	$.each( prototype, function( prop, value ) {
107		if ( !$.isFunction( value ) ) {
108			proxiedPrototype[ prop ] = value;
109			return;
110		}
111		proxiedPrototype[ prop ] = (function() {
112			var _super = function() {
113					return base.prototype[ prop ].apply( this, arguments );
114				},
115				_superApply = function( args ) {
116					return base.prototype[ prop ].apply( this, args );
117				};
118			return function() {
119				var __super = this._super,
120					__superApply = this._superApply,
121					returnValue;
122
123				this._super = _super;
124				this._superApply = _superApply;
125
126				returnValue = value.apply( this, arguments );
127
128				this._super = __super;
129				this._superApply = __superApply;
130
131				return returnValue;
132			};
133		})();
134	});
135	constructor.prototype = $.widget.extend( basePrototype, {
136		// TODO: remove support for widgetEventPrefix
137		// always use the name + a colon as the prefix, e.g., draggable:start
138		// don't prefix for widgets that aren't DOM-based
139		widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
140	}, proxiedPrototype, {
141		constructor: constructor,
142		namespace: namespace,
143		widgetName: name,
144		widgetFullName: fullName
145	});
146
147	// If this widget is being redefined then we need to find all widgets that
148	// are inheriting from it and redefine all of them so that they inherit from
149	// the new version of this widget. We're essentially trying to replace one
150	// level in the prototype chain.
151	if ( existingConstructor ) {
152		$.each( existingConstructor._childConstructors, function( i, child ) {
153			var childPrototype = child.prototype;
154
155			// redefine the child widget using the same prototype that was
156			// originally used, but inherit from the new version of the base
157			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
158		});
159		// remove the list of existing child constructors from the old constructor
160		// so the old child constructors can be garbage collected
161		delete existingConstructor._childConstructors;
162	} else {
163		base._childConstructors.push( constructor );
164	}
165
166	$.widget.bridge( name, constructor );
167
168	return constructor;
169};
170
171$.widget.extend = function( target ) {
172	var input = widget_slice.call( arguments, 1 ),
173		inputIndex = 0,
174		inputLength = input.length,
175		key,
176		value;
177	for ( ; inputIndex < inputLength; inputIndex++ ) {
178		for ( key in input[ inputIndex ] ) {
179			value = input[ inputIndex ][ key ];
180			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
181				// Clone objects
182				if ( $.isPlainObject( value ) ) {
183					target[ key ] = $.isPlainObject( target[ key ] ) ?
184						$.widget.extend( {}, target[ key ], value ) :
185						// Don't extend strings, arrays, etc. with objects
186						$.widget.extend( {}, value );
187				// Copy everything else by reference
188				} else {
189					target[ key ] = value;
190				}
191			}
192		}
193	}
194	return target;
195};
196
197$.widget.bridge = function( name, object ) {
198	var fullName = object.prototype.widgetFullName || name;
199	$.fn[ name ] = function( options ) {
200		var isMethodCall = typeof options === "string",
201			args = widget_slice.call( arguments, 1 ),
202			returnValue = this;
203
204		// allow multiple hashes to be passed on init
205		options = !isMethodCall && args.length ?
206			$.widget.extend.apply( null, [ options ].concat(args) ) :
207			options;
208
209		if ( isMethodCall ) {
210			this.each(function() {
211				var methodValue,
212					instance = $.data( this, fullName );
213				if ( options === "instance" ) {
214					returnValue = instance;
215					return false;
216				}
217				if ( !instance ) {
218					return $.error( "cannot call methods on " + name + " prior to initialization; " +
219						"attempted to call method '" + options + "'" );
220				}
221				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
222					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
223				}
224				methodValue = instance[ options ].apply( instance, args );
225				if ( methodValue !== instance && methodValue !== undefined ) {
226					returnValue = methodValue && methodValue.jquery ?
227						returnValue.pushStack( methodValue.get() ) :
228						methodValue;
229					return false;
230				}
231			});
232		} else {
233			this.each(function() {
234				var instance = $.data( this, fullName );
235				if ( instance ) {
236					instance.option( options || {} );
237					if ( instance._init ) {
238						instance._init();
239					}
240				} else {
241					$.data( this, fullName, new object( options, this ) );
242				}
243			});
244		}
245
246		return returnValue;
247	};
248};
249
250$.Widget = function( /* options, element */ ) {};
251$.Widget._childConstructors = [];
252
253$.Widget.prototype = {
254	widgetName: "widget",
255	widgetEventPrefix: "",
256	defaultElement: "<div>",
257	options: {
258		disabled: false,
259
260		// callbacks
261		create: null
262	},
263	_createWidget: function( options, element ) {
264		element = $( element || this.defaultElement || this )[ 0 ];
265		this.element = $( element );
266		this.uuid = widget_uuid++;
267		this.eventNamespace = "." + this.widgetName + this.uuid;
268		this.options = $.widget.extend( {},
269			this.options,
270			this._getCreateOptions(),
271			options );
272
273		this.bindings = $();
274		this.hoverable = $();
275		this.focusable = $();
276
277		if ( element !== this ) {
278			$.data( element, this.widgetFullName, this );
279			this._on( true, this.element, {
280				remove: function( event ) {
281					if ( event.target === element ) {
282						this.destroy();
283					}
284				}
285			});
286			this.document = $( element.style ?
287				// element within the document
288				element.ownerDocument :
289				// element is window or document
290				element.document || element );
291			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
292		}
293
294		this._create();
295		this._trigger( "create", null, this._getCreateEventData() );
296		this._init();
297	},
298	_getCreateOptions: $.noop,
299	_getCreateEventData: $.noop,
300	_create: $.noop,
301	_init: $.noop,
302
303	destroy: function() {
304		this._destroy();
305		// we can probably remove the unbind calls in 2.0
306		// all event bindings should go through this._on()
307		this.element
308			.unbind( this.eventNamespace )
309			.removeData( this.widgetFullName )
310			// support: jquery <1.6.3
311			// http://bugs.jquery.com/ticket/9413
312			.removeData( $.camelCase( this.widgetFullName ) );
313		this.widget()
314			.unbind( this.eventNamespace )
315			.removeAttr( "aria-disabled" )
316			.removeClass(
317				this.widgetFullName + "-disabled " +
318				"ui-state-disabled" );
319
320		// clean up events and states
321		this.bindings.unbind( this.eventNamespace );
322		this.hoverable.removeClass( "ui-state-hover" );
323		this.focusable.removeClass( "ui-state-focus" );
324	},
325	_destroy: $.noop,
326
327	widget: function() {
328		return this.element;
329	},
330
331	option: function( key, value ) {
332		var options = key,
333			parts,
334			curOption,
335			i;
336
337		if ( arguments.length === 0 ) {
338			// don't return a reference to the internal hash
339			return $.widget.extend( {}, this.options );
340		}
341
342		if ( typeof key === "string" ) {
343			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
344			options = {};
345			parts = key.split( "." );
346			key = parts.shift();
347			if ( parts.length ) {
348				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
349				for ( i = 0; i < parts.length - 1; i++ ) {
350					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
351					curOption = curOption[ parts[ i ] ];
352				}
353				key = parts.pop();
354				if ( arguments.length === 1 ) {
355					return curOption[ key ] === undefined ? null : curOption[ key ];
356				}
357				curOption[ key ] = value;
358			} else {
359				if ( arguments.length === 1 ) {
360					return this.options[ key ] === undefined ? null : this.options[ key ];
361				}
362				options[ key ] = value;
363			}
364		}
365
366		this._setOptions( options );
367
368		return this;
369	},
370	_setOptions: function( options ) {
371		var key;
372
373		for ( key in options ) {
374			this._setOption( key, options[ key ] );
375		}
376
377		return this;
378	},
379	_setOption: function( key, value ) {
380		this.options[ key ] = value;
381
382		if ( key === "disabled" ) {
383			this.widget()
384				.toggleClass( this.widgetFullName + "-disabled", !!value );
385
386			// If the widget is becoming disabled, then nothing is interactive
387			if ( value ) {
388				this.hoverable.removeClass( "ui-state-hover" );
389				this.focusable.removeClass( "ui-state-focus" );
390			}
391		}
392
393		return this;
394	},
395
396	enable: function() {
397		return this._setOptions({ disabled: false });
398	},
399	disable: function() {
400		return this._setOptions({ disabled: true });
401	},
402
403	_on: function( suppressDisabledCheck, element, handlers ) {
404		var delegateElement,
405			instance = this;
406
407		// no suppressDisabledCheck flag, shuffle arguments
408		if ( typeof suppressDisabledCheck !== "boolean" ) {
409			handlers = element;
410			element = suppressDisabledCheck;
411			suppressDisabledCheck = false;
412		}
413
414		// no element argument, shuffle and use this.element
415		if ( !handlers ) {
416			handlers = element;
417			element = this.element;
418			delegateElement = this.widget();
419		} else {
420			element = delegateElement = $( element );
421			this.bindings = this.bindings.add( element );
422		}
423
424		$.each( handlers, function( event, handler ) {
425			function handlerProxy() {
426				// allow widgets to customize the disabled handling
427				// - disabled as an array instead of boolean
428				// - disabled class as method for disabling individual parts
429				if ( !suppressDisabledCheck &&
430						( instance.options.disabled === true ||
431							$( this ).hasClass( "ui-state-disabled" ) ) ) {
432					return;
433				}
434				return ( typeof handler === "string" ? instance[ handler ] : handler )
435					.apply( instance, arguments );
436			}
437
438			// copy the guid so direct unbinding works
439			if ( typeof handler !== "string" ) {
440				handlerProxy.guid = handler.guid =
441					handler.guid || handlerProxy.guid || $.guid++;
442			}
443
444			var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
445				eventName = match[1] + instance.eventNamespace,
446				selector = match[2];
447			if ( selector ) {
448				delegateElement.delegate( selector, eventName, handlerProxy );
449			} else {
450				element.bind( eventName, handlerProxy );
451			}
452		});
453	},
454
455	_off: function( element, eventName ) {
456		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
457		element.unbind( eventName ).undelegate( eventName );
458	},
459
460	_delay: function( handler, delay ) {
461		function handlerProxy() {
462			return ( typeof handler === "string" ? instance[ handler ] : handler )
463				.apply( instance, arguments );
464		}
465		var instance = this;
466		return setTimeout( handlerProxy, delay || 0 );
467	},
468
469	_hoverable: function( element ) {
470		this.hoverable = this.hoverable.add( element );
471		this._on( element, {
472			mouseenter: function( event ) {
473				$( event.currentTarget ).addClass( "ui-state-hover" );
474			},
475			mouseleave: function( event ) {
476				$( event.currentTarget ).removeClass( "ui-state-hover" );
477			}
478		});
479	},
480
481	_focusable: function( element ) {
482		this.focusable = this.focusable.add( element );
483		this._on( element, {
484			focusin: function( event ) {
485				$( event.currentTarget ).addClass( "ui-state-focus" );
486			},
487			focusout: function( event ) {
488				$( event.currentTarget ).removeClass( "ui-state-focus" );
489			}
490		});
491	},
492
493	_trigger: function( type, event, data ) {
494		var prop, orig,
495			callback = this.options[ type ];
496
497		data = data || {};
498		event = $.Event( event );
499		event.type = ( type === this.widgetEventPrefix ?
500			type :
501			this.widgetEventPrefix + type ).toLowerCase();
502		// the original event may come from any element
503		// so we need to reset the target on the new event
504		event.target = this.element[ 0 ];
505
506		// copy original event properties over to the new event
507		orig = event.originalEvent;
508		if ( orig ) {
509			for ( prop in orig ) {
510				if ( !( prop in event ) ) {
511					event[ prop ] = orig[ prop ];
512				}
513			}
514		}
515
516		this.element.trigger( event, data );
517		return !( $.isFunction( callback ) &&
518			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
519			event.isDefaultPrevented() );
520	}
521};
522
523$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
524	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
525		if ( typeof options === "string" ) {
526			options = { effect: options };
527		}
528		var hasOptions,
529			effectName = !options ?
530				method :
531				options === true || typeof options === "number" ?
532					defaultEffect :
533					options.effect || defaultEffect;
534		options = options || {};
535		if ( typeof options === "number" ) {
536			options = { duration: options };
537		}
538		hasOptions = !$.isEmptyObject( options );
539		options.complete = callback;
540		if ( options.delay ) {
541			element.delay( options.delay );
542		}
543		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
544			element[ method ]( options );
545		} else if ( effectName !== method && element[ effectName ] ) {
546			element[ effectName ]( options.duration, options.easing, callback );
547		} else {
548			element.queue(function( next ) {
549				$( this )[ method ]();
550				if ( callback ) {
551					callback.call( element[ 0 ] );
552				}
553				next();
554			});
555		}
556	};
557});
558
559var widget = $.widget;
560
561
562
563}));
564
565(function($) {
566
567    $.fn.autosave = function(options) {
568        var identifier = $.map(this, function(obj, i) {
569            return $(obj).attr("id") + $(obj).attr("name")
570        }).join();
571
572        var autosave = Autosave.getInstance(identifier);
573        autosave.protect(this, options);
574        return autosave;
575    };
576
577    var dataSender = {};
578
579    dataSender.set = function(key, value) {
580    };
581
582    dataSender.get = function(key) {
583    };
584
585    dataSender.remove = function(key) {
586    };
587
588    Autosave = (function() {
589        var params = {
590            instantiated: [],
591            started: []
592        };
593
594        function init() {
595
596            return {
597                stopTimer: function() {
598                    this.targets = [];
599                    clearTimeout(this.timeoutId);
600                    clearTimeout(this.timeoutInnerId);
601                },
602                setInstanceIdentifier: function(identifier) {
603                    this.identifier = identifier
604                },
605                getInstanceIdentifier: function() {
606                    return this.identifier;
607                },
608                /**
609                 * Set plugin initial options
610                 *
611                 * @param [Object] options
612                 *
613                 * @return void
614                 */
615                setInitialOptions: function(options) {
616                    var defaults = {
617                        excludeFields: [],
618                        customKeySuffix: "",
619                        locationBased: false,
620                        timeout: 0,
621                        autoRelease: true,
622                        onSave: function() {
623                        },
624                        onBeforeRestore: function() {
625                        },
626                        onRestore: function() {
627                        },
628                        onRelease: function() {
629                        }
630                    };
631                    this.options = this.options || $.extend(defaults, options);
632                    this.dataSender = dataSender;
633                },
634                /**
635                 * Set plugin options
636                 *
637                 * @param [Object] options
638                 *
639                 * @return void
640                 */
641                setOptions: function(options) {
642                    this.options = this.options || this.setInitialOptions(options);
643                    this.options = $.extend(this.options, options);
644                },
645                /**
646                 * Protect specified forms, store it's fields data to local storage and restore them on page load
647                 *
648                 * @param [Object] targets		forms object(s), result of jQuery selector
649                 * @param Object options			plugin options
650                 *
651                 * @return void
652                 */
653                protect: function(targets, options) {
654                    this.setOptions(options);
655                    targets = targets || {};
656                    var self = this;
657                    this.targets = this.targets || [];
658                    this.href = location.hostname + location.pathname + location.search + location.hash;
659                    this.targets = $.merge(this.targets, targets);
660                    this.targets = $.unique(this.targets);
661                    this.targets = $(this.targets);
662
663                    if (self.options.restore == true) {
664                        self.restoreAllData();
665                    }
666                    /*
667                     var callback_result = self.options.onBeforeRestore.call(self);
668                     if (callback_result === undefined || callback_result) {
669                     self.restoreAllData();
670                     }
671                     
672                     if (this.options.autoRelease) {
673                     self.bindReleaseData();
674                     }
675                     */
676//                    if (!params.started[ this.getInstanceIdentifier() ]) {
677                    if (self.isCKEditorPresent()) {
678                        var intervalId = setInterval(function() {
679                            if (CKEDITOR.isLoaded) {
680                                clearInterval(intervalId);
681                                self.bindSaveData();
682                                params.started[ self.getInstanceIdentifier() ] = true;
683                            }
684                        }, 100);
685                    } else {
686                        self.bindSaveData();
687                        params.started[ self.getInstanceIdentifier() ] = true;
688                    }
689//                    }
690                },
691                isCKEditorPresent: function() {
692                    if (this.isCKEditorExists()) {
693                        CKEDITOR.isLoaded = false;
694                        CKEDITOR.on('instanceReady', function() {
695                            CKEDITOR.isLoaded = true;
696                        });
697                        var self = this;
698                        var cke_element_exsts = false;
699                        //cke exists but instances not found
700                        self.targets.each(function() {
701                            self.findFieldsToProtect($(this)).each(function() {
702                                var field = $(this);
703                                if ($("#cke_" + field.attr('id')).length) {
704                                    cke_element_exsts = true;
705                                }
706                            });
707                        });
708                        return cke_element_exsts;
709                    } else {
710                        return false;
711                    }
712                },
713                isCKEditorExists: function() {
714                    return typeof CKEDITOR != "undefined";
715                },
716                findFieldsToProtect: function(target) {
717                    return target.find(":input").not(":submit").not(":reset").not(":button").not(":file").not(":password").not(":disabled").not("[readonly]");
718                },
719                /**
720                 * Bind saving data
721                 *
722                 * @return void
723                 */
724                bindSaveData: function() {
725                    var self = this;
726
727                    if (self.options.timeout) {
728                        self.saveDataByTimeout();
729                        if (self.options.noactive == 1) {
730                            self.targets.each(function() {
731                                self.findFieldsToProtect($(this)).each(function() {
732                                    if ($.inArray(this, self.options.excludeFields) !== -1) {
733                                        return true;
734                                    }
735                                    var field = $(this);
736                                    self.bindResetTimerOnChange(field);
737                                });
738                            });
739                        }
740                    }
741                    if (self.options.onkeys)
742                        self.targets.each(function() {
743                            var targetFormIdAndName = $(this).attr("id") + $(this).attr("name");
744                            self.findFieldsToProtect($(this)).each(function() {
745                                if ($.inArray(this, self.options.excludeFields) !== -1) {
746                                    // Returning non-false is the same as a continue statement in a for loop; it will skip immediately to the next iteration.
747                                    return true;
748                                }
749                                var field = $(this);
750                                var prefix = (self.options.locationBased ? self.href : "") + targetFormIdAndName + field.attr("name") + self.options.customKeySuffix;
751                                if (field.is(":text") || field.is("textarea")) {
752                                    if (!self.options.timeout) {
753                                        self.bindSaveDataImmediately(field, prefix);
754                                    }
755                                }
756                                self.bindSaveDataOnChange(field);
757                            });
758                        });
759                },
760                /**
761                 * Save all protected forms data to Local Storage.
762                 * Common method, necessary to not lead astray user firing 'data is saved' when select/checkbox/radio
763                 * is changed and saved, while text field data is saved only by timeout
764                 *
765                 * @return void
766                 */
767                saveAllData: function() {
768                    var self = this;
769                    self.targets.each(function() {
770                        var targetFormIdAndName = $(this).attr("id") + $(this).attr("name");
771                        var multiCheckboxCache = {};
772
773                        self.findFieldsToProtect($(this)).each(function() {
774                            var field = $(this);
775                            if ($.inArray(this, self.options.excludeFields) !== -1 || field.attr("name") === undefined) {
776                                // Returning non-false is the same as a continue statement in a for loop; it will skip immediately to the next iteration.
777                                return true;
778                            }
779                            var prefix = (self.options.locationBased ? self.href : "") + targetFormIdAndName + field.attr("name") + self.options.customKeySuffix;
780                            var value = field.val();
781
782                            if (field.is(":checkbox")) {
783                                if (field.attr("name").indexOf("[") !== -1) {
784                                    if (multiCheckboxCache[ field.attr("name") ] === true) {
785                                        return;
786                                    }
787                                    value = [];
788                                    $("[name='" + field.attr("name") + "']:checked").each(function() {
789                                        value.push($(this).val());
790                                    });
791                                    multiCheckboxCache[ field.attr("name") ] = true;
792                                } else {
793                                    value = field.is(":checked");
794                                }
795                                self.saveToStorage(prefix, value, false);
796                            } else if (field.is(":radio")) {
797                                if (field.is(":checked")) {
798                                    value = field.val();
799                                    self.saveToStorage(prefix, value, false);
800                                }
801                            } else {
802                                if (self.isCKEditorExists()) {
803                                    var editor;
804                                    if (editor = CKEDITOR.instances[ field.attr("name") ] || CKEDITOR.instances[ field.attr("id") ]) {
805                                        editor.updateElement();
806                                        self.saveToStorage(prefix, field.val(), false);
807                                    } else {
808                                        self.saveToStorage(prefix, value, false);
809                                    }
810                                } else {
811                                    self.saveToStorage(prefix, value, false);
812                                }
813                            }
814                        });
815                    });
816                    self.options.onSave.call(self);
817                },
818                /**
819                 * Restore forms data from Local Storage
820                 *
821                 * @return void
822                 */
823                restoreAllData: function() {
824                    var self = this;
825                    var restored = false;
826
827                    self.targets.each(function() {
828                        var target = $(this);
829                        var targetFormIdAndName = $(this).attr("id") + $(this).attr("name");
830
831                        self.findFieldsToProtect(target).each(function() {
832                            if ($.inArray(this, self.options.excludeFields) !== -1) {
833                                // Returning non-false is the same as a continue statement in a for loop; it will skip immediately to the next iteration.
834                                return true;
835                            }
836                            var field = $(this);
837
838                            var prefix = (self.options.locationBased ? self.href : "") + targetFormIdAndName + field.attr("name") + self.options.customKeySuffix;
839                            var resque = (typeof self.options.fields_to_restore[field.attr("name")] !== 'undefined') ? self.options.fields_to_restore[field.attr("name")] : null;
840                            if (resque !== null) {
841                                self.restoreFieldsData(field, resque);
842                                restored = true;
843                            }
844                        });
845                    });
846
847//                    if (restored) {
848//                        self.options.onRestore.call(self);
849//                    }
850                },
851                /**
852                 * Restore form field data from local storage
853                 *
854                 * @param Object field		jQuery form element object
855                 * @param String resque	 previously stored fields data
856                 *
857                 * @return void
858                 */
859                restoreFieldsData: function(field, resque) {
860                    if (field.attr("name") === undefined) {
861                        return false;
862                    }
863                    if (field.is(":checkbox") && resque !== "false" && field.attr("name").indexOf("[") === -1) {
864                        field.attr("checked", "checked");
865                    } else if (field.is(":checkbox") && resque === "false" && field.attr("name").indexOf("[") === -1) {
866                        field.removeAttr("checked");
867                    } else if (field.is(":radio")) {
868                        if (field.val() === resque) {
869                            field.attr("checked", "checked");
870                        }
871                    } else if (field.attr("name").indexOf("[") === -1) {
872                        field.val(resque);
873                    } else {
874                        resque = resque.split(",");
875                        field.val(resque);
876                    }
877                },
878                /**
879                 * Bind immediate saving (on typing/checking/changing) field data to local storage when user fills it
880                 *
881                 * @param Object field		jQuery form element object
882                 * @param String prefix	 prefix used as key to store data in local storage
883                 *
884                 * @return void
885                 */
886                bindSaveDataImmediately: function(field, prefix) {
887                    var self = this;
888                    if ('onpropertychange' in field) {
889                        field.get(0).onpropertychange = function() {
890                            self.saveToStorage(prefix, field.val());
891                        };
892                    } else {
893                        field.get(0).oninput = function() {
894                            self.saveToStorage(prefix, field.val());
895                        };
896                    }
897                    if (this.isCKEditorExists()) {
898                        var editor;
899                        if (editor = CKEDITOR.instances[ field.attr("name") ] || CKEDITOR.instances[ field.attr("id") ]) {
900                            editor.document.on('keyup', function() {
901                                editor.updateElement();
902                                self.saveToStorage(prefix, field.val());
903                            });
904                        }
905                    }
906                },
907                /**
908                 * Save data to Local Storage and fire callback if defined
909                 *
910                 * @param String key
911                 * @param String value
912                 * @param Boolean [true] fireCallback
913                 *
914                 * @return void
915                 */
916                saveToStorage: function(key, value, fireCallback) {
917                    // if fireCallback is undefined it should be true
918                    fireCallback = fireCallback === undefined ? true : fireCallback;
919                    this.dataSender.set(key, value);
920                    if (fireCallback && value !== "") {
921                        this.options.onSave.call(this);
922                    }
923                },
924                /**
925                 * Bind saving field data on change
926                 *
927                 * @param Object field		jQuery form element object
928                 *
929                 * @return void
930                 */
931                bindSaveDataOnChange: function(field) {
932                    var self = this;
933                    field.change(function() {
934                        self.saveAllData();
935                    });
936                },
937                resetTimer: function(self) {
938                    if (nc_autosave_type === 'timer') {
939                        clearTimeout(self.timeoutId);
940                        clearTimeout(self.timeoutInnerId);
941                        var targetForms = self.targets;
942                        self.timeoutId = setTimeout((function() {
943                            function timeout() {
944                                self.saveAllData();
945                                self.timeoutInnerId = setTimeout(timeout, self.options.timeout * 1000);
946                            }
947                            return timeout;
948                        })(targetForms), self.options.timeout * 1000);
949                    }
950                },
951                bindResetTimerOnChange: function(field) {
952                    if (nc_autosave_type === 'timer') {
953                        var self = this;
954                        if ('onpropertychange' in field) {
955                            field.get(0).onpropertychange = function() {
956                                self.resetTimer(self);
957                            };
958                        } else {
959                            field.get(0).oninput = function() {
960                                self.resetTimer(self);
961                            };
962                        }
963                        if (this.isCKEditorExists()) {
964                            CKEDITOR.on('instanceReady', function(evt){
965                                var editor = evt.editor;
966                                if (editor = CKEDITOR.instances[ field.attr("name") ] || CKEDITOR.instances[ field.attr("id") ]) {
967                                    editor.document.on('keyup', function() {
968                                        editor.updateElement();
969                                        self.resetTimer(self);
970                                    });
971                                }
972                            });
973                        }
974                    }
975                },
976                /**
977                 * Saving (by timeout) field data to local storage when user fills it
978                 *
979                 * @return void
980                 */
981                saveDataByTimeout: function() {
982                    var self = this;
983                    var targetForms = self.targets;
984                    self.timeoutId = setTimeout((function() {
985                        function timeout() {
986                            self.saveAllData();
987                            self.timeoutInnerId = setTimeout(timeout, self.options.timeout * 1000);
988                        }
989                        return timeout;
990                    })(targetForms), self.options.timeout * 1000);
991                },
992                /**
993                 * Bind release form fields data from local storage on submit/reset form
994                 *
995                 * @return void
996                 */
997                bindReleaseData: function() {
998                    var self = this;
999                    self.targets.each(function() {
1000                        var target = $(this);
1001                        var formIdAndName = target.attr("id") + target.attr("name");
1002                        $(this).bind("submit reset", function() {
1003                            self.releaseData(formIdAndName, self.findFieldsToProtect(target));
1004                        });
1005                    });
1006                },
1007                /**
1008                 * Manually release form fields
1009                 *
1010                 * @return void
1011                 */
1012                manuallyReleaseData: function() {
1013                    var self = this;
1014                    self.targets.each(function() {
1015                        var target = $(this);
1016                        var formIdAndName = target.attr("id") + target.attr("name");
1017                        self.releaseData(formIdAndName, self.findFieldsToProtect(target));
1018                    });
1019                },
1020                /**
1021                 * Bind release form fields data from local storage on submit/resett form
1022                 *
1023                 * @param String targetFormIdAndName	a form identifier consists of its id and name glued
1024                 * @param Object fieldsToProtect		jQuery object c
1024ontains form fields to protect
1025                 *
1026                 * @return void
1027                 */
1028                releaseData: function(targetFormIdAndName, fieldsToProtect) {
1029                    var released = false;
1030                    var self = this;
1031
1032                    // Released form, are not started anymore. Fix for ajax loaded forms.
1033                    params.started[ self.getInstanceIdentifier() ] = false;
1034
1035                    fieldsToProtect.each(function() {
1036                        if ($.inArray(this, self.options.excludeFields) !== -1) {
1037                            // Returning non-false is the same as a continue statement in a for loop; it will skip immediately to the next iteration.
1038                            return true;
1039                        }
1040                        var field = $(this);
1041                        var prefix = (self.options.locationBased ? self.href : "") + targetFormIdAndName + field.attr("name") + self.options.customKeySuffix;
1042                        self.dataSender.remove(prefix);
1043                        released = true;
1044                    });
1045
1046                    if (released) {
1047                        self.options.onRelease.call(self);
1048                    }
1049                }
1050
1051            };
1052        }
1053
1054        return {
1055            getInstance: function(identifier) {
1056                if (!params.instantiated[ identifier ]) {
1057                    params.instantiated[ identifier ] = init();
1058                    params.instantiated[ identifier ].setInstanceIdentifier(identifier);
1059                    params.instantiated[ identifier ].setInitialOptions();
1060                }
1061                if (identifier) {
1062                    return params.instantiated[ identifier ];
1063                }
1064                return params.instantiated[ identifier ];
1065            },
1066            free: function() {
1067                params = {
1068                    instantiated: [],
1069                    started: []
1070                };
1071                return null;
1072            }
1073        };
1074    })();
1075})(jQuery);
1076
1077/*
1078 * jQuery Iframe Transport Plugin 1.8.3
1079 * https://github.com/blueimp/jQuery-File-Upload
1080 *
1081 * Copyright 2011, Sebastian Tschan
1082 * https://blueimp.net
1083 *
1084 * Licensed under the MIT license:
1085 * http://www.opensource.org/licenses/MIT
1086 */
1087
1088/* global define, require, window, document */
1089
1090(function (factory) {
1091    'use strict';
1092    if (typeof define === 'function' && define.amd) {
1093        // Register as an anonymous AMD module:
1094        define(['jquery'], factory);
1095    } else if (typeof exports === 'object') {
1096        // Node/CommonJS:
1097        factory(require('jquery'));
1098    } else {
1099        // Browser globals:
1100        factory(window.jQuery);
1101    }
1102}(function ($) {
1103    'use strict';
1104
1105    // Helper variable to create unique names for the transport iframes:
1106    var counter = 0;
1107
1108    // The iframe transport accepts four additional options:
1109    // options.fileInput: a jQuery collection of file input fields
1110    // options.paramName: the parameter name for the file form data,
1111    //  overrides the name property of the file input field(s),
1112    //  can be a string or an array of strings.
1113    // options.formData: an array of objects with name and value properties,
1114    //  equivalent to the return data of .serializeArray(), e.g.:
1115    //  [{name: 'a', value: 1}, {name: 'b', value: 2}]
1116    // options.initialIframeSrc: the URL of the initial iframe src,
1117    //  by default set to "javascript:false;"
1118    $.ajaxTransport('iframe', function (options) {
1119        if (options.async) {
1120            // javascript:false as initial iframe src
1121            // prevents warning popups on HTTPS in IE6:
1122            /*jshint scripturl: true */
1123            var initialIframeSrc = options.initialIframeSrc || 'javascript:false;',
1124            /*jshint scripturl: false */
1125                form,
1126                iframe,
1127                addParamChar;
1128            return {
1129                send: function (_, completeCallback) {
1130                    form = $('<form style="display:none;"></form>');
1131                    form.attr('accept-charset', options.formAcceptCharset);
1132                    addParamChar = /\?/.test(options.url) ? '&' : '?';
1133                    // XDomainRequest only supports GET and POST:
1134                    if (options.type === 'DELETE') {
1135                        options.url = options.url + addParamChar + '_method=DELETE';
1136                        options.type = 'POST';
1137                    } else if (options.type === 'PUT') {
1138                        options.url = options.url + addParamChar + '_method=PUT';
1139                        options.type = 'POST';
1140                    } else if (options.type === 'PATCH') {
1141                        options.url = options.url + addParamChar + '_method=PATCH';
1142                        options.type = 'POST';
1143                    }
1144                    // IE versions below IE8 cannot set the name property of
1145                    // elements that have already been added to the DOM,
1146                    // so we set the name along with the iframe HTML markup:
1147                    counter += 1;
1148                    iframe = $(
1149                        '<iframe src="' + initialIframeSrc +
1150                            '" name="iframe-transport-' + counter + '"></iframe>'
1151                    ).bind('load', function () {
1152                        var fileInputClones,
1153                            paramNames = $.isArray(options.paramName) ?
1154                                    options.paramName : [options.paramName];
1155                        iframe
1156                            .unbind('load')
1157                            .bind('load', function () {
1158                                var response;
1159                                // Wrap in a try/catch block to catch exceptions thrown
1160                                // when trying to access cross-domain iframe contents:
1161                                try {
1162                                    response = iframe.contents();
1163                                    // Google Chrome and Firefox do not throw an
1164                                    // exception when calling iframe.contents() on
1165                                    // cross-domain requests, so we unify the response:
1166                                    if (!response.length || !response[0].firstChild) {
1167                                        throw new Error();
1168                                    }
1169                                } catch (e) {
1170                                    response = undefined;
1171                                }
1172                                // The complete callback returns the
1173                                // iframe content document as response object:
1174                                completeCallback(
1175                                    200,
1176                                    'success',
1177                                    {'iframe': response}
1178                                );
1179                                // Fix for IE endless progress bar activity bug
1180                                // (happens on form submits to iframe targets):
1181                                $('<iframe src="' + initialIframeSrc + '"></iframe>')
1182                                    .appendTo(form);
1183                                window.setTimeout(function () {
1184                                    // Removing the form in a setTimeout call
1185                                    // allows Chrome's developer tools to display
1186                                    // the response result
1187                                    form.remove();
1188                                }, 0);
1189                            });
1190                        form
1191                            .prop('target', iframe.prop('name'))
1192                            .prop('action', options.url)
1193                            .prop('method', options.type);
1194                        if (options.formData) {
1195                            $.each(options.formData, function (index, field) {
1196                                $('<input type="hidden"/>')
1197                                    .prop('name', field.name)
1198                                    .val(field.value)
1199                                    .appendTo(form);
1200                            });
1201                        }
1202                        if (options.fileInput && options.fileInput.length &&
1203                                options.type === 'POST') {
1204                            fileInputClones = options.fileInput.clone();
1205                            // Insert a clone for each file input field:
1206                            options.fileInput.after(function (index) {
1207                                return fileInputClones[index];
1208                            });
1209                            if (options.paramName) {
1210                                options.fileInput.each(function (index) {
1211                                    $(this).prop(
1212                                        'name',
1213                                        paramNames[index] || options.paramName
1214                                    );
1215                                });
1216                            }
1217                            // Appending the file input fields to the hidden form
1218                            // removes them from their original location:
1219                            form
1220                                .append(options.fileInput)
1221                                .prop('enctype', 'multipart/form-data')
1222                                // enctype must be set as encoding for IE:
1223                                .prop('encoding', 'multipart/form-data');
1224                            // Remove the HTML5 form attribute from the input(s):
1225                            options.fileInput.removeAttr('form');
1226                        }
1227                        form.submit();
1228                        // Insert the file input fields at their original location
1229                        // by replacing the clones with the originals:
1230                        if (fileInputClones && fileInputClones.length) {
1231                            options.fileInput.each(function (index, input) {
1232                                var clone = $(fileInputClones[index]);
1233                                // Restore the original name and form properties:
1234                                $(input)
1235                                    .prop('name', clone.prop('name'))
1236                                    .attr('form', clone.attr('form'));
1237                                clone.replaceWith(input);
1238                            });
1239                        }
1240                    });
1241                    form.append(iframe).appendTo(document.body);
1242                },
1243                abort: function () {
1244                    if (iframe) {
1245                        // javascript:false as iframe src aborts the request
1246                        // and prevents warning popups on HTTPS in IE6.
1247                        // concat is used to avoid the "Script URL" JSLint error:
1248                        iframe
1249                            .unbind('load')
1250                            .prop('src', initialIframeSrc);
1251                    }
1252                    if (form) {
1253                        form.remove();
1254                    }
1255                }
1256            };
1257        }
1258    });
1259
1260    // The iframe transport returns the iframe content document as response.
1261    // The following adds converters from iframe to text, json, html, xml
1262    // and script.
1263    // Please note that the Content-Type for JSON responses has to be text/plain
1264    // or text/html, if the browser doesn't include application/json in the
1265    // Accept header, else IE will show a download dialog.
1266    // The Content-Type for XML responses on the other hand has to be al
1266ways
1267    // application/xml or text/xml, so IE properly parses the XML response.
1268    // See also
1269    // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation
1270    $.ajaxSetup({
1271        converters: {
1272            'iframe text': function (iframe) {
1273                return iframe && $(iframe[0].body).text();
1274            },
1275            'iframe json': function (iframe) {
1276                return iframe && $.parseJSON($(iframe[0].body).text());
1277            },
1278            'iframe html': function (iframe) {
1279                return iframe && $(iframe[0].body).html();
1280            },
1281            'iframe xml': function (iframe) {
1282                var xmlDoc = iframe && iframe[0];
1283                return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc :
1284                        $.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) ||
1285                            $(xmlDoc.body).html());
1286            },
1287            'iframe script': function (iframe) {
1288                return iframe && $.globalEval($(iframe[0].body).text());
1289            }
1290        }
1291    });
1292
1293}));
1294
1295(function(J,l,W){var K={transition:"elastic",speed:300,width:false,initialWidth:"600",innerWidth:false,maxWidth:false,height:false,initialHeight:"450",innerHeight:false,maxHeight:false,scalePhotos:true,scrolling:true,inline:false,html:false,iframe:false,fastIframe:true,photo:false,href:false,title:false,rel:false,opacity:0.9,preloading:true,current:"image {current} of {total}",previous:"previous",next:"next",close:"close",xhrError:"This content failed to load.",imgError:"This image failed to load.",open:false,returnFocus:true,reposition:true,loop:true,slideshow:false,slideshowAuto:true,slideshowSpeed:2500,slideshowStart:"start slideshow",slideshowStop:"stop slideshow",onOpen:false,onLoad:false,onComplete:false,onCleanup:false,onClosed:false,overlayClose:true,escKey:true,arrowKey:true,top:false,bottom:false,left:false,right:false,fixed:false,data:undefined},x="colorbox",S="cbox",r=S+"Element",V=S+"_open",e=S+"_load",U=S+"_complete",u=S+"_cleanup",ac=S+"_closed",i=S+"_purge",v=!J.support.leadingWhitespace,af=v&&!W.XMLHttpRequest,aa=S+"_IE6",Q,ag,ah,d,H,p,b,P,c,Z,N,k,h,o,t,X,s,R,z,B,ae,ai,m,g,a,w,I,n,D,Y,M,A,L,ad="div",ab;function G(aj,am,al){var ak=l.createElement(aj);if(am){ak.id=S+am}if(al){ak.style.cssText=al}return J(ak)}function E(ak){var aj=c.length,al=(I+ak)%aj;return(al<0)?aj+al:al}function O(aj,ak){return Math.round((/%/.test(aj)?((ak==="x"?Z.width():Z.height())/100):1)*parseInt(aj,10))}function C(aj){return ae.photo||/\.(gif|png|jp(e|g|eg)|bmp|ico)((#|\?).*)?$/i.test(aj)}function T(){var aj,ak=J.data(w,x);if(ak==null){ae=J.extend({},K);if(console&&console.log){console.log("Error: cboxElement missing settings object")}}else{ae=J.extend({},ak)}for(aj in ae){if(J.isFunction(ae[aj])&&aj.slice(0,2)!=="on"){ae[aj]=ae[aj].call(w)}}ae.rel=ae.rel||w.rel||J(w).data("rel")||"nofollow";ae.href=ae.href||J(w).attr("href");ae.title=ae.title||w.title;if(typeof ae.href==="string"){ae.href=J.trim(ae.href)}}function F(aj,ak){J(l).trigger(aj);J("*",ag).trigger(aj);if(ak){ak.call(w)}}function y(){var aj,al=S+"Slideshow_",am="click."+S,an,ak;if(ae.slideshow&&c[1]){an=function(){X.html(ae.slideshowStop).unbind(am).bind(U,function(){if(ae.loop||c[I+1]){aj=setTimeout(L.next,ae.slideshowSpeed)}}).bind(e,function(){clearTimeout(aj)}).one(am+" "+u,ak);ag.removeClass(al+"off").addClass(al+"on");aj=setTimeout(L.next,ae.slideshowSpeed)};ak=function(){clearTimeout(aj);X.html(ae.slideshowStart).unbind([U,e,u,am].join(" ")).one(am,function(){L.next();an()});ag.removeClass(al+"on").addClass(al+"off")};if(ae.slideshowAuto){an()}else{ak()}}else{ag.removeClass(al+"off "+al+"on")}}function f(aj){if(!M){w=aj;T();c=J(w);I=0;if(ae.rel!=="nofollow"){c=J("."+r).filter(function(){var al=J.data(this,x),ak;if(al){ak=J(this).data("rel")||al.rel||this.rel}return(ak===ae.rel)});I=c.index(w);if(I===-1){c=c.add(w);I=c.length-1}}if(!D){D=Y=true;ag.show();if(ae.returnFocus){J(w).blur();J(l).one(ac,function(){J(w).focus()})}Q.css({opacity:+ae.opacity,cursor:ae.overlayClose?"pointer":"auto"}).show();ae.w=O(ae.initialWidth,"x");ae.h=O(ae.initialHeight,"y");L.position();if(af){Z.bind("resize."+aa+" scroll."+aa,function(){Q.css({width:Z.width(),height:Z.height(),top:Z.scrollTop(),left:Z.scrollLeft()})}).trigger("resize."+aa)}F(V,ae.onOpen);B.add(o).hide();z.html(ae.close).show()}L.load(true)}}function q(){if(!ag&&l.body){ab=false;Z=J(W);ag=G(ad).attr({id:x,"class":v?S+(af?"IE6":"IE"):""}).hide();Q=G(ad,"Overlay",af?"position:absolute":"").hide();h=G(ad,"LoadingOverlay").add(G(ad,"LoadingGraphic"));ah=G(ad,"Wrapper");d=G(ad,"Content").append(N=G(ad,"LoadedContent","width:0; height:0; overflow:hidden"),o=G(ad,"Title"),t=G(ad,"Current"),s=G(ad,"Next"),R=G(ad,"Previous"),X=G(ad,"Slideshow").bind(V,y),z=G(ad,"Close"));ah.append(G(ad).append(G(ad,"TopLeft"),H=G(ad,"TopCenter"),G(ad,"TopRight")),G(ad,false,"clear:left").append(p=G(ad,"MiddleLeft"),d,b=G(ad,"MiddleRight")),G(ad,false,"clear:left").append(G(ad,"BottomLeft"),P=G(ad,"BottomCenter"),G(ad,"BottomRight"))).find("div div").css({"float":"left"});k=G(ad,false,"position:absolute; width:9999px; visibility:hidden; display:none");B=s.add(R).add(t).add(X);J(l.body).append(Q,ag.append(ah,k))}}function j(){if(ag){if(!ab){ab=true;ai=H.height()+P.height()+d.outerHeight(true)-d.height();
1295m=p.width()+b.width()+d.outerWidth(true)-d.width();g=N.outerHeight(true);a=N.outerWidth(true);s.click(function(){L.next()});R.click(function(){L.prev()});z.click(function(){L.close()});Q.click(function(){if(ae.overlayClose){L.close()}});J(l).bind("keydown."+S,function(ak){var aj=ak.keyCode;if(D&&ae.escKey&&aj===27){ak.preventDefault();L.close()}if(D&&ae.arrowKey&&c[1]){if(aj===37){ak.preventDefault();R.click()}else{if(aj===39){ak.preventDefault();s.click()}}}});J(l).delegate("."+r,"click",function(aj){if(!(aj.which>1||aj.shiftKey||aj.altKey||aj.metaKey)){aj.preventDefault();f(this)}})}return true}return false}if(J.colorbox){return}J(q);L=J.fn[x]=J[x]=function(aj,al){var ak=this;aj=aj||{};q();if(j()){if(!ak[0]){if(ak.selector){return ak}ak=J("<a/>");aj.open=true}if(al){aj.onComplete=al}ak.each(function(){J.data(this,x,J.extend({},J.data(this,x)||K,aj))}).addClass(r);if((J.isFunction(aj.open)&&aj.open.call(ak))||aj.open){f(ak[0])}}return ak};L.position=function(al,an){var ap,ar=0,ak=0,ao=ag.offset(),aj,am;Z.unbind("resize."+S);ag.css({top:-90000,left:-90000});aj=Z.scrollTop();am=Z.scrollLeft();if(ae.fixed&&!af){ao.top-=aj;ao.left-=am;ag.css({position:"fixed"})}else{ar=aj;ak=am;ag.css({position:"absolute"})}if(ae.right!==false){ak+=Math.max(Z.width()-ae.w-a-m-O(ae.right,"x"),0)}else{if(ae.left!==false){ak+=O(ae.left,"x")}else{ak+=Math.round(Math.max(Z.width()-ae.w-a-m,0)/2)}}if(ae.bottom!==false){ar+=Math.max(Z.height()-ae.h-g-ai-O(ae.bottom,"y"),0)}else{if(ae.top!==false){ar+=O(ae.top,"y")}else{ar+=Math.round(Math.max(Z.height()-ae.h-g-ai,0)/2)}}ag.css({top:ao.top,left:ao.left});al=(ag.width()===ae.w+a&&ag.height()===ae.h+g)?0:al||0;ah[0].style.width=ah[0].style.height="9999px";function aq(at){H[0].style.width=P[0].style.width=d[0].style.width=(parseInt(at.style.width,10)-m)+"px";d[0].style.height=p[0].style.height=b[0].style.height=(parseInt(at.style.height,10)-ai)+"px"}ap={width:ae.w+a+m,height:ae.h+g+ai,top:ar,left:ak};if(al===0){ag.css(ap)}ag.dequeue().animate(ap,{duration:al,complete:function(){aq(this);Y=false;ah[0].style.width=(ae.w+a+m)+"px";ah[0].style.height=(ae.h+g+ai)+"px";if(ae.reposition){setTimeout(function(){Z.bind("resize."+S,L.position)},1)}if(an){an()}},step:function(){aq(this)}})};L.resize=function(aj){if(D){aj=aj||{};if(aj.width){ae.w=O(aj.width,"x")-a-m}if(aj.innerWidth){ae.w=O(aj.innerWidth,"x")}N.css({width:ae.w});if(aj.height){ae.h=O(aj.height,"y")-g-ai}if(aj.innerHeight){ae.h=O(aj.innerHeight,"y")}if(!aj.innerHeight&&!aj.height){N.css({height:"auto"});ae.h=N.height()}N.css({height:ae.h});L.position(ae.transition==="none"?0:ae.speed)}};L.prep=function(ak){if(!D){return}var an,al=ae.transition==="none"?0:ae.speed;N.remove();N=G(ad,"LoadedContent").append(ak);function aj(){ae.w=ae.w||N.width();ae.w=ae.mw&&ae.mw<ae.w?ae.mw:ae.w;return ae.w}function am(){ae.h=ae.h||N.height();ae.h=ae.mh&&ae.mh<ae.h?ae.mh:ae.h;return ae.h}N.hide().appendTo(k.show()).css({width:aj(),overflow:ae.scrolling?"auto":"hidden"}).css({height:am()}).prependTo(d);k.hide();J(n).css({"float":"none"});an=function(){var at=c.length,aq,ar="frameBorder",ao="allowTransparency",ap;if(!D){return}function au(){if(v){ag[0].style.removeAttribute("filter")}}ap=function(){clearTimeout(A);h.detach().hide();F(U,ae.onComplete)};if(v){if(n){N.fadeIn(100)}}o.html(ae.title).add(N).show();if(at>1){if(typeof ae.current==="string"){t.html(ae.current.replace("{current}",I+1).replace("{total}",at)).show()}s[(ae.loop||I<at-1)?"show":"hide"]().html(ae.next);R[(ae.loop||I)?"show":"hide"]().html(ae.previous);if(ae.slideshow){X.show()}if(ae.preloading){J.each([E(-1),E(1)],function(){var ay,av,aw=c[this],ax=J.data(aw,x);if(ax&&ax.href){ay=ax.href;if(J.isFunction(ay)){ay=ay.call(aw)}}else{ay=aw.href}if(C(ay)){av=new Image();av.src=ay}})}}else{B.hide()}if(ae.iframe){aq=G("iframe")[0];if(ar in aq){aq[ar]=0}if(ao in aq){aq[ao]="true"}if(!ae.scrolling){aq.scrolling="no"}J(aq).attr({src:ae.href,name:(new Date()).getTime(),"class":S+"Iframe",allowFullScreen:true,webkitAllowFullScreen:true,mozallowfullscreen:true}).one("load",ap).appendTo(N);J(l).one(i,function(){aq.src="//about:blank"});if(ae.fastIframe){J(aq).trigger("load")}}else{ap()}
1295if(ae.transition==="fade"){ag.fadeTo(al,1,au)}else{au()}};if(ae.transition==="fade"){ag.fadeTo(al,0,function(){L.position(0,an)})}else{L.position(al,an)}};L.load=function(am){var al,an,ak=L.prep,aj;Y=true;n=false;w=c[I];if(!am){T()}F(i);F(e,ae.onLoad);ae.h=ae.height?O(ae.height,"y")-g-ai:ae.innerHeight&&O(ae.innerHeight,"y");ae.w=ae.width?O(ae.width,"x")-a-m:ae.innerWidth&&O(ae.innerWidth,"x");ae.mw=ae.w;ae.mh=ae.h;if(ae.maxWidth){ae.mw=O(ae.maxWidth,"x")-a-m;ae.mw=ae.w&&ae.w<ae.mw?ae.w:ae.mw}if(ae.maxHeight){ae.mh=O(ae.maxHeight,"y")-g-ai;ae.mh=ae.h&&ae.h<ae.mh?ae.h:ae.mh}al=ae.href;A=setTimeout(function(){h.show().appendTo(d)},100);if(ae.inline){aj=G(ad).hide().insertBefore(J(al)[0]);J(l).one(i,function(){aj.replaceWith(N.children())});ak(J(al))}else{if(ae.iframe){ak(" ")}else{if(ae.html){ak(ae.html)}else{if(C(al)){J(n=new Image()).addClass(S+"Photo").bind("error",function(){ae.title=false;ak(G(ad,"Error").html(ae.imgError))}).load(function(){var ao;n.onload=null;if(ae.scalePhotos){an=function(){n.height-=n.height*ao;n.width-=n.width*ao};if(ae.mw&&n.width>ae.mw){ao=(n.width-ae.mw)/n.width;an()}if(ae.mh&&n.height>ae.mh){ao=(n.height-ae.mh)/n.height;an()}}if(ae.h){n.style.marginTop=Math.max(ae.h-n.height,0)/2+"px"}if(c[1]&&(ae.loop||c[I+1])){n.style.cursor="pointer";n.onclick=function(){L.next()}}if(v){n.style.msInterpolationMode="bicubic"}setTimeout(function(){ak(n)},1)});setTimeout(function(){n.src=al},1)}else{if(al){k.load(al,ae.data,function(ap,ao){ak(ao==="error"?G(ad,"Error").html(ae.xhrError):J(this).contents())})}}}}}};L.next=function(){if(!Y&&c[1]&&(ae.loop||c[I+1])){I=E(1);L.load()}};L.prev=function(){if(!Y&&c[1]&&(ae.loop||I)){I=E(-1);L.load()}};L.close=function(){if(D&&!M){M=true;D=false;F(u,ae.onCleanup);Z.unbind("."+S+" ."+aa);Q.fadeTo(200,0);ag.stop().fadeTo(300,0,function(){ag.add(Q).css({opacity:1,cursor:"auto"}).hide();F(i);N.remove();setTimeout(function(){M=false;F(ac,ae.onClosed)},1)})}};L.remove=function(){J([]).add(ag).add(Q).remove();ag=null;J("."+r).removeData(x).removeClass(r);J(l).undelegate("."+r)};L.element=function(){return J(w)};L.settings=K}(jQuery,document,window));
1296/*
1297 * jQuery File Upload Plugin 5.42.3
1298 * https://github.com/blueimp/jQuery-File-Upload
1299 *
1300 * Copyright 2010, Sebastian Tschan
1301 * https://blueimp.net
1302 *
1303 * Licensed under the MIT license:
1304 * http://www.opensource.org/licenses/MIT
1305 */
1306
1307/* jshint nomen:false */
1308/* global define, require, window, document, location, Blob, FormData */
1309
1310(function (factory) {
1311    'use strict';
1312    if (typeof define === 'function' && define.amd) {
1313        // Register as an anonymous AMD module:
1314        define([
1315            'jquery',
1316            'jquery.ui.widget'
1317        ], factory);
1318    } else if (typeof exports === 'object') {
1319        // Node/CommonJS:
1320        factory(
1321            require('jquery'),
1322            require('./vendor/jquery.ui.widget')
1323        );
1324    } else {
1325        // Browser globals:
1326        factory(window.jQuery);
1327    }
1328}(function ($) {
1329    'use strict';
1330
1331    // Detect file input support, based on
1332    // http://viljamis.com/blog/2012/file-upload-support-on-mobile/
1333    $.support.fileInput = !(new RegExp(
1334        // Handle devices which give false positives for the feature detection:
1335        '(Android (1\\.[0156]|2\\.[01]))' +
1336            '|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' +
1337            '|(w(eb)?OSBrowser)|(webOS)' +
1338            '|(Kindle/(1\\.0|2\\.[05]|3\\.0))'
1339    ).test(window.navigator.userAgent) ||
1340        // Feature detection for all other devices:
1341        $('<input type="file">').prop('disabled'));
1342
1343    // The FileReader API is not actually used, but works as feature detection,
1344    // as some Safari versions (5?) support XHR file uploads via the FormData API,
1345    // but not non-multipart XHR file uploads.
1346    // window.XMLHttpRequestUpload is not available on IE10, so we check for
1347    // window.ProgressEvent instead to detect XHR2 file upload capability:
1348    $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader);
1349    $.support.xhrFormDataFileUpload = !!window.FormData;
1350
1351    // Detect support for Blob slicing (required for chunked uploads):
1352    $.support.blobSlice = window.Blob && (Blob.prototype.slice ||
1353        Blob.prototype.webkitSlice || Blob.prototype.mozSlice);
1354
1355    // Helper function to create drag handlers for dragover/dragenter/dragleave:
1356    function getDragHandler(type) {
1357        var isDragOver = type === 'dragover';
1358        return function (e) {
1359            e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
1360            var dataTransfer = e.dataTransfer;
1361            if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 &&
1362                    this._trigger(
1363                        type,
1364                        $.Event(type, {delegatedEvent: e})
1365                    ) !== false) {
1366                e.preventDefault();
1367                if (isDragOver) {
1368                    dataTransfer.dropEffect = 'copy';
1369                }
1370            }
1371        };
1372    }
1373
1374    // The fileupload widget listens for change events on file input fields defined
1375    // via fileInput setting and paste or drop events of the given dropZone.
1376    // In addition to the default jQuery Widget methods, the fileupload widget
1377    // exposes the "add" and "send" methods, to add or directly send files using
1378    // the fileupload API.
1379    // By default, files added via file input selection, paste, drag & drop or
1380    // "add" method are uploaded immediately, but it is possible to override
1381    // the "add" callback option to queue file uploads.
1382    $.widget('blueimp.fileupload', {
1383
1384        options: {
1385            // The drop target element(s), by the default the complete document.
1386            // Set to null to disable drag & drop support:
1387            dropZone: $(document),
1388            // The paste target element(s), by the default undefined.
1389            // Set to a DOM node or jQuery object to enable file pasting:
1390            pasteZone: undefined,
1391            // The file input field(s), that are listened to for change events.
1392            // If undefined, it is set to the file input fields inside
1393            // of the widget element on plugin initialization.
1394            // Set to null to disable the change listener.
1395            fileInput: undefined,
1396            // By default, the file input field is replaced with a clone after
1397            // each input field change event. This is required for iframe transport
1398            // queues and allows change events to be fired for the same file
1399            // selection, but can be disabled by setting the following option to false:
1400            replaceFileInput: true,
1401            // The parameter name for the file form data (the request argument name).
1402            // If undefined or empty, the name property of the file input field is
1403            // used, or "files[]" if the file input name property is also empty,
1404            // can be a string or an array of strings:
1405            paramName: undefined,
1406            // By default, each file of a selection is uploaded using an individual
1407            // request for XHR type uploads. Set to false to upload file
1408            // selections in one request each:
1409            singleFileUploads: true,
1410            // To limit the number of files uploaded with one XHR request,
1411            // set the following option to an integer greater than 0:
1412            limitMultiFileUploads: undefined,
1413            // The following option limits the number of files uploaded with one
1414            // XHR request to keep the request size under or equal to the defined
1415            // limit in bytes:
1416            limitMultiFileUploadSize: undefined,
1417            // Multipart file uploads add a number of bytes to each uploaded file,
1418            // therefore the following option adds an overhead for each file used
1419            // in the limitMultiFileUploadSize configuration:
1420            limitMultiFileUploadSizeOverhead: 512,
1421            // Set the following option to true to issue all file upload requests
1422            // in a sequential order:
1423            sequentialUploads: false,
1424            // To limit the number of concurrent uploads,
1425            // set the following option to an integer greater than 0:
1426            limitConcurrentUploads: undefined,
1427            // Set the following option to true to force iframe transport uploads:
1428            forceIframeTransport: false,
1429            // Set the following option to the location of a redirect url on the
1430            // origin server, for cross-domain iframe transport uploads:
1431            redirect: undefined,
1432            // The parameter name for the redirect url, sent as part of the form
1433            // data and set to 'redirect' if this option is empty:
1434            redirectParamName: undefined,
1435            // Set the following option to the location of a postMessage window,
1436            // to enable postMessage transport uploads:
1437            postMessage: undefined,
1438            // By default, XHR file uploads are sent as multipart/form-data.
1439            // The iframe transport is always using multipart/form-data.
1440            // Set to false to enable non-multipart XHR uploads:
1441            multipart: true,
1442            // To upload large files in smaller chunks, set the following option
1443            // to a preferred maximum chunk size. If set to 0, null or undefined,
1444            // or the browser does not support the required Blob API, files will
1445            // be uploaded as a whole.
1446            maxChunkSize: undefined,
1447            // When a non-multipart upload or a chunked multipart upload has been
1448            // aborted, this option can be used to resume the upload by setting
1449            // it to the size of the already uploaded bytes. This option is most
1450            // useful when modifying the options object inside of the "add" or
1451            // "send" callbacks, as the options are cloned for each file upload.
1452            uploadedBytes: undefined,
1453            // By default, failed (abort or error) file uploads are removed from the
1454            // global progress calculation. Set the following option to fal
1454se to
1455            // prevent recalculating the global progress data:
1456            recalculateProgress: true,
1457            // Interval in milliseconds to calculate and trigger progress events:
1458            progressInterval: 100,
1459            // Interval in milliseconds to calculate progress bitrate:
1460            bitrateInterval: 500,
1461            // By default, uploads are started automatically when adding files:
1462            autoUpload: true,
1463
1464            // Error and info messages:
1465            messages: {
1466                uploadedBytes: 'Uploaded bytes exceed file size'
1467            },
1468
1469            // Translation function, gets the message key to be translated
1470            // and an object with context specific data as arguments:
1471            i18n: function (message, context) {
1472                message = this.messages[message] || message.toString();
1473                if (context) {
1474                    $.each(context, function (key, value) {
1475                        message = message.replace('{' + key + '}', value);
1476                    });
1477                }
1478                return message;
1479            },
1480
1481            // Additional form data to be sent along with the file uploads can be set
1482            // using this option, which accepts an array of objects with name and
1483            // value properties, a function returning such an array, a FormData
1484            // object (for XHR file uploads), or a simple object.
1485            // The form of the first fileInput is given as parameter to the function:
1486            formData: function (form) {
1487                return form.serializeArray();
1488            },
1489
1490            // The add callback is invoked as soon as files are added to the fileupload
1491            // widget (via file input selection, drag & drop, paste or add API call).
1492            // If the singleFileUploads option is enabled, this callback will be
1493            // called once for each file in the selection for XHR file uploads, else
1494            // once for each file selection.
1495            //
1496            // The upload starts when the submit method is invoked on the data parameter.
1497            // The data object contains a files property holding the added files
1498            // and allows you to override plugin options as well as define ajax settings.
1499            //
1500            // Listeners for this callback can also be bound the following way:
1501            // .bind('fileuploadadd', func);
1502            //
1503            // data.submit() returns a Promise object and allows to attach additional
1504            // handlers using jQuery's Deferred callbacks:
1505            // data.submit().done(func).fail(func).always(func);
1506            add: function (e, data) {
1507                if (e.isDefaultPrevented()) {
1508                    return false;
1509                }
1510                if (data.autoUpload || (data.autoUpload !== false &&
1511                        $(this).fileupload('option', 'autoUpload'))) {
1512                    data.process().done(function () {
1513                        data.submit();
1514                    });
1515                }
1516            },
1517
1518            // Other callbacks:
1519
1520            // Callback for the submit event of each file upload:
1521            // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);
1522
1523            // Callback for the start of each file upload request:
1524            // send: function (e, data) {}, // .bind('fileuploadsend', func);
1525
1526            // Callback for successful uploads:
1527            // done: function (e, data) {}, // .bind('fileuploaddone', func);
1528
1529            // Callback for failed (abort or error) uploads:
1530            // fail: function (e, data) {}, // .bind('fileuploadfail', func);
1531
1532            // Callback for completed (success, abort or error) requests:
1533            // always: function (e, data) {}, // .bind('fileuploadalways', func);
1534
1535            // Callback for upload progress events:
1536            // progress: function (e, data) {}, // .bind('fileuploadprogress', func);
1537
1538            // Callback for global upload progress events:
1539            // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);
1540
1541            // Callback for uploads start, equivalent to the global ajaxStart event:
1542            // start: function (e) {}, // .bind('fileuploadstart', func);
1543
1544            // Callback for uploads stop, equivalent to the global ajaxStop event:
1545            // stop: function (e) {}, // .bind('fileuploadstop', func);
1546
1547            // Callback for change events of the fileInput(s):
1548            // change: function (e, data) {}, // .bind('fileuploadchange', func);
1549
1550            // Callback for paste events to the pasteZone(s):
1551            // paste: function (e, data) {}, // .bind('fileuploadpaste', func);
1552
1553            // Callback for drop events of the dropZone(s):
1554            // drop: function (e, data) {}, // .bind('fileuploaddrop', func);
1555
1556            // Callback for dragover events of the dropZone(s):
1557            // dragover: function (e) {}, // .bind('fileuploaddragover', func);
1558
1559            // Callback for the start of each chunk upload request:
1560            // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func);
1561
1562            // Callback for successful chunk uploads:
1563            // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func);
1564
1565            // Callback for failed (abort or error) chunk uploads:
1566            // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func);
1567
1568            // Callback for completed (success, abort or error) chunk upload requests:
1569            // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func);
1570
1571            // The plugin options are used as settings object for the ajax calls.
1572            // The following are jQuery ajax settings required for the file uploads:
1573            processData: false,
1574            contentType: false,
1575            cache: false
1576        },
1577
1578        // A list of options that require reinitializing event listeners and/or
1579        // special initialization code:
1580        _specialOptions: [
1581            'fileInput',
1582            'dropZone',
1583            'pasteZone',
1584            'multipart',
1585            'forceIframeTransport'
1586        ],
1587
1588        _blobSlice: $.support.blobSlice && function () {
1589            var slice = this.slice || this.webkitSlice || this.mozSlice;
1590            return slice.apply(this, arguments);
1591        },
1592
1593        _BitrateTimer: function () {
1594            this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime());
1595            this.loaded = 0;
1596            this.bitrate = 0;
1597            this.getBitrate = function (now, loaded, interval) {
1598                var timeDiff = now - this.timestamp;
1599                if (!this.bitrate || !interval || timeDiff > interval) {
1600                    this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8;
1601                    this.loaded = loaded;
1602                    this.timestamp = now;
1603                }
1604                return this.bitrate;
1605            };
1606        },
1607
1608        _isXHRUpload: function (options) {
1609            return !options.forceIframeTransport &&
1610                ((!options.multipart && $.support.xhrFileUpload) ||
1611                $.support.xhrFormDataFileUpload);
1612        },
1613
1614        _getFormData: function (options) {
1615            var formData;
1616            if ($.type(options.formData) === 'function') {
1617                return options.formData(options.form);
1618            }
1619            if ($.isArray(options.formData)) {
1620                return options.formData;
1621            }
1622            if ($.type(options.formData) === 'object') {
1623                formData = [];
1624                $.each(options.formData, function (name, value) {
1625                    formData.push({name: name, value: value});
1626                });
1627                return formData;
1628            }
1629            return [];
1630        },
1631
1632        _getTotal: function (files) {
1633            var total = 0;
1634            $.each(files, function (index, file) {
1635                total += file.size || 1;
1636            });
1637            return total;
1638        },
1639
1640        _initProgressObject: function (obj) {
1641            var progress = {
1642                loaded: 0,
1643                total: 0,
1644                bitrate: 0
1645            };
1646            if (obj._progress) {
1647                $.extend(obj._progress, progress);
1648            } else {
1649                obj._progress = progress;
1650            }
1651        },
1652
1653        _initResponseObject: function (obj) {
1654            var prop;
1655            if (obj._response) {
1656                for (prop in obj._response) {
1657                    if (obj._response.hasOwnProperty(prop)) {
1658                        delete obj._response[prop];
1659                    }
1660                }
1661            } else {
1662                obj._response = {};
1663            }
1664        },
1665
1666        _onProgress: function (e, data) {
1667            if (e.lengthComputable) {
1668                var now = ((Date.now) ? Date.now() : (new Date()).getTime()),
1669                    loaded;
1670                if (data._time && data.progressInterval &&
1671                        (now - data._time < data.progressInterval) &&
1672                        e.loaded !== e.total) {
1673                    return;
1674                }
1675                data._time = now;
1676                loaded = Math.floor(
1677                    e.loaded / e.total * (data.chunkSize || data._progress.total)
1678                ) + (data.uploadedBytes || 0);
1679                // Add the difference from the previously loaded state
1680                // to the global loaded counter:
1681                this._progress.loaded += (loaded - data._progress.loaded);
1682                this._progress.bitrate = this._bitrateTimer.getBitrate(
1683                    now,
1684                    this._progress.loaded,
1685                    data.bitrateInterval
1686                );
1687                data._progress.loaded = data.loaded = loaded;
1688                data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate(
1689                    now,
1690                    loaded,
1691                    data.bitrateInterval
1692                );
1693                // Trigger a custom progress event with a total data property set
1694                // to the file size(s) of the current upload and a loaded data
1695                // property calculated accordingly:
1696                this._trigger(
1697                    'progress',
1698                    $.Event('progress', {delegatedEvent: e}),
1699                    data
1700                );
1701                // Trigger a global progress event for all current file uploads,
1702                // including ajax calls queued for sequential file uploads:
1703                this._trigger(
1704                    'progressall',
1705                    $.Event('progressall', {delegatedEvent: e}),
1706                    this._progress
1707                );
1708            }
1709        },
1710
1711        _initProgressListener: function (options) {
1712            var that = this,
1713                xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();
1714            // Accesss to the native XHR object is required to add event listeners
1715            // for the upload progress event:
1716            if (xhr.upload) {
1717                $(xhr.upload).bind('progress', function (e) {
1718                    var oe = e.originalEvent;
1719                    // Make sure the progress event properties get copied over:
1720                    e.lengthComputable = oe.lengthComputable;
1721                    e.loaded = oe.loaded;
1722                    e.total = oe.total;
1723                    that._onProgress(e, options);
1724                });
1725                options.xhr = function () {
1726                    return xhr;
1727                };
1728            }
1729        },
1730
1731        _isInstanceOf: function (type, obj) {
1732            // Cross-frame instanceof check
1733            return Object.prototype.toString.call(obj) === '[object ' + type + ']';
1734        },
1735
1736        _initXHRData: function (options) {
1737            var that = this,
1738                formData,
1739                file = options.files[0],
1740                // Ignore non-multipart setting if not supported:
1741                multipart = options.multipart || !$.support.xhrFileUpload,
1742                paramName = $.type(options.paramName) === 'array' ?
1743                    options.paramName[0] : options.paramName;
1744            options.headers = $.extend({}, options.headers);
1745            if (options.contentRange) {
1746                options.headers['Content-Range'] = options.contentRange;
1747            }
1748            if (!multipart || options.blob || !this._isInstanceOf('File', file)) {
1749                options.headers['Content-Disposition'] = 'attachment; filename="' +
1750                    encodeURI(file.name) + '"';
1751            }
1752            if (!multipart) {
1753                options.contentType = file.type || 'application/octet-stream';
1754                options.data = options.blob || file;
1755            } else if ($.support.xhrFormDataFileUpload) {
1756                if (options.postMessage) {
1757                    // window.postMessage does not allow sending FormData
1758                    // objects, so we just add the File/Blob objects to
1759                    // the formData array and let the postMessage window
1760                    // create the FormData object out of this array:
1761                    formData = this._getFormData(options);
1762                    if (options.blob) {
1763                        formData.push({
1764                            name: paramName,
1765                            value: options.blob
1766                        });
1767                    } else {
1768                        $.each(options.files, function (index, file) {
1769                            formData.push({
1770                                name: ($.type(options.paramName) === 'array' &&
1771                                    options.paramName[index]) || paramName,
1772                                value: file
1773                            });
1774                        });
1775                    }
1776                } else {
1777                    if (that._isInstanceOf('FormData', options.formData)) {
1778                        formData = options.formData;
1779                    } else {
1780                        formData = new FormData();
1781                        $.each(this._getFormData(options), function (index, field) {
1782                            formData.append(field.name, field.value);
1783                        });
1784                    }
1785                    if (options.blob) {
1786                        formData.append(paramName, options.blob, file.name);
1787                    } else {
1788                        $.each(options.files, function (index, file) {
1789                            // This check allows the tests to run with
1790                            // dummy objects:
1791                            if (that._isInstanceOf('File', file) ||
1792                                    that._isInstanceOf('Blob', file)) {
1793                                formData.append(
1794                                    ($.type(options.paramName) === 'array' &&
1795                                        options.paramName[index]) || paramName,
1796                                    file,
1797                                    file.uploadName || file.name
1798                                );
1799                            }
1800                        });
1801                    }
1802                }
1803                options.data = formData;
1804            }
1805            // Blob reference is not needed anymore, free memory:
1806            options.blob = null;
1807        },
1808
1809        _initIframeSettings: function (options) {
1810            var targetHost = $('<a></a>').prop('href', options.url).prop('host');
1811            // Setting the dataType to iframe enables the iframe transport:
1812            options.dataType = 'iframe ' + (options.dataType || '');
1813            // The iframe transport accepts a serialized array as form data:
1814            options.formData = this._getFormData(options);
1815            // Add redirect url to form data on cross-domain uploads:
1816            if (options.redirect && targetHost && targetHost !== location.host) {
1817                options.formData.push({
1818                    name: options.redirectParamName || 'redirect',
1819                    value: options.redirect
1820                });
1821            }
1822        },
1823
1824        _initDataSettings: function (options) {
1825            if (this._isXHRUpload(options)) {
1826                if (!this._chunkedUpload(options, true)) {
1827                    if (!options.data) {
1828                        this._initXHRData(options);
1829                    }
1830                    this._initProgressListener(options);
1831                }
1832                if (options.postMessage) {
1833                    // Setting the dataType to postmessage enables the
1834                    // postMessage transport:
1835                    options.dataType = 'postmessage ' + (options.dataType || '');
1836                }
1837            } else {
1838                this._initIframeSettings(options);
1839            }
1840        },
1841
1842        _getParamName: function (options) {
1843            var fileInput = $(options.fileInput),
1844                paramName = options.paramName;
1845            if (!paramName) {
1846                paramName = [];
1847                fileInput.each(function () {
1848                    var input = $(this),
1849                        name = input.prop('name') || 'files[]',
1850                        i = (input.prop('files') || [1]).length;
1851                    while (i) {
1852                        paramName.push(name);
1853                        i -= 1;
1854                    }
1855                });
1856                if (!paramName.length) {
1857                    paramName = [fileInput.prop('name') || 'files[]'];
1858                }
1859            } else if (!$.isArray(paramName)) {
1860                paramName = [paramName];
1861            }
1862            return paramName;
1863        },
1864
1865        _initFormSettings: function (options) {
1866            // Retrieve missing options from the input field and the
1867            // associated form, if available:
1868            if (!options.form || !options.form.length) {
1869                options.form = $(options.fileInput.prop('form'));
1870                // If the given file input doesn't have an associated form,
1871                // use the default widget file input's form:
1872                if (!options.form.length) {
1873                    options.form = $(this.options.fileInput.prop('form'));
1874                }
1875            }
1876            options.paramName = this._getParamName(options);
1877            if (!options.url) {
1878                options.url = options.form.prop('action') || location.href;
1879            }
1880            // The HTTP request method must be "POST" or "PUT":
1881            options.type = (options.type ||
1882                ($.type(options.form.prop('method')) === 'string' &&
1883                    options.form.prop('method')) || ''
1884                ).toUpperCase();
1885            if (options.type !== 'POST' && options.type !== 'PUT' &&
1886                    options.type !== 'PATCH') {
1887                options.type = 'POST';
1888            }
1889            if (!options.formAcceptCharset) {
1890                options.formAcceptCharset = options.form.attr('accept-charset');
1891            }
1892        },
1893
1894        _getAJAXSettings: function (data) {
1895            var options = $.extend({}, this.options, data);
1896            this._initFormSettings(options);
1897            this._initDataSettings(options);
1898            return options;
1899        },
1900
1901        // jQuery 1.6 doesn't provide .state(),
1902        // while jQuery 1.8+ removed .isRejected() and .isResolved():
1903        _getDeferredState: function (deferred) {
1904            if (deferred.state) {
1905                return deferred.state();
1906            }
1907            if (deferred.isResolved()) {
1908                return 'resolved';
1909            }
1910            if (deferred.isRejected()) {
1911                return 'rejected';
1912            }
1913            return 'pending';
1914        },
1915
1916        // Maps jqXHR callbacks to the equivalent
1917        // methods of the given Promise object:
1918        _enhancePromise: function (promise) {
1919            promise.success = promise.done;
1920            promise.error = promise.fail;
1921            promise.complete = promise.always;
1922            return promise;
1923        },
1924
1925        // Creates and returns a Promise object enhanced with
1926        // the jqXHR methods abort, success, error and complete:
1927        _getXHRPromise: function (resolveOrReject, context, args
1927) {
1928            var dfd = $.Deferred(),
1929                promise = dfd.promise();
1930            context = context || this.options.context || promise;
1931            if (resolveOrReject === true) {
1932                dfd.resolveWith(context, args);
1933            } else if (resolveOrReject === false) {
1934                dfd.rejectWith(context, args);
1935            }
1936            promise.abort = dfd.promise;
1937            return this._enhancePromise(promise);
1938        },
1939
1940        // Adds convenience methods to the data callback argument:
1941        _addConvenienceMethods: function (e, data) {
1942            var that = this,
1943                getPromise = function (args) {
1944                    return $.Deferred().resolveWith(that, args).promise();
1945                };
1946            data.process = function (resolveFunc, rejectFunc) {
1947                if (resolveFunc || rejectFunc) {
1948                    data._processQueue = this._processQueue =
1949                        (this._processQueue || getPromise([this])).pipe(
1950                            function () {
1951                                if (data.errorThrown) {
1952                                    return $.Deferred()
1953                                        .rejectWith(that, [data]).promise();
1954                                }
1955                                return getPromise(arguments);
1956                            }
1957                        ).pipe(resolveFunc, rejectFunc);
1958                }
1959                return this._processQueue || getPromise([this]);
1960            };
1961            data.submit = function () {
1962                if (this.state() !== 'pending') {
1963                    data.jqXHR = this.jqXHR =
1964                        (that._trigger(
1965                            'submit',
1966                            $.Event('submit', {delegatedEvent: e}),
1967                            this
1968                        ) !== false) && that._onSend(e, this);
1969                }
1970                return this.jqXHR || that._getXHRPromise();
1971            };
1972            data.abort = function () {
1973                if (this.jqXHR) {
1974                    return this.jqXHR.abort();
1975                }
1976                this.errorThrown = 'abort';
1977                that._trigger('fail', null, this);
1978                return that._getXHRPromise(false);
1979            };
1980            data.state = function () {
1981                if (this.jqXHR) {
1982                    return that._getDeferredState(this.jqXHR);
1983                }
1984                if (this._processQueue) {
1985                    return that._getDeferredState(this._processQueue);
1986                }
1987            };
1988            data.processing = function () {
1989                return !this.jqXHR && this._processQueue && that
1990                    ._getDeferredState(this._processQueue) === 'pending';
1991            };
1992            data.progress = function () {
1993                return this._progress;
1994            };
1995            data.response = function () {
1996                return this._response;
1997            };
1998        },
1999
2000        // Parses the Range header from the server response
2001        // and returns the uploaded bytes:
2002        _getUploadedBytes: function (jqXHR) {
2003            var range = jqXHR.getResponseHeader('Range'),
2004                parts = range && range.split('-'),
2005                upperBytesPos = parts && parts.length > 1 &&
2006                    parseInt(parts[1], 10);
2007            return upperBytesPos && upperBytesPos + 1;
2008        },
2009
2010        // Uploads a file in multiple, sequential requests
2011        // by splitting the file up in multiple blob chunks.
2012        // If the second parameter is true, only tests if the file
2013        // should be uploaded in chunks, but does not invoke any
2014        // upload requests:
2015        _chunkedUpload: function (options, testOnly) {
2016            options.uploadedBytes = options.uploadedBytes || 0;
2017            var that = this,
2018                file = options.files[0],
2019                fs = file.size,
2020                ub = options.uploadedBytes,
2021                mcs = options.maxChunkSize || fs,
2022                slice = this._blobSlice,
2023                dfd = $.Deferred(),
2024                promise = dfd.promise(),
2025                jqXHR,
2026                upload;
2027            if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) ||
2028                    options.data) {
2029                return false;
2030            }
2031            if (testOnly) {
2032                return true;
2033            }
2034            if (ub >= fs) {
2035                file.error = options.i18n('uploadedBytes');
2036                return this._getXHRPromise(
2037                    false,
2038                    options.context,
2039                    [null, 'error', file.error]
2040                );
2041            }
2042            // The chunk upload method:
2043            upload = function () {
2044                // Clone the options object for each chunk upload:
2045                var o = $.extend({}, options),
2046                    currentLoaded = o._progress.loaded;
2047                o.blob = slice.call(
2048                    file,
2049                    ub,
2050                    ub + mcs,
2051                    file.type
2052                );
2053                // Store the current chunk size, as the blob itself
2054                // will be dereferenced after data processing:
2055                o.chunkSize = o.blob.size;
2056                // Expose the chunk bytes position range:
2057                o.contentRange = 'bytes ' + ub + '-' +
2058                    (ub + o.chunkSize - 1) + '/' + fs;
2059                // Process the upload data (the blob and potential form data):
2060                that._initXHRData(o);
2061                // Add progress listeners for this chunk upload:
2062                that._initProgressListener(o);
2063                jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) ||
2064                        that._getXHRPromise(false, o.context))
2065                    .done(function (result, textStatus, jqXHR) {
2066                        ub = that._getUploadedBytes(jqXHR) ||
2067                            (ub + o.chunkSize);
2068                        // Create a progress event if no final progress event
2069                        // with loaded equaling total has been triggered
2070                        // for this chunk:
2071                        if (currentLoaded + o.chunkSize - o._progress.loaded) {
2072                            that._onProgress($.Event('progress', {
2073                                lengthComputable: true,
2074                                loaded: ub - o.uploadedBytes,
2075                                total: ub - o.uploadedBytes
2076                            }), o);
2077                        }
2078                        options.uploadedBytes = o.uploadedBytes = ub;
2079                        o.result = result;
2080                        o.textStatus = textStatus;
2081                        o.jqXHR = jqXHR;
2082                        that._trigger('chunkdone', null, o);
2083                        that._trigger('chunkalways', null, o);
2084                        if (ub < fs) {
2085                            // File upload not yet complete,
2086                            // continue with the next chunk:
2087                            upload();
2088                        } else {
2089                            dfd.resolveWith(
2090                                o.context,
2091                                [result, textStatus, jqXHR]
2092                            );
2093                        }
2094                    })
2095                    .fail(function (jqXHR, textStatus, errorThrown) {
2096                        o.jqXHR = jqXHR;
2097                        o.textStatus = textStatus;
2098                        o.errorThrown = errorThrown;
2099                        that._trigger('chunkfail', null, o);
2100                        that._trigger('chunkalways', null, o);
2101                        dfd.rejectWith(
2102                            o.context,
2103                            [jqXHR, textStatus, errorThrown]
2104                        );
2105                    });
2106            };
2107            this._enhancePromise(promise);
2108            promise.abort = function () {
2109                return jqXHR.abort();
2110            };
2111            upload();
2112            return promise;
2113        },
2114
2115        _beforeSend: function (e, data) {
2116            if (this._active === 0) {
2117                // the start callback is triggered when an upload starts
2118                // and no other uploads are currently running,
2119                // equivalent to the global ajaxStart event:
2120                this._trigger('start');
2121                // Set timer for global bitrate progress calculation:
2122                this._bitrateTimer = new this._BitrateTimer();
2123                // Reset the global progress values:
2124                this._progress.loaded = this._progress.total = 0;
2125                this._progress.bitrate = 0;
2126            }
2127            // Make sure the container objects for the .response() and
2128            // .progress() methods on the data object are available
2129            // and reset to their initial state:
2130            this._initResponseObject(data);
2131            this._initProgressObject(data);
2132            data._progress.loaded = data.loaded = data.uploadedBytes || 0;
2133            data._progress.total = data.total = this._getTotal(data.files) || 1;
2134            data._progress.bitrate = data.bitrate = 0;
2135            this._active += 1;
2136            // Initialize the global progress values:
2137            this._progress.loaded += data.loaded;
2138            this._progress.total += data.total;
2139        },
2140
2141        _onDone: function (result, textStatus, jqXHR, options) {
2142            var total = options._progress.total,
2143                response = options._response;
2144            if (options._progress.loaded < total) {
2145                // Create a progress event if no final progress event
2146                // with loaded equaling total has been triggered:
2147                this._onProgress($.Event('progress', {
2148                    lengthComputable: true,
2149                    loaded: total,
2150                    total: total
2151                }), options);
2152            }
2153            response.result = options.result = result;
2154            response.textStatus = options.textStatus = textStatus;
2155            response.jqXHR = options.jqXHR = jqXHR;
2156            this._trigger('done', null, options);
2157        },
2158
2159        _onFail: function (jqXHR, textStatus, errorThrown, options) {
2160            var response = options._response;
2161            if (options.recalculateProgress) {
2162                // Remove the failed (error or abort) file upload from
2163                // the global progress calculation:
2164                this._progress.loaded -= options._progress.loaded;
2165                this._progress.total -= options._progress.total;
2166            }
2167            response.jqXHR = options.jqXHR = jqXHR;
2168            response.textStatus = options.textStatus = textStatus;
2169            response.errorThrown = options.errorThrown = errorThrown;
2170            this._trigger('fail', null, options);
2171        },
2172
2173        _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {
2174            // jqXHRorResult, textStatus and jqXHRorError are added to the
2175            // options object via done and fail callbacks
2176            this._trigger('always', null, options);
2177        },
2178
2179        _onSend: function (e, data) {
2180            if (!data.submit) {
2181                this._addConvenienceMethods(e, data);
2182            }
2183            var that = this,
2184                jqXHR,
2185                aborted,
2186                slot,
2187                pipe,
2188                options = that._getAJAXSettings(data),
2189                send = function () {
2190                    that._sending += 1;
2191                    // Set timer for bitrate progress calculation:
2192                    options._bitrateTimer = new that._BitrateTimer();
2193                    jqXHR = jqXHR || (
2194                        ((aborted || that._trigger(
2195                            'send',
2196                            $.Event('send', {delegatedEvent: e}),
2197                            options
2198                        ) === false) &&
2199                        that._getXHRPromise(false, options.context, aborted)) ||
2200                        that._chunkedUpload(options) || $.ajax(options)
2201                    ).done(function (result, textStatus, jqXHR) {
2202                        that._onDone(result, textStatus, jqXHR, options);
2203                    }).fail(function (jqXHR, textStatus, errorThrown) {
2204                        that._onFail(jqXHR, textStatus, errorThrown, options);
2205                    }).always(function (jqXHRorResult, textStatus, jqXHRorError) {
2206                        that._onAlways(
2207                            jqXHRorResult,
2208                            textStatus,
2209                            jqXHRorError,
2210                            options
2211                        );
2212                        that._sending -= 1;
2213                        that._active -= 1;
2214                        if (options.limitConcurrentUploads &&
2215                                options.limitConcurrentUploads > that._sending) {
2216                            // Start the next queued upload,
2217                            // that has not been aborted:
2218                            var nextSlot = that._slots.shift();
2219                            while (nextSlot) {
2220                                if (that._getDeferredState(nextSlot) === 'pending') {
2221                                    nextSlot.resolve();
2222                                    break;
2223                                }
2224                                nextSlot = that._slots.shift();
2225                            }
2226                        }
2227                        if (that._active === 0) {
2228                            // The stop callback is triggered when all uploads have
2229                            // been completed, equivalent to the global ajaxStop event:
2230                            that._trigger('stop');
2231                        }
2232                    });
2233                    return jqXHR;
2234                };
2235            this._beforeSend(e, options);
2236            if (this.options.sequentialUploads ||
2237                    (this.options.limitConcurrentUploads &&
2238                    this.options.limitConcurrentUploads <= this._sending)) {
2239                if (this.options.limitConcurrentUploads > 1) {
2240                    slot = $.Deferred();
2241                    this._slots.push(slot);
2242                    pipe = slot.pipe(send);
2243                } else {
2244                    this._sequence = this._sequence.pipe(send, send);
2245                    pipe = this._sequence;
2246                }
2247                // Return the piped Promise object, enhanced with an abort method,
2248                // which is delegated to the jqXHR object of the current upload,
2249                // and jqXHR callbacks mapped to the equivalent Promise methods:
2250                pipe.abort = function () {
2251                    aborted = [undefined, 'abort', 'abort'];
2252                    if (!jqXHR) {
2253                        if (slot) {
2254                            slot.rejectWith(options.context, aborted);
2255                        }
2256                        return send();
2257                    }
2258                    return jqXHR.abort();
2259                };
2260                return this._enhancePromise(pipe);
2261            }
2262            return send();
2263        },
2264
2265        _onAdd: function (e, data) {
2266            var that = this,
2267                result = true,
2268                options = $.extend({}, this.options, data),
2269                files = data.files,
2270                filesLength = files.length,
2271                limit = options.limitMultiFileUploads,
2272                limitSize = options.limitMultiFileUploadSize,
2273                overhead = options.limitMultiFileUploadSizeOverhead,
2274                batchSize = 0,
2275                paramName = this._getParamName(options),
2276                paramNameSet,
2277                paramNameSlice,
2278                fileSet,
2279                i,
2280                j = 0;
2281            if (limitSize && (!filesLength || files[0].size === undefined)) {
2282                limitSize = undefined;
2283            }
2284            if (!(options.singleFileUploads || limit || limitSize) ||
2285                    !this._isXHRUpload(options)) {
2286                fileSet = [files];
2287                paramNameSet = [paramName];
2288            } else if (!(options.singleFileUploads || limitSize) && limit) {
2289                fileSet = [];
2290                paramNameSet = [];
2291                for (i = 0; i < filesLength; i += limit) {
2292                    fileSet.push(files.slice(i, i + limit));
2293                    paramNameSlice = paramName.slice(i, i + limit);
2294                    if (!paramNameSlice.length) {
2295                        paramNameSlice = paramName;
2296                    }
2297                    paramNameSet.push(paramNameSlice);
2298                }
2299            } else if (!options.singleFileUploads && limitSize) {
2300                fileSet = [];
2301                paramNameSet = [];
2302                for (i = 0; i < filesLength; i = i + 1) {
2303                    batchSize += files[i].size + overhead;
2304                    if (i + 1 === filesLength ||
2305                            ((batchSize + files[i + 1].size + overhead) > limitSize) ||
2306                            (limit && i + 1 - j >= limit)) {
2307                        fileSet.push(files.slice(j, i + 1));
2308                        paramNameSlice = paramName.slice(j, i + 1);
2309                        if (!paramNameSlice.length) {
2310                            paramNameSlice = paramName;
2311                        }
2312                        paramNameSet.push(paramNameSlice);
2313                        j = i + 1;
2314                        batchSize = 0;
2315                    }
2316                }
2317            } else {
2318                paramNameSet = paramName;
2319            }
2320            data.originalFiles = files;
2321            $.each(fileSet || files, function (index, element) {
2322                var newData = $.extend({}, data);
2323                newData.files = fileSet ? element : [element];
2324                newData.paramName = paramNameSet[index];
2325                that._initResponseObject(newData);
2326                that._initProgressObject(newData);
2327                that._addConvenienceMethods(e, newData);
2328                result = that._trigger(
2329                    'add',
2330                    $.Event('add', {delegatedEvent: e}),
2331                    newData
2332                );
2333                return result;
2334            });
2335            return result;
2336        },
2337
2338        _replaceFileInput: function (data) {
2339            var input = data.fileInput,
2340                inputClone = input.clone(true);
2341            // Add a reference for the new cloned file input to the data argument:
2342            data.fileInputClone = inputClone;
2343            $('<form></form>').append(inputClone)[0].reset();
2344            // Detaching allows to insert the fileInput on another form
2345            // without loosing the file input value:
2346            input.after(inputClone).detach();
2347            // Avoid memory leaks with the detached file input:
2348            $.cleanData(input.unbind('remove'));
2349            // Replace the original file input element in the fileInput
2350            // elements set with the clone, which has been copied including
2351            // event handlers:
2352            this.options.fileInput = this.options.fileInput.map(function (i, el) {
2353                if (el === input[0]) {
2354                    return inputClone[0];
2355                }
2356                return el;
2357            });
2358            // If the widget has been initialized on the file input itself,
2359            // override this.element with the file input clone:
2360            if (input[0] === this.element[0]) {
2361                this.element = inputClone;
2362            }
2363        },
2364
2365        _handleFileTreeEntry: function (entry, path) {
2366            var that = this,
2367                dfd = $.Deferred(),
2368                errorHandler = function (e) {
2369                    if (e && !e.entry) {
2370                        e.entry = entry;
2371                    }
2372                    // Since $.when returns immediately if one
2373                    // Deferred is rejected, we use resolve instead.
2374                    // This allows valid files and invalid items
2375                    // to be returned together in one set:
2376                    dfd.resolve([e]);
2377                },
2378                successHandler = function (entries) {
2379                    that._handleFileTreeEntries(
2380                        entries,
2381                        path + entry.name + '/'
2382                    ).done(function (files) {
2383                        dfd.resolve(files);
2384                    }).fail(errorHandler);
2385                },
2386                readEntries = function () {
2387                    dirReader.readEntries(function (results) {
2388                        if (!results.length) {
2389                            successHandler(entries);
2390                        } else {
2391                            entries = entries.concat(results);
2392                            readEntries();
2393                        }
2394                    }, errorHandler);
2395                },
2396                dirReader, entries = [];
2397            path = path || '';
2398            if (entry.isFile) {
2399                if (entry._file) {
2400                    // Workaround for Chrome bug #149735
2401                    entry._file.relativePath = path;
2402                    dfd.resolve(entry._file);
2403                } else {
2404                    entry.file(function (file) {
2405                        file.relativePath = path;
2406                        dfd.resolve(file);
2407                    }, errorHandler);
2408                }
2409            } else if (entry.isDirectory) {
2410                dirReader = entry.createReader();
2411                readEntries();
2412            } else {
2413                // Return an empy list for file system items
2414                // other than files or directories:
2415                dfd.resolve([]);
2416            }
2417            return dfd.promise();
2418        },
2419
2420        _handleFileTreeEntries: function (entries, path) {
2421            var that = this;
2422            return $.when.apply(
2423                $,
2424                $.map(entries, function (entry) {
2425                    return that._handleFileTreeEntry(entry, path);
2426                })
2427            ).pipe(function () {
2428                return Array.prototype.concat.apply(
2429                    [],
2430                    arguments
2431                );
2432            });
2433        },
2434
2435        _getDroppedFiles: function (dataTransfer) {
2436            dataTransfer = dataTransfer || {};
2437            var items = dataTransfer.items;
2438            if (items && items.length && (items[0].webkitGetAsEntry ||
2439                    items[0].getAsEntry)) {
2440                return this._handleFileTreeEntries(
2441                    $.map(items, function (item) {
2442                        var entry;
2443                        if (item.webkitGetAsEntry) {
2444                            entry = item.webkitGetAsEntry();
2445                            if (entry) {
2446                                // Workaround for Chrome bug #149735:
2447                                entry._file = item.getAsFile();
2448                            }
2449                            return entry;
2450                        }
2451                        return item.getAsEntry();
2452                    })
2453                );
2454            }
2455            return $.Deferred().resolve(
2456                $.makeArray(dataTransfer.files)
2457            ).promise();
2458        },
2459
2460        _getSingleFileInputFiles: function (fileInput) {
2461            fileInput = $(fileInput);
2462            var entries = fileInput.prop('webkitEntries') ||
2463                    fileInput.prop('entries'),
2464                files,
2465                value;
2466            if (entries && entries.length) {
2467                return this._handleFileTreeEntries(entries);
2468            }
2469            files = $.makeArray(fileInput.prop('files'));
2470            if (!files.length) {
2471                value = fileInput.prop('value');
2472                if (!value) {
2473                    return $.Deferred().resolve([]).promise();
2474                }
2475                // If the files property is not available, the browser does not
2476                // support the File API and we add a pseudo File object with
2477                // the input value as name with path information removed:
2478                files = [{name: value.replace(/^.*\\/, '')}];
2479            } else if (files[0].name === undefined && files[0].fileName) {
2480                // File normalization for Safari 4 and Firefox 3:
2481                $.each(files, function (index, file) {
2482                    file.name = file.fileName;
2483                    file.size = file.fileSize;
2484                });
2485            }
2486            return $.Deferred().resolve(files).promise();
2487        },
2488
2489        _getFileInputFiles: function (fileInput) {
2490            if (!(fileInput instanceof $) || fileInput.length === 1) {
2491                return this._getSingleFileInputFiles(fileInput);
2492            }
2493            return $.when.apply(
2494                $,
2495                $.map(fileInput, this._getSingleFileInputFiles)
2496            ).pipe(function () {
2497                return Array.prototype.concat.apply(
2498                    [],
2499                    arguments
2500                );
2501            });
2502        },
2503
2504        _onChange: function (e) {
2505            var that = this,
2506                data = {
2507                    fileInput: $(e.target),
2508                    form: $(e.target.form)
2509                };
2510            this._getFileInputFiles(data.fileInput).always(function (files) {
2511                data.files = files;
2512                if (that.options.replaceFileInput) {
2513                    that._replaceFileInput(data);
2514                }
2515                if (that._trigger(
2516                        'change',
2517                        $.Event('change', {delegatedEvent: e}),
2518                        data
2519                    ) !== false) {
2520                    that._onAdd(e, data);
2521                }
2522            });
2523        },
2524
2525        _onPaste: function (e) {
2526            var items = e.originalEvent && e.originalEvent.clipboardData &&
2527                    e.originalEvent.clipboardData.items,
2528                data = {files: []};
2529            if (items && items.length) {
2530                $.each(items, function (index, item) {
2531                    var file = item.getAsFile && item.getAsFile();
2532                    if (file) {
2533                        data.files.push(file);
2534                    }
2535                });
2536                if (this._trigger(
2537                        'paste',
2538                        $.Event('paste', {delegatedEvent: e}),
2539                        data
2540                    ) !== false) {
2541                    this._onAdd(e, data);
2542                }
2543            }
2544        },
2545
2546        _onDrop: function (e) {
2547            e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
2548            var that = this,
2549                dataTransfer = e.dataTransfer,
2550                data = {};
2551            if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {
2552                e.preventDefault();
2553                this._getDroppedFiles(dataTransfer).always(function (files) {
2554                    data.files = files;
2555                    if (that._trigger(
2556                            'drop',
2557                            $.Event('drop', {delegatedEvent: e}),
2558                            data
2559                        ) !== false) {
2560                        that._onAdd(e, data);
2561                    }
2562                });
2563            }
2564        },
2565
2566        _onDragOver: getDragHandler('dragover'),
2567
2568        _onDragEnter: getDragHandler('dragenter'),
2569
2570        _onDragLeave: getDragHandler('dragleave'),
2571
2572        _initEventHandlers: function () {
2573            if (this._isXHRUpload(this.options)) {
2574                this._on(this.options.dropZone, {
2575                    dragover: this._onDragOver,
2576                    drop: this._onDrop,
2577                    // event.preventDefault() on dragenter is required for IE10+:
2578                    dragenter: this._onDragEnter,
2579                    // dragleave is not required, but added for c
2579ompleteness:
2580                    dragleave: this._onDragLeave
2581                });
2582                this._on(this.options.pasteZone, {
2583                    paste: this._onPaste
2584                });
2585            }
2586            if ($.support.fileInput) {
2587                this._on(this.options.fileInput, {
2588                    change: this._onChange
2589                });
2590            }
2591        },
2592
2593        _destroyEventHandlers: function () {
2594            this._off(this.options.dropZone, 'dragenter dragleave dragover drop');
2595            this._off(this.options.pasteZone, 'paste');
2596            this._off(this.options.fileInput, 'change');
2597        },
2598
2599        _setOption: function (key, value) {
2600            var reinit = $.inArray(key, this._specialOptions) !== -1;
2601            if (reinit) {
2602                this._destroyEventHandlers();
2603            }
2604            this._super(key, value);
2605            if (reinit) {
2606                this._initSpecialOptions();
2607                this._initEventHandlers();
2608            }
2609        },
2610
2611        _initSpecialOptions: function () {
2612            var options = this.options;
2613            if (options.fileInput === undefined) {
2614                options.fileInput = this.element.is('input[type="file"]') ?
2615                        this.element : this.element.find('input[type="file"]');
2616            } else if (!(options.fileInput instanceof $)) {
2617                options.fileInput = $(options.fileInput);
2618            }
2619            if (!(options.dropZone instanceof $)) {
2620                options.dropZone = $(options.dropZone);
2621            }
2622            if (!(options.pasteZone instanceof $)) {
2623                options.pasteZone = $(options.pasteZone);
2624            }
2625        },
2626
2627        _getRegExp: function (str) {
2628            var parts = str.split('/'),
2629                modifiers = parts.pop();
2630            parts.shift();
2631            return new RegExp(parts.join('/'), modifiers);
2632        },
2633
2634        _isRegExpOption: function (key, value) {
2635            return key !== 'url' && $.type(value) === 'string' &&
2636                /^\/.*\/[igm]{0,3}$/.test(value);
2637        },
2638
2639        _initDataAttributes: function () {
2640            var that = this,
2641                options = this.options,
2642                data = this.element.data();
2643            // Initialize options set via HTML5 data-attributes:
2644            $.each(
2645                this.element[0].attributes,
2646                function (index, attr) {
2647                    var key = attr.name.toLowerCase(),
2648                        value;
2649                    if (/^data-/.test(key)) {
2650                        // Convert hyphen-ated key to camelCase:
2651                        key = key.slice(5).replace(/-[a-z]/g, function (str) {
2652                            return str.charAt(1).toUpperCase();
2653                        });
2654                        value = data[key];
2655                        if (that._isRegExpOption(key, value)) {
2656                            value = that._getRegExp(value);
2657                        }
2658                        options[key] = value;
2659                    }
2660                }
2661            );
2662        },
2663
2664        _create: function () {
2665            this._initDataAttributes();
2666            this._initSpecialOptions();
2667            this._slots = [];
2668            this._sequence = this._getXHRPromise(true);
2669            this._sending = this._active = 0;
2670            this._initProgressObject(this);
2671            this._initEventHandlers();
2672        },
2673
2674        // This method is exposed to the widget API and allows to query
2675        // the number of active uploads:
2676        active: function () {
2677            return this._active;
2678        },
2679
2680        // This method is exposed to the widget API and allows to query
2681        // the widget upload progress.
2682        // It returns an object with loaded, total and bitrate properties
2683        // for the running uploads:
2684        progress: function () {
2685            return this._progress;
2686        },
2687
2688        // This method is exposed to the widget API and allows adding files
2689        // using the fileupload API. The data parameter accepts an object which
2690        // must have a files property and can contain additional options:
2691        // .fileupload('add', {files: filesList});
2692        add: function (data) {
2693            var that = this;
2694            if (!data || this.options.disabled) {
2695                return;
2696            }
2697            if (data.fileInput && !data.files) {
2698                this._getFileInputFiles(data.fileInput).always(function (files) {
2699                    data.files = files;
2700                    that._onAdd(null, data);
2701                });
2702            } else {
2703                data.files = $.makeArray(data.files);
2704                this._onAdd(null, data);
2705            }
2706        },
2707
2708        // This method is exposed to the widget API and allows sending files
2709        // using the fileupload API. The data parameter accepts an object which
2710        // must have a files or fileInput property and can contain additional options:
2711        // .fileupload('send', {files: filesList});
2712        // The method returns a Promise object for the file upload call.
2713        send: function (data) {
2714            if (data && !this.options.disabled) {
2715                if (data.fileInput && !data.files) {
2716                    var that = this,
2717                        dfd = $.Deferred(),
2718                        promise = dfd.promise(),
2719                        jqXHR,
2720                        aborted;
2721                    promise.abort = function () {
2722                        aborted = true;
2723                        if (jqXHR) {
2724                            return jqXHR.abort();
2725                        }
2726                        dfd.reject(null, 'abort', 'abort');
2727                        return promise;
2728                    };
2729                    this._getFileInputFiles(data.fileInput).always(
2730                        function (files) {
2731                            if (aborted) {
2732                                return;
2733                            }
2734                            if (!files.length) {
2735                                dfd.reject();
2736                                return;
2737                            }
2738                            data.files = files;
2739                            jqXHR = that._onSend(null, data);
2740                            jqXHR.then(
2741                                function (result, textStatus, jqXHR) {
2742                                    dfd.resolve(result, textStatus, jqXHR);
2743                                },
2744                                function (jqXHR, textStatus, errorThrown) {
2745                                    dfd.reject(jqXHR, textStatus, errorThrown);
2746                                }
2747                            );
2748                        }
2749                    );
2750                    return this._enhancePromise(promise);
2751                }
2752                data.files = $.makeArray(data.files);
2753                if (data.files.length) {
2754                    return this._onSend(null, data);
2755                }
2756            }
2757            return this._getXHRPromise(false, data && data.context);
2758        }
2759
2760    });
2761
2762}));
2763
2764/*
2765 * jQuery Form Plugin; v20130731
2766 * http://jquery.malsup.com/form/
2767 * Copyright (c) 2013 M. Alsup; Dual licensed: MIT/GPL
2768 * https://github.com/malsup/form#copyright-and-license
2769 */
2770;(function(e){"use strict";function t(t){var r=t.data;t.isDefaultPrevented()||(t.preventDefault(),e(this).ajaxSubmit(r))}function r(t){var r=t.target,a=e(r);if(!a.is("[type=submit],[type=image]")){var n=a.closest("[type=submit]");if(0===n.length)return;r=n[0]}var i=this;if(i.clk=r,"image"==r.type)if(void 0!==t.offsetX)i.clk_x=t.offsetX,i.clk_y=t.offsetY;else if("function"==typeof e.fn.offset){var o=a.offset();i.clk_x=t.pageX-o.left,i.clk_y=t.pageY-o.top}else i.clk_x=t.pageX-r.offsetLeft,i.clk_y=t.pageY-r.offsetTop;setTimeout(function(){i.clk=i.clk_x=i.clk_y=null},100)}function a(){if(e.fn.ajaxSubmit.debug){var t="[jquery.form] "+Array.prototype.join.call(arguments,"");window.console&&window.console.log?window.console.log(t):window.opera&&window.opera.postError&&window.opera.postError(t)}}var n={};n.fileapi=void 0!==e("<input type='file'/>").get(0).files,n.formdata=void 0!==window.FormData;var i=!!e.fn.prop;e.fn.attr2=function(){if(!i)return this.attr.apply(this,arguments);var e=this.prop.apply(this,arguments);return e&&e.jquery||"string"==typeof e?e:this.attr.apply(this,arguments)},e.fn.ajaxSubmit=function(t){function r(r){var a,n,i=e.param(r,t.traditional).split("&"),o=i.length,s=[];for(a=0;o>a;a++)i[a]=i[a].replace(/\+/g," "),n=i[a].split("="),s.push([decodeURIComponent(n[0]),decodeURIComponent(n[1])]);return s}function o(a){for(var n=new FormData,i=0;a.length>i;i++)n.append(a[i].name,a[i].value);if(t.extraData){var o=r(t.extraData);for(i=0;o.length>i;i++)o[i]&&n.append(o[i][0],o[i][1])}t.data=null;var s=e.extend(!0,{},e.ajaxSettings,t,{contentType:!1,processData:!1,cache:!1,type:u||"POST"});t.uploadProgress&&(s.xhr=function(){var r=e.ajaxSettings.xhr();return r.upload&&r.upload.addEventListener("progress",function(e){var r=0,a=e.loaded||e.position,n=e.total;e.lengthComputable&&(r=Math.ceil(100*(a/n))),t.uploadProgress(e,a,n,r)},!1),r}),s.data=null;var l=s.beforeSend;return s.beforeSend=function(e,t){t.data=n,l&&l.call(this,e,t)},e.ajax(s)}function s(r){function n(e){var t=null;try{e.contentWindow&&(t=e.contentWindow.document)}catch(r){a("cannot get iframe.contentWindow document: "+r)}if(t)return t;try{t=e.contentDocument?e.contentDocument:e.document}catch(r){a("cannot get iframe.contentDocument: "+r),t=e.document}return t}function o(){function t(){try{var e=n(g).readyState;a("state = "+e),e&&"uninitialized"==e.toLowerCase()&&setTimeout(t,50)}catch(r){a("Server abort: ",r," (",r.name,")"),s(D),j&&clearTimeout(j),j=void 0}}var r=f.attr2("target"),i=f.attr2("action");w.setAttribute("target",d),u||w.setAttribute("method","POST"),i!=m.url&&w.setAttribute("action",m.url),m.skipEncodingOverride||u&&!/post/i.test(u)||f.attr({encoding:"multipart/form-data",enctype:"multipart/form-data"}),m.timeout&&(j=setTimeout(function(){T=!0,s(k)},m.timeout));var o=[];try{if(m.extraData)for(var l in m.extraData)m.extraData.hasOwnProperty(l)&&(e.isPlainObject(m.extraData[l])&&m.extraData[l].hasOwnProperty("name")&&m.extraData[l].hasOwnProperty("value")?o.push(e('<input type="hidden" name="'+m.extraData[l].name+'">').val(m.extraData[l].value).appendTo(w)[0]):o.push(e('<input type="hidden" name="'+l+'">').val(m.extraData[l]).appendTo(w)[0]));m.iframeTarget||(v.appendTo("body"),g.attachEvent?g.attachEvent("onload",s):g.addEventListener("load",s,!1)),setTimeout(t,15);try{w.submit()}catch(c){var p=document.createElement("form").submit;p.apply(w)}}finally{w.setAttribute("action",i),r?w.setAttribute("target",r):f.removeAttr("target"),e(o).remove()}}function s(t){if(!x.aborted&&!F){if(M=n(g),M||(a("cannot access response document"),t=D),t===k&&x)return x.abort("timeout"),S.reject(x,"timeout"),void 0;if(t==D&&x)return x.abort("server abort"),S.reject(x,"error","server abort"),void 0;if(M&&M.location.href!=m.iframeSrc||T){g.detachEvent?g.detachEvent("onload",s):g.removeEventListener("load",s,!1);var r,i="success";try{if(T)throw"timeout";var o="xml"==m.dataType||M.XMLDocument||e.isXMLDoc(M);if(a("isXml="+o),!o&&window.opera&&(null===M.body||!M.body.innerHTML)&&--O)return a("requeing onLoad callback, DOM not available"),setTimeout(s,250),void 0;var u=M.body?M.body:M.documentElement;x.responseText=u?u.innerHTML:null,x.responseXML=M.XMLDocument?M.XMLDocument:M,o&&(m.dataType="xml"),x.getResponseHeader=function(e){var t={"content-type":m.dataType};return t[e]},u&&(x.status=Number(u.getAttribute("status"))||x.status,x.statusText=u.getAttribute("statusText")||x.statusText);
2770var l=(m.dataType||"").toLowerCase(),c=/(json|script|text)/.test(l);if(c||m.textarea){var f=M.getElementsByTagName("textarea")[0];if(f)x.responseText=f.value,x.status=Number(f.getAttribute("status"))||x.status,x.statusText=f.getAttribute("statusText")||x.statusText;else if(c){var d=M.getElementsByTagName("pre")[0],h=M.getElementsByTagName("body")[0];d?x.responseText=d.textContent?d.textContent:d.innerText:h&&(x.responseText=h.textContent?h.textContent:h.innerText)}}else"xml"==l&&!x.responseXML&&x.responseText&&(x.responseXML=X(x.responseText));try{E=_(x,l,m)}catch(b){i="parsererror",x.error=r=b||i}}catch(b){a("error caught: ",b),i="error",x.error=r=b||i}x.aborted&&(a("upload aborted"),i=null),x.status&&(i=x.status>=200&&300>x.status||304===x.status?"success":"error"),"success"===i?(m.success&&m.success.call(m.context,E,"success",x),S.resolve(x.responseText,"success",x),p&&e.event.trigger("ajaxSuccess",[x,m])):i&&(void 0===r&&(r=x.statusText),m.error&&m.error.call(m.context,x,i,r),S.reject(x,"error",r),p&&e.event.trigger("ajaxError",[x,m,r])),p&&e.event.trigger("ajaxComplete",[x,m]),p&&!--e.active&&e.event.trigger("ajaxStop"),m.complete&&m.complete.call(m.context,x,i),F=!0,m.timeout&&clearTimeout(j),setTimeout(function(){m.iframeTarget||v.remove(),x.responseXML=null},100)}}}var l,c,m,p,d,v,g,x,b,y,T,j,w=f[0],S=e.Deferred();if(S.abort=function(e){x.abort(e)},r)for(c=0;h.length>c;c++)l=e(h[c]),i?l.prop("disabled",!1):l.removeAttr("disabled");if(m=e.extend(!0,{},e.ajaxSettings,t),m.context=m.context||m,d="jqFormIO"+(new Date).getTime(),m.iframeTarget?(v=e(m.iframeTarget),y=v.attr2("name"),y?d=y:v.attr2("name",d)):(v=e('<iframe name="'+d+'" src="'+m.iframeSrc+'" />'),v.css({position:"absolute",top:"-1000px",left:"-1000px"})),g=v[0],x={aborted:0,responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(t){var r="timeout"===t?"timeout":"aborted";a("aborting upload... "+r),this.aborted=1;try{g.contentWindow.document.execCommand&&g.contentWindow.document.execCommand("Stop")}catch(n){}v.attr("src",m.iframeSrc),x.error=r,m.error&&m.error.call(m.context,x,r,t),p&&e.event.trigger("ajaxError",[x,m,r]),m.complete&&m.complete.call(m.context,x,r)}},p=m.global,p&&0===e.active++&&e.event.trigger("ajaxStart"),p&&e.event.trigger("ajaxSend",[x,m]),m.beforeSend&&m.beforeSend.call(m.context,x,m)===!1)return m.global&&e.active--,S.reject(),S;if(x.aborted)return S.reject(),S;b=w.clk,b&&(y=b.name,y&&!b.disabled&&(m.extraData=m.extraData||{},m.extraData[y]=b.value,"image"==b.type&&(m.extraData[y+".x"]=w.clk_x,m.extraData[y+".y"]=w.clk_y)));var k=1,D=2,A=e("meta[name=csrf-token]").attr("content"),L=e("meta[name=csrf-param]").attr("content");L&&A&&(m.extraData=m.extraData||{},m.extraData[L]=A),m.forceSync?o():setTimeout(o,10);var E,M,F,O=50,X=e.parseXML||function(e,t){return window.ActiveXObject?(t=new ActiveXObject("Microsoft.XMLDOM"),t.async="false",t.loadXML(e)):t=(new DOMParser).parseFromString(e,"text/xml"),t&&t.documentElement&&"parsererror"!=t.documentElement.nodeName?t:null},C=e.parseJSON||function(e){return window.eval("("+e+")")},_=function(t,r,a){var n=t.getResponseHeader("content-type")||"",i="xml"===r||!r&&n.indexOf("xml")>=0,o=i?t.responseXML:t.responseText;return i&&"parsererror"===o.documentElement.nodeName&&e.error&&e.error("parsererror"),a&&a.dataFilter&&(o=a.dataFilter(o,r)),"string"==typeof o&&("json"===r||!r&&n.indexOf("json")>=0?o=C(o):("script"===r||!r&&n.indexOf("javascript")>=0)&&e.globalEval(o)),o};return S}if(!this.length)return a("ajaxSubmit: skipping submit process - no element selected"),this;var u,l,c,f=this;"function"==typeof t?t={success:t}:void 0===t&&(t={}),u=t.type||this.attr2("method"),l=t.url||this.attr2("action"),c="string"==typeof l?e.trim(l):"",c=c||window.location.href||"",c&&(c=(c.match(/^([^#]+)/)||[])[1]),t=e.extend(!0,{url:c,success:e.ajaxSettings.success,type:u||e.ajaxSettings.type,iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank"},t);var m={};if(this.trigger("form-pre-serialize",[this,t,m]),m.veto)return a("ajaxSubmit: submit vetoed via form-pre-serialize trigger"),this;if(t.beforeSerialize&&t.beforeSerialize(this,t)===!1)return a("ajaxSubmit: submit aborted via beforeSerialize callback"),this;var p=t.traditional;void 0===p&&(p=e.ajaxSettings.traditional);var d,h=[],v=this.formToArray(t.semantic,h);if(t.data&&(t.extraData=t.data,d=e.param(t.data,p)),t.beforeSubmit&&t.beforeSubmit(v,this,t)===!1)return a("ajaxSubmit: submit aborted via beforeSubmit callback"),this;if(this.trigger("form-submit-validate",[v,this,t,m]),m.veto)return a("ajaxSubmit: submit vetoed via form-submit-validate trigger"),this;var g=e.param(v,p);d&&(g=g?g+"&"+d:d),"GET"==t.type.toUpperCase()?(t.url+=(t.url.indexOf("?")>=0?"&":"?")+g,t.data=null):t.data=g;var x=[];if(t.resetForm&&x.push(function(){f.resetForm()}),t.clearForm&&x.push(function(){f.clearForm(t.includeHidden)}),!t.dataType&&t.target){var b=t.success||function(){};x.push(function(r){var a=t.replaceTarget?"replaceWith":"html";e(t.target)[a](r).each(b,arguments)})}else t.success&&x.push(t.success);if(t.success=function(e,r,a){for(var n=t.context||this,i=0,o=x.length;o>i;i++)x[i].apply(n,[e,r,a||f,f])},t.error){var y=t.error;t.error=function(e,r,a){var n=t.context||this;y.apply(n,[e,r,a,f])}}if(t.complete){var T=t.complete;t.complete=function(e,r){var a=t.context||this;T.apply(a,[e,r,f])}}var j=e('input[type=file]:enabled:not([value=""])',this),w=j.length>0,S="multipart/form-data",k=f.attr("enctype")==S||f.attr("encoding")==S,D=n.fileapi&&n.formdata;a("fileAPI :"+D);var A,L=(w||k)&&!D;t.iframe!==!1&&(t.iframe||L)?t.closeKeepAlive?e.get(t.closeKeepAlive,function(){A=s(v)}):A=s(v):A=(w||k)&&D?o(v):e.ajax(t),f.removeData("jqxhr").data("jqxhr",A);for(var E=0;h.length>E;E++)h[E]=null;return this.trigger("form-submit-notify",[this,t]),this},e.fn.ajaxForm=function(n){if(n=n||{},n.delegation=n.delegation&&e.isFunction(e.fn.on),!n.delegation&&0===this.length){var i={s:this.selector,c:this.context};return!e.isReady&&i.s?(a("DOM not ready, queuing ajaxForm"),e(function(){e(i.s,i.c).ajaxForm(n)}),this):(a("terminating; zero elements found by selector"+(e.isReady?"":" (DOM not ready)")),this)}return n.delegation?(e(document).off("submit.form-plugin",this.selector,t).off("click.form-plugin",this.selector,r).on("submit.form-plugin",this.selector,n,t).on("click.form-plugin",this.selector,n,r),this):this.ajaxFormUnbind().bind("submit.form-plugin",n,t).bind("click.form-plugin",n,r)},e.fn.ajaxFormUnbind=function(){return this.unbind("submit.form-plugin click.form-plugin")},e.fn.formToArray=function(t,r){var a=[];if(0===this.length)return a;var i=this[0],o=t?i.getElementsByTagName("*"):i.elements;if(!o)return a;var s,u,l,c,f,m,p;for(s=0,m=o.length;m>s;s++)if(f=o[s],l=f.name,l&&!f.disabled)if(t&&i.clk&&"image"==f.type)i.clk==f&&(a.push({name:l,value:e(f).val(),type:f.type}),a.push({name:l+".x",value:i.clk_x},{name:l+".y",value:i.clk_y}));else if(c=e.fieldValue(f,!0),c&&c.constructor==Array)for(r&&r.push(f),u=0,p=c.length;p>u;u++)a.push({name:l,value:c[u]});else if(n.fileapi&&"file"==f.type){r&&r.push(f);var d=f.files;if(d.length)for(u=0;d.length>u;u++)a.push({name:l,value:d[u],type:f.type});else a.push({name:l,value:"",type:f.type})}else null!==c&&c!==void 0&&(r&&r.push(f),a.push({name:l,value:c,type:f.type,required:f.required}));if(!t&&i.clk){var h=e(i.clk),v=h[0];l=v.name,l&&!v.disabled&&"image"==v.type&&(a.push({name:l,value:h.val()}),a.push({name:l+".x",value:i.clk_x},{name:l+".y",value:i.clk_y}))}return a}
2770,e.fn.formSerialize=function(t){return e.param(this.formToArray(t))},e.fn.fieldSerialize=function(t){var r=[];return this.each(function(){var a=this.name;if(a){var n=e.fieldValue(this,t);if(n&&n.constructor==Array)for(var i=0,o=n.length;o>i;i++)r.push({name:a,value:n[i]});else null!==n&&n!==void 0&&r.push({name:this.name,value:n})}}),e.param(r)},e.fn.fieldValue=function(t){for(var r=[],a=0,n=this.length;n>a;a++){var i=this[a],o=e.fieldValue(i,t);null===o||void 0===o||o.constructor==Array&&!o.length||(o.constructor==Array?e.merge(r,o):r.push(o))}return r},e.fieldValue=function(t,r){var a=t.name,n=t.type,i=t.tagName.toLowerCase();if(void 0===r&&(r=!0),r&&(!a||t.disabled||"reset"==n||"button"==n||("checkbox"==n||"radio"==n)&&!t.checked||("submit"==n||"image"==n)&&t.form&&t.form.clk!=t||"select"==i&&-1==t.selectedIndex))return null;if("select"==i){var o=t.selectedIndex;if(0>o)return null;for(var s=[],u=t.options,l="select-one"==n,c=l?o+1:u.length,f=l?o:0;c>f;f++){var m=u[f];if(m.selected){var p=m.value;if(p||(p=m.attributes&&m.attributes.value&&!m.attributes.value.specified?m.text:m.value),l)return p;s.push(p)}}return s}return e(t).val()},e.fn.clearForm=function(t){return this.each(function(){e("input,select,textarea",this).clearFields(t)})},e.fn.clearFields=e.fn.clearInputs=function(t){var r=/^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i;return this.each(function(){var a=this.type,n=this.tagName.toLowerCase();r.test(a)||"textarea"==n?this.value="":"checkbox"==a||"radio"==a?this.checked=!1:"select"==n?this.selectedIndex=-1:"file"==a?/MSIE/.test(navigator.userAgent)?e(this).replaceWith(e(this).clone(!0)):e(this).val(""):t&&(t===!0&&/hidden/.test(a)||"string"==typeof t&&e(this).is(t))&&(this.value="")})},e.fn.resetForm=function(){return this.each(function(){("function"==typeof this.reset||"object"==typeof this.reset&&!this.reset.nodeType)&&this.reset()})},e.fn.enable=function(e){return void 0===e&&(e=!0),this.each(function(){this.disabled=!e})},e.fn.selected=function(t){return void 0===t&&(t=!0),this.each(function(){var r=this.type;if("checkbox"==r||"radio"==r)this.checked=t;else if("option"==this.tagName.toLowerCase()){var a=e(this).parent("select");t&&a[0]&&"select-one"==a[0].type&&a.find("option").selected(!1),this.selected=t}})},e.fn.ajaxSubmit.debug=!1})("undefined"!=typeof jQuery?jQuery:window.Zepto);
2771/**
2772 * jquery.Jcrop.js v0.9.12
2773 * jQuery Image Cropping Plugin - released under MIT License 
2774 * Author: Kelly Hallman <[email protected]>
2775 * http://github.com/tapmodo/Jcrop
2776 * Copyright (c) 2008-2013 Tapmodo Interactive LLC {{{
2777 *
2778 * Permission is hereby granted, free of charge, to any person
2779 * obtaining a copy of this software and associated documentation
2780 * files (the "Software"), to deal in the Software without
2781 * restriction, including without limitation the rights to use,
2782 * copy, modify, merge, publish, distribute, sublicense, and/or sell
2783 * copies of the Software, and to permit persons to whom the
2784 * Software is furnished to do so, subject to the following
2785 * conditions:
2786 *
2787 * The above copyright notice and this permission notice shall be
2788 * included in all copies or substantial portions of the Software.
2789 *
2790 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2791 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
2792 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2793 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
2794 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
2795 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2796 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2797 * OTHER DEALINGS IN THE SOFTWARE.
2798 *
2799 * }}}
2800 */
2801
2802(function ($) {
2803
2804  $.Jcrop = function (obj, opt) {
2805    var options = $.extend({}, $.Jcrop.defaults),
2806        docOffset,
2807        _ua = navigator.userAgent.toLowerCase(),
2808        is_msie = /msie/.test(_ua),
2809        ie6mode = /msie [1-6]\./.test(_ua);
2810
2811    // Internal Methods {{{
2812    function px(n) {
2813      return Math.round(n) + 'px';
2814    }
2815    function cssClass(cl) {
2816      return options.baseClass + '-' + cl;
2817    }
2818    function supportsColorFade() {
2819      return $.fx.step.hasOwnProperty('backgroundColor');
2820    }
2821    function getPos(obj) //{{{
2822    {
2823      var pos = $(obj).offset();
2824      return [pos.left, pos.top];
2825    }
2826    //}}}
2827    function mouseAbs(e) //{{{
2828    {
2829      return [(e.pageX - docOffset[0]), (e.pageY - docOffset[1])];
2830    }
2831    //}}}
2832    function setOptions(opt) //{{{
2833    {
2834      if (typeof(opt) !== 'object') opt = {};
2835      options = $.extend(options, opt);
2836
2837      $.each(['onChange','onSelect','onRelease','onDblClick'],function(i,e) {
2838        if (typeof(options[e]) !== 'function') options[e] = function () {};
2839      });
2840    }
2841    //}}}
2842    function startDragMode(mode, pos, touch) //{{{
2843    {
2844      docOffset = getPos($img);
2845      Tracker.setCursor(mode === 'move' ? mode : mode + '-resize');
2846
2847      if (mode === 'move') {
2848        return Tracker.activateHandlers(createMover(pos), doneSelect, touch);
2849      }
2850
2851      var fc = Coords.getFixed();
2852      var opp = oppLockCorner(mode);
2853      var opc = Coords.getCorner(oppLockCorner(opp));
2854
2855      Coords.setPressed(Coords.getCorner(opp));
2856      Coords.setCurrent(opc);
2857
2858      Tracker.activateHandlers(dragmodeHandler(mode, fc), doneSelect, touch);
2859    }
2860    //}}}
2861    function dragmodeHandler(mode, f) //{{{
2862    {
2863      return function (pos) {
2864        if (!options.aspectRatio) {
2865          switch (mode) {
2866          case 'e':
2867            pos[1] = f.y2;
2868            break;
2869          case 'w':
2870            pos[1] = f.y2;
2871            break;
2872          case 'n':
2873            pos[0] = f.x2;
2874            break;
2875          case 's':
2876            pos[0] = f.x2;
2877            break;
2878          }
2879        } else {
2880          switch (mode) {
2881          case 'e':
2882            pos[1] = f.y + 1;
2883            break;
2884          case 'w':
2885            pos[1] = f.y + 1;
2886            break;
2887          case 'n':
2888            pos[0] = f.x + 1;
2889            break;
2890          case 's':
2891            pos[0] = f.x + 1;
2892            break;
2893          }
2894        }
2895        Coords.setCurrent(pos);
2896        Selection.update();
2897      };
2898    }
2899    //}}}
2900    function createMover(pos) //{{{
2901    {
2902      var lloc = pos;
2903      KeyManager.watchKeys();
2904
2905      return function (pos) {
2906        Coords.moveOffset([pos[0] - lloc[0], pos[1] - lloc[1]]);
2907        lloc = pos;
2908
2909        Selection.update();
2910      };
2911    }
2912    //}}}
2913    function oppLockCorner(ord) //{{{
2914    {
2915      switch (ord) {
2916      case 'n':
2917        return 'sw';
2918      case 's':
2919        return 'nw';
2920      case 'e':
2921        return 'nw';
2922      case 'w':
2923        return 'ne';
2924      case 'ne':
2925        return 'sw';
2926      case 'nw':
2927        return 'se';
2928      case 'se':
2929        return 'nw';
2930      case 'sw':
2931        return 'ne';
2932      }
2933    }
2934    //}}}
2935    function createDragger(ord) //{{{
2936    {
2937      return function (e) {
2938        if (options.disabled) {
2939          return false;
2940        }
2941        if ((ord === 'move') && !options.allowMove) {
2942          return false;
2943        }
2944        
2945        // Fix position of crop area when dragged the very first time.
2946        // Necessary when crop image is in a hidden element when page is loaded.
2947        docOffset = getPos($img);
2948
2949        btndown = true;
2950        startDragMode(ord, mouseAbs(e));
2951        e.stopPropagation();
2952        e.preventDefault();
2953        return false;
2954      };
2955    }
2956    //}}}
2957    function presize($obj, w, h) //{{{
2958    {
2959      var nw = $obj.width(),
2960          nh = $obj.height();
2961      if ((nw > w) && w > 0) {
2962        nw = w;
2963        nh = (w / $obj.width()) * $obj.height();
2964      }
2965      if ((nh > h) && h > 0) {
2966        nh = h;
2967        nw = (h / $obj.height()) * $obj.width();
2968      }
2969      xscale = $obj.width() / nw;
2970      yscale = $obj.height() / nh;
2971      $obj.width(nw).height(nh);
2972    }
2973    //}}}
2974    function unscale(c) //{{{
2975    {
2976      return {
2977        x: c.x * xscale,
2978        y: c.y * yscale,
2979        x2: c.x2 * xscale,
2980        y2: c.y2 * yscale,
2981        w: c.w * xscale,
2982        h: c.h * yscale
2983      };
2984    }
2985    //}}}
2986    function doneSelect(pos) //{{{
2987    {
2988      var c = Coords.getFixed();
2989      if ((c.w > options.minSelect[0]) && (c.h > options.minSelect[1])) {
2990        Selection.enableHandles();
2991        Selection.done();
2992      } else {
2993        Selection.release();
2994      }
2995      Tracker.setCursor(options.allowSelect ? 'crosshair' : 'default');
2996    }
2997    //}}}
2998    function newSelection(e) //{{{
2999    {
3000      if (options.disabled) {
3001        return;
3002      }
3003      if (!options.allowSelect) {
3004        return;
3005      }
3006      btndown = true;
3007      docOffset = getPos($img);
3008      Selection.disableHandles();
3009      Tracker.setCursor('crosshair');
3010      var pos = mouseAbs(e);
3011      Coords.setPressed(pos);
3012      Selection.update();
3013      Tracker.activateHandlers(selectDrag, doneSelect, e.type.substring(0,5)==='touch');
3014      KeyManager.watchKeys();
3015
3016      e.stopPropagation();
3017      e.preventDefault();
3018      return false;
3019    }
3020    //}}}
3021    function selectDrag(pos) //{{{
3022    {
3023      Coords.setCurrent(pos);
3024      Selection.update();
3025    }
3026    //}}}
3027    function newTracker() //{{{
3028    {
3029      var trk = $('<div></div>').addClass(cssClass('tracker'));
3030      if (is_msie) {
3031        trk.css({
3032          opacity: 0,
3033          backgroundColor: 'white'
3034        });
3035      }
3036      return trk;
3037    }
3038    //}}}
3039
3040    // }}}
3041    // Initialization {{{
3042    // Sanitize some options {{{
3043    if (typeof(obj) !== 'object') {
3044      obj = $(obj)[0];
3045    }
3046    if (typeof(opt) !== 'object') {
3047      opt = {};
3048    }
3049    // }}}
3050    setOptions(opt);
3051    // Initialize some jQuery objects {{{
3052    // The values are SET on the image(s) for the interface
3053    // If the original image has any of these set, they will be reset
3054    // However, if you destroy() the Jcrop instance the original image's
3055    // character in the DOM will be as you left it.
3056    var img_css = {
3057      border: 'none',
3058      visibility: 'visible',
3059      margin: 0,
3060      padding: 0,
3061      position: 'absolute',
3062      top: 0,
3063      left: 0
3064    };
3065
3066    var $origimg = $(obj),
3067      img_mode = true;
3068
3069    if (obj.tagName == 'IMG') {
3070      // Fix size of crop image.
3071      // Necessary when crop image is within a hidden element when page is loaded.
3072      if ($origimg[0].width != 0 && $origimg[0].height != 0) {
3073        // Obtain dimensions from contained img element.
3074        $origimg.width($origimg[0].width);
3075        $origimg.height($origimg[0].height);
3076      } else {
3077        // Obtain dimensions from temporary image in case the original is not loaded yet (e.g. IE 7.0). 
3078        var tempImage = new Image();
3079        tempImage.src = $origimg[0].src;
3080        $origimg.width(tempImage.width);
3081        $origimg.height(tempImage.height);
3082      } 
3083
3084      var $img = $origimg.clone().removeAttr('id').css(img_css).show();
3085
3086      $img.width($origimg.width());
3087      $img.height($origimg.height());
3088      $origimg.after($img).hide();
3089
3090    } else {
3091      $img = $origimg.css(img_css).show();
3092      img_mode = false;
3093      if (options.shade === null) { options.shade = true; }
3094    }
3095
3096    presize($img, options.boxWidth, options.boxHeight);
3097
3098    var boundx = $img.width(),
3099        boundy = $img.height(),
3100        
3101        
3102        $div = $('<div />').width(boundx).height(boundy).addClass(cssClass('holder')).css({
3103        position: 'relative',
3104        backgroundColor: options.bgColor
3105      }).insertAfter($origimg).append($img);
3106
3107    if (options.addClass) {
3108      $div.addClass(options.addClass);
3109    }
3110
3111    var $img2 = $('<div />'),
3112
3113        $img_holder = $('<div />') 
3114        .width('100%').height('100%').css({
3115          zIndex: 310,
3116          position: 'absolute',
3117          overflow: 'hidden'
3118        }),
3119
3120        $hdl_holder = $('<div />') 
3121        .width('100%').height('100%').css('zIndex', 320), 
3122
3123        $sel = $('<div />') 
3124        .css({
3125          position: 'absolute',
3126          zIndex: 600
3127        }).dblclick(function(){
3128          var c = Coords.getFixed();
3129          options.onDblClick.call(api,c);
3130        }).insertBefore($img).append($img_holder, $hdl_holder); 
3131
3132    if (img_mode) {
3133
3134      $img2 = $('<img />')
3135          .attr('src', $img.attr('src')).css(img_css).width(boundx).height(boundy),
3136
3137      $img_holder.append($img2);
3138
3139    }
3140
3141    if (ie6mode) {
3142      $sel.css({
3143        overflowY: 'hidden'
3144      });
3145    }
3146
3147    var bound = options.boundary;
3148    var $trk = newTracker().width(boundx + (bound * 2)).height(boundy + (bound * 2)).css({
3149      position: 'absolute',
3150      top: px(-bound),
3151      left: px(-bound),
3152      zIndex: 290
3153    }).mousedown(newSelection);
3154
3155    /* }}} */
3156    // Set more variables {{{
3157    var bgcolor = options.bgColor,
3158        bgopacity = options.bgOpacity,
3159        xlimit, ylimit, xmin, ymin, xscale, yscale, enabled = true,
3160        btndown, animating, shift_down;
3161
3162    docOffset = getPos($img);
3163    // }}}
3164    // }}}
3165    // Internal Modules {{{
3166    // Touch Module {{{ 
3167    var Touch = (function () {
3168      // Touch support detection function adapted (under MIT License)
3169      // from code by Jeffrey Sambells - http://github.com/iamamused/
3170      function hasTouchSupport() {
3171        var support = {}, events = ['touchstart', 'touchmove', 'touchend'],
3172            el = document.createElement('div'), i;
3173
3174        try {
3175          for(i=0; i<events.length; i++) {
3176            var eventName = events[i];
3177            eventName = 'on' + eventName;
3178            var isSupported = (eventName in el);
3179            if (!isSupported) {
3180              el.setAttribute(eventName, 'return;');
3181              isSupported = typeof el[eventName] == 'function';
3182            }
3183            support[events[i]] = isSupported;
3184          }
3185          return support.touchstart && support.touchend && support.touchmove;
3186        }
3187        catch(err) {
3188          return false;
3189        }
3190      }
3191
3192      function detectSupport() {
3193        if ((options.touchSupport === true) || (options.touchSupport === false)) return options.touchSupport;
3194          else return hasTouchSupport();
3195      }
3196      return {
3197        createDragger: function (ord) {
3198          return function (e) {
3199            if (options.disabled) {
3200              return false;
3201            }
3202            if ((ord === 'move') && !options.allowMove) {
3203              return false;
3204            }
3205            docOffset = getPos($img);
3206            btndown = true;
3207            startDragMode(ord, mouseAbs(Touch.cfilter(e)), true);
3208            e.stopPropagation();
3209            e.preventDefault();
3210            return false;
3211          };
3212        },
3213        newSelection: function (e) {
3214          return newSelection(Touch.cfilter(e));
3215        },
3216        cfilter: function (e){
3217          e.pageX = e.originalEvent.changedTouches[0].pageX;
3218          e.pageY = e.originalEvent.changedTouches[0].pageY;
3219          return e;
3220        },
3221        isSupported: hasTouchSupport,
3222        support: detectSupport()
3223      };
3224    }());
3225    // }}}
3226    // Coords Module {{{
3227    var Coords = (function () {
3228      var x1 = 0,
3229          y1 = 0,
3230          x2 = 0,
3231          y2 = 0,
3232          ox, oy;
3233
3234      function setPressed(pos) //{{{
3235      {
3236        pos = rebound(pos);
3237        x2 = x1 = pos[0];
3238        y2 = y1 = pos[1];
3239      }
3240      //}}}
3241      function setCurrent(pos) //{{{
3242      {
3243        pos = rebound(pos);
3244        ox = pos[0] - x2;
3245        oy = pos[1] - y2;
3246        x2 = pos[0];
3247        y2 = pos[1];
3248      }
3249      //}}}
3250      function getOffset() //{{{
3251      {
3252        return [ox, oy];
3253      }
3254      //}}}
3255      function moveOffset(offset) //{{{
3256      {
3257        var ox = offset[0],
3258            oy = offset[1];
3259
3260        if (0 > x1 + ox) {
3261          ox -= ox + x1;
3262        }
3263        if (0 > y1 + oy) {
3264          oy -= oy + y1;
3265        }
3266
3267        if (boundy < y2 + oy) {
3268          oy += boundy - (y2 + oy);
3269        }
3270        if (boundx < x2 + ox) {
3271          ox += boundx - (x2 + ox);
3272        }
3273
3274        x1 += ox;
3275        x2 += ox;
3276        y1 += oy;
3277        y2 += oy;
3278      }
3279      //}}}
3280      function getCorner(ord) //{{{
3281      {
3282        var c = getFixed();
3283        switch (ord) {
3284        case 'ne':
3285          return [c.x2, c.y];
3286        case 'nw':
3287          return [c.x, c.y];
3288        case 'se':
3289          return [c.x2, c.y2];
3290        case 'sw':
3291          return [c.x, c.y2];
3292        }
3293      }
3294      //}}}
3295      function getFixed() //{{{
3296      {
3297        if (!options.aspectRatio) {
3298          return getRect();
3299        }
3300        // This function could use some optimization I think...
3301        var aspect = options.aspectRatio,
3302            min_x = options.minSize[0] / xscale,
3303            
3304            
3305            //min_y = options.minSize[1]/yscale,
3306            max_x = options.maxSize[0] / xscale,
3307            max_y = options.maxSize[1] / yscale,
3308            rw = x2 - x1,
3309            rh = y2 - y1,
3310            rwa = Math.abs(rw),
3311            rha = Math.abs(rh),
3312            real_ratio = rwa / rha,
3313            xx, yy, w, h;
3314
3315        if (max_x === 0) {
3316          max_x = boundx * 10;
3317        }
3318        if (max_y === 0) {
3319          max_y = boundy * 10;
3320        }
3321        if (real_ratio < aspect) {
3322          yy = y2;
3323          w = rha * aspect;
3324          xx = rw < 0 ? x1 - w : w + x1;
3325
3326          if (xx < 0) {
3327            xx = 0;
3328            h = Math.abs((xx - x1) / aspect);
3329            yy = rh < 0 ? y1 - h : h + y1;
3330          } else if (xx > boundx) {
3331            xx = boundx;
3332            h = Math.abs((xx - x1) / aspect);
3333            yy = rh < 0 ? y1 - h : h + y1;
3334          }
3335        } else {
3336          xx = x2;
3337          h = rwa / aspect;
3338          yy = rh < 0 ? y1 - h : y1 + h;
3339          if (yy < 0) {
3340            yy = 0;
3341            w = Math.abs((yy - y1) * aspect);
3342            xx = rw < 0 ? x1 - w : w + x1;
3343          } else if (yy > boundy) {
3344            yy = boundy;
3345            w = Math.abs(yy - y1) * aspect;
3346            xx = rw < 0 ? x1 - w : w + x1;
3347          }
3348        }
3349
3350        // Magic %-)
3351        if (xx > x1) { // right side
3352          if (xx - x1 < min_x) {
3353            xx = x1 + min_x;
3354          } else if (xx - x1 > max_x) {
3355            xx = x1 + max_x;
3356          }
3357          if (yy > y1) {
3358            yy = y1 + (xx - x1) / aspect;
3359          } else {
3360            yy = y1 - (xx - x1) / aspect;
3361          }
3362        } else if (xx < x1) { // left side
3363          if (x1 - xx < min_x) {
3364            xx = x1 - min_x;
3365          } else if (x1 - xx > max_x) {
3366            xx = x1 - max_x;
3367          }
3368          if (yy > y1) {
3369            yy = y1 + (x1 - xx) / aspect;
3370          } else {
3371            yy = y1 - (x1 - xx) / aspect;
3372          }
3373        }
3374
3375        if (xx < 0) {
3376          x1 -= xx;
3377          xx = 0;
3378        } else if (xx > boundx) {
3379          x1 -= xx - boundx;
3380          xx = boundx;
3381        }
3382
3383        if (yy < 0) {
3384          y1 -= yy;
3385          yy = 0;
3386        } else if (yy > boundy) {
3387          y1 -= yy - boundy;
3388          yy = boundy;
3389        }
3390
3391        return makeObj(flipCoords(x1, y1, xx, yy));
3392      }
3393      //}}}
3394      function rebound(p) //{{{
3395      {
3396        if (p[0] < 0) p[0] = 0;
3397        if (p[1] < 0) p[1] = 0;
3398
3399        if (p[0] > boundx) p[0] = boundx;
3400        if (p[1] > boundy) p[1] = boundy;
3401
3402        return [Math.round(p[0]), Math.round(p[1])];
3403      }
3404      //}}}
3405      function flipCoords(x1, y1, x2, y2) //{{{
3406      {
3407        var xa = x1,
3408            xb = x2,
3409            ya = y1,
3410            yb = y2;
3411        if (x2 < x1) {
3412          xa = x2;
3413          xb = x1;
3414        }
3415        if (y2 < y1) {
3416          ya = y2;
3417          yb = y1;
3418        }
3419        return [xa, ya, xb, yb];
3420      }
3421      //}}}
3422      function getRect() //{{{
3423      {
3424        var xsize = x2 - x1,
3425            ysize = y2 - y1,
3426            delta;
3427
3428        if (xlimit && (Math.abs(xsize) > xlimit)) {
3429          x2 = (xsize > 0) ? (x1 + xlimit) : (x1 - xlimit);
3430        }
3431        if (ylimit && (Math.abs(ysize) > ylimit)) {
3432          y2 = (ysize > 0) ? (y1 + ylimit) : (y1 - ylimit);
3433        }
3434
3435        if (ymin / yscale && (Math.abs(ysize) < ymin / yscale)) {
3436          y2 = (ysize > 0) ? (y1 + ymin / yscale) : (y1 - ymin / yscale);
3437        }
3438        if (xmin / xscale && (Math.abs(xsize) < xmin / xscale)) {
3439          x2 = (xsize > 0) ? (x1 + xmin / xscale) : (x1 - xmin / xscale);
3440        }
3441
3442        if (x1 < 0) {
3443          x2 -= x1;
3444          x1 -= x1;
3445        }
3446        if (y1 < 0) {
3447          y2 -= y1;
3448          y1 -= y1;
3449        }
3450        if (x2 < 0) {
3451          x1 -= x2;
3452          x2 -= x2;
3453        }
3454        if (y2 < 0) {
3455          y1 -= y2;
3456          y2 -= y2;
3457        }
3458        if (x2 > boundx) {
3459          delta = x2 - boundx;
3460          x1 -= delta;
3461          x2 -= delta;
3462        }
3463        if (y2 > boundy) {
3464          delta = y2 - boundy;
3465          y1 -= delta;
3466          y2 -= delta;
3467        }
3468        if (x1 > boundx) {
3469          delta = x1 - boundy;
3470          y2 -= delta;
3471          y1 -= delta;
3472        }
3473        if (y1 > boundy) {
3474          delta = y1 - boundy;
3475          y2 -= delta;
3476          y1 -= delta;
3477        }
3478
3479        return makeObj(flipCoords(x1, y1, x2, y2));
3480      }
3481      //}}}
3482      function makeObj(a) //{{{
3483      {
3484        return {
3485          x: a[0],
3486          y: a[1],
3487          x2: a[2],
3488          y2: a[3],
3489          w: a[2] - a[0],
3490          h: a[3] - a[1]
3491        };
3492      }
3493      //}}}
3494
3495      return {
3496        flipCoords: flipCoords,
3497        setPressed: setPressed,
3498        setCurrent: setCurrent,
3499        getOffset: getOffset,
3500        moveOffset: moveOffset,
3501        getCorner: getCorner,
3502        getFixed: getFixed
3503      };
3504    }());
3505
3506    //}}}
3507    // Shade Module {{{
3508    var Shade = (function() {
3509      var enabled = false,
vendor: 7,004 bytes, lines 3510-3796
3510          holder = $('<div />').css({
3511            position: 'absolute',
3512            zIndex: 240,
3513            opacity: 0
3514          }),
3515          shades = {
3516            top: createShade(),
3517            left: createShade().height(boundy),
3518            right: createShade().height(boundy),
3519            bottom: createShade()
3520          };
3521
3522      function resizeShades(w,h) {
3523        shades.left.css({ height: px(h) });
3524        shades.right.css({ height: px(h) });
3525      }
3526      function updateAuto()
3527      {
3528        return updateShade(Coords.getFixed());
3529      }
3530      function updateShade(c)
3531      {
3532        shades.top.css({
3533          left: px(c.x),
3534          width: px(c.w),
3535          height: px(c.y)
3536        });
3537        shades.bottom.css({
3538          top: px(c.y2),
3539          left: px(c.x),
3540          width: px(c.w),
3541          height: px(boundy-c.y2)
3542        });
3543        shades.right.css({
3544          left: px(c.x2),
3545          width: px(boundx-c.x2)
3546        });
3547        shades.left.css({
3548          width: px(c.x)
3549        });
3550      }
3551      function createShade() {
3552        return $('<div />').css({
3553          position: 'absolute',
3554          backgroundColor: options.shadeColor||options.bgColor
3555        }).appendTo(holder);
3556      }
3557      function enableShade() {
3558        if (!enabled) {
3559          enabled = true;
3560          holder.insertBefore($img);
3561          updateAuto();
3562          Selection.setBgOpacity(1,0,1);
3563          $img2.hide();
3564
3565          setBgColor(options.shadeColor||options.bgColor,1);
3566          if (Selection.isAwake())
3567          {
3568            setOpacity(options.bgOpacity,1);
3569          }
3570            else setOpacity(1,1);
3571        }
3572      }
3573      function setBgColor(color,now) {
3574        colorChangeMacro(getShades(),color,now);
3575      }
3576      function disableShade() {
3577        if (enabled) {
3578          holder.remove();
3579          $img2.show();
3580          enabled = false;
3581          if (Selection.isAwake()) {
3582            Selection.setBgOpacity(options.bgOpacity,1,1);
3583          } else {
3584            Selection.setBgOpacity(1,1,1);
3585            Selection.disableHandles();
3586          }
3587          colorChangeMacro($div,0,1);
3588        }
3589      }
3590      function setOpacity(opacity,now) {
3591        if (enabled) {
3592          if (options.bgFade && !now) {
3593            holder.animate({
3594              opacity: 1-opacity
3595            },{
3596              queue: false,
3597              duration: options.fadeTime
3598            });
3599          }
3600          else holder.css({opacity:1-opacity});
3601        }
3602      }
3603      function refreshAll() {
3604        options.shade ? enableShade() : disableShade();
3605        if (Selection.isAwake()) setOpacity(options.bgOpacity);
3606      }
3607      function getShades() {
3608        return holder.children();
3609      }
3610
3611      return {
3612        update: updateAuto,
3613        updateRaw: updateShade,
3614        getShades: getShades,
3615        setBgColor: setBgColor,
3616        enable: enableShade,
3617        disable: disableShade,
3618        resize: resizeShades,
3619        refresh: refreshAll,
3620        opacity: setOpacity
3621      };
3622    }());
3623    // }}}
3624    // Selection Module {{{
3625    var Selection = (function () {
3626      var awake,
3627          hdep = 370,
3628          borders = {},
3629          handle = {},
3630          dragbar = {},
3631          seehandles = false;
3632
3633      // Private Methods
3634      function insertBorder(type) //{{{
3635      {
3636        var jq = $('<div />').css({
3637          position: 'absolute',
3638          opacity: options.borderOpacity
3639        }).addClass(cssClass(type));
3640        $img_holder.append(jq);
3641        return jq;
3642      }
3643      //}}}
3644      function dragDiv(ord, zi) //{{{
3645      {
3646        var jq = $('<div />').mousedown(createDragger(ord)).css({
3647          cursor: ord + '-resize',
3648          position: 'absolute',
3649          zIndex: zi
3650        }).addClass('ord-'+ord);
3651
3652        if (Touch.support) {
3653          jq.bind('touchstart.jcrop', Touch.createDragger(ord));
3654        }
3655
3656        $hdl_holder.append(jq);
3657        return jq;
3658      }
3659      //}}}
3660      function insertHandle(ord) //{{{
3661      {
3662        var hs = options.handleSize,
3663
3664          div = dragDiv(ord, hdep++).css({
3665            opacity: options.handleOpacity
3666          }).addClass(cssClass('handle'));
3667
3668        if (hs) { div.width(hs).height(hs); }
3669
3670        return div;
3671      }
3672      //}}}
3673      function insertDragbar(ord) //{{{
3674      {
3675        return dragDiv(ord, hdep++).addClass('jcrop-dragbar');
3676      }
3677      //}}}
3678      function createDragbars(li) //{{{
3679      {
3680        var i;
3681        for (i = 0; i < li.length; i++) {
3682          dragbar[li[i]] = insertDragbar(li[i]);
3683        }
3684      }
3685      //}}}
3686      function createBorders(li) //{{{
3687      {
3688        var cl,i;
3689        for (i = 0; i < li.length; i++) {
3690          switch(li[i]){
3691            case'n': cl='hline'; break;
3692            case's': cl='hline bottom'; break;
3693            case'e': cl='vline right'; break;
3694            case'w': cl='vline'; break;
3695          }
3696          borders[li[i]] = insertBorder(cl);
3697        }
3698      }
3699      //}}}
3700      function createHandles(li) //{{{
3701      {
3702        var i;
3703        for (i = 0; i < li.length; i++) {
3704          handle[li[i]] = insertHandle(li[i]);
3705        }
3706      }
3707      //}}}
3708      function moveto(x, y) //{{{
3709      {
3710        if (!options.shade) {
3711          $img2.css({
3712            top: px(-y),
3713            left: px(-x)
3714          });
3715        }
3716        $sel.css({
3717          top: px(y),
3718          left: px(x)
3719        });
3720      }
3721      //}}}
3722      function resize(w, h) //{{{
3723      {
3724        $sel.width(Math.round(w)).height(Math.round(h));
3725      }
3726      //}}}
3727      function refresh() //{{{
3728      {
3729        var c = Coords.getFixed();
3730
3731        Coords.setPressed([c.x, c.y]);
3732        Coords.setCurrent([c.x2, c.y2]);
3733
3734        updateVisible();
3735      }
3736      //}}}
3737
3738      // Internal Methods
3739      function updateVisible(select) //{{{
3740      {
3741        if (awake) {
3742          return update(select);
3743        }
3744      }
3745      //}}}
3746      function update(select) //{{{
3747      {
3748        var c = Coords.getFixed();
3749
3750        resize(c.w, c.h);
3751        moveto(c.x, c.y);
3752        if (options.shade) Shade.updateRaw(c);
3753
3754        awake || show();
3755
3756        if (select) {
3757          options.onSelect.call(api, unscale(c));
3758        } else {
3759          options.onChange.call(api, unscale(c));
3760        }
3761      }
3762      //}}}
3763      function setBgOpacity(opacity,force,now) //{{{
3764      {
3765        if (!awake && !force) return;
3766        if (options.bgFade && !now) {
3767          $img.animate({
3768            opacity: opacity
3769          },{
3770            queue: false,
3771            duration: options.fadeTime
3772          });
3773        } else {
3774          $img.css('opacity', opacity);
3775        }
3776      }
3777      //}}}
3778      function show() //{{{
3779      {
3780        $sel.show();
3781
3782        if (options.shade) Shade.opacity(bgopacity);
3783          else setBgOpacity(bgopacity,true);
3784
3785        awake = true;
3786      }
3787      //}}}
3788      function release() //{{{
3789      {
3790        disableHandles();
3791        $sel.hide();
3792
3793        if (options.shade) Shade.opacity(1);
3794          else setBgOpacity(1);
3795
3796        awake = false;
3797        options.onRelease.call(api);
3798      }
3799      //}}}
3800      function showHandles() //{{{
3801      {
3802        if (seehandles) {
3803          $hdl_holder.show();
3804        }
3805      }
3806      //}}}
3807      function enableHandles() //{{{
3808      {
3809        seehandles = true;
3810        if (options.allowResize) {
3811          $hdl_holder.show();
3812          return true;
3813        }
3814      }
3815      //}}}
3816      function disableHandles() //{{{
3817      {
3818        seehandles = false;
3819        $hdl_holder.hide();
3820      } 
3821      //}}}
3822      function animMode(v) //{{{
3823      {
3824        if (v) {
3825          animating = true;
3826          disableHandles();
3827        } else {
3828          animating = false;
3829          enableHandles();
3830        }
3831      } 
3832      //}}}
3833      function done() //{{{
3834      {
3835        animMode(false);
3836        refresh();
3837      } 
3838      //}}}
3839      // Insert draggable elements {{{
3840      // Insert border divs for outline
3841
3842      if (options.dragEdges && $.isArray(options.createDragbars))
3843        createDragbars(options.createDragbars);
3844
3845      if ($.isArray(options.createHandles))
3846        createHandles(options.createHandles);
3847
3848      if (options.drawBorders && $.isArray(options.createBorders))
3849        createBorders(options.createBorders);
3850
3851      //}}}
3852
3853      // This is a hack for iOS5 to support drag/move touch functionality
3854      $(document).bind('touchstart.jcrop-ios',function(e) {
3855        if ($(e.currentTarget).hasClass('jcrop-tracker')) e.stopPropagation();
3856      });
3857
3858      var $track = newTracker().mousedown(createDragger('move')).css({
3859        cursor: 'move',
3860        position: 'absolute',
3861        zIndex: 360
3862      });
3863
3864      if (Touch.support) {
3865        $track.bind('touchstart.jcrop', Touch.createDragger('move'));
3866      }
3867
3868      $img_holder.append($track);
3869      disableHandles();
3870
3871      return {
3872        updateVisible: updateVisible,
3873        update: update,
3874        release: release,
3875        refresh: refresh,
3876        isAwake: function () {
3877          return awake;
3878        },
3879        setCursor: function (cursor) {
3880          $track.css('cursor', cursor);
3881        },
3882        enableHandles: enableHandles,
3883        enableOnly: function () {
3884          seehandles = true;
3885        },
3886        showHandles: showHandles,
3887        disableHandles: disableHandles,
3888        animMode: animMode,
3889        setBgOpacity: setBgOpacity,
3890        done: done
3891      };
3892    }());
3893    
3894    //}}}
3895    // Tracker Module {{{
3896    var Tracker = (function () {
3897      var onMove = function () {},
3898          onDone = function () {},
3899          trackDoc = options.trackDocument;
3900
3901      function toFront(touch) //{{{
3902      {
3903        $trk.css({
3904          zIndex: 450
3905        });
3906
3907        if (touch)
3908          $(document)
3909            .bind('touchmove.jcrop', trackTouchMove)
3910            .bind('touchend.jcrop', trackTouchEnd);
3911
3912        else if (trackDoc)
3913          $(document)
3914            .bind('mousemove.jcrop',trackMove)
3915            .bind('mouseup.jcrop',trackUp);
3916      } 
3917      //}}}
3918      function toBack() //{{{
3919      {
3920        $trk.css({
3921          zIndex: 290
3922        });
3923        $(document).unbind('.jcrop');
3924      } 
3925      //}}}
3926      function trackMove(e) //{{{
3927      {
3928        onMove(mouseAbs(e));
3929        return false;
3930      } 
3931      //}}}
3932      function trackUp(e) //{{{
3933      {
3934        e.preventDefault();
3935        e.stopPropagation();
3936
3937        if (btndown) {
3938          btndown = false;
3939
3940          onDone(mouseAbs(e));
3941
3942          if (Selection.isAwake()) {
3943            options.onSelect.call(api, unscale(Coords.getFixed()));
3944          }
3945
3946          toBack();
3947          onMove = function () {};
3948          onDone = function () {};
3949        }
3950
3951        return false;
3952      }
3953      //}}}
3954      function activateHandlers(move, done, touch) //{{{
3955      {
3956        btndown = true;
3957        onMove = move;
3958        onDone = done;
3959        toFront(touch);
3960        return false;
3961      }
3962      //}}}
3963      function trackTouchMove(e) //{{{
3964      {
3965        onMove(mouseAbs(Touch.cfilter(e)));
3966        return false;
3967      }
3968      //}}}
3969      function trackTouchEnd(e) //{{{
3970      {
3971        return trackUp(Touch.cfilter(e));
3972      }
3973      //}}}
3974      function setCursor(t) //{{{
3975      {
3976        $trk.css('cursor', t);
3977      }
3978      //}}}
3979
3980      if (!trackDoc) {
3981        $trk.mousemove(trackMove).mouseup(trackUp).mouseout(trackUp);
3982      }
3983
3984      $img.before($trk);
3985      return {
3986        activateHandlers: activateHandlers,
3987        setCursor: setCursor
3988      };
3989    }());
3990    //}}}
3991    // KeyManager Module {{{
3992    var KeyManager = (function () {
3993      var $keymgr = $('<input type="radio" />').css({
3994        position: 'fixed',
3995        left: '-120px',
3996        width: '12px'
3997      }).addClass('jcrop-keymgr'),
3998
3999        $keywrap = $('<div />').css({
4000          position: 'absolute',
4001          overflow: 'hidden'
4002        }).append($keymgr);
4003
4004      function watchKeys() //{{{
4005      {
4006        if (options.keySupport) {
4007          $keymgr.show();
4008          $keymgr.focus();
4009        }
4010      }
4011      //}}}
4012      function onBlur(e) //{{{
4013      {
4014        $keymgr.hide();
4015      }
4016      //}}}
4017      function doNudge(e, x, y) //{{{
4018      {
4019        if (options.allowMove) {
4020          Coords.moveOffset([x, y]);
4021          Selection.updateVisible(true);
4022        }
4023        e.preventDefault();
4024        e.stopPropagation();
4025      }
4026      //}}}
4027      function parseKey(e) //{{{
4028      {
4029        if (e.ctrlKey || e.metaKey) {
4030          return true;
4031        }
4032        shift_down = e.shiftKey ? true : false;
4033        var nudge = shift_down ? 10 : 1;
4034
4035        switch (e.keyCode) {
4036        case 37:
4037          doNudge(e, -nudge, 0);
4038          break;
4039        case 39:
4040          doNudge(e, nudge, 0);
4041          break;
4042        case 38:
4043          doNudge(e, 0, -nudge);
4044          break;
4045        case 40:
4046          doNudge(e, 0, nudge);
4047          break;
4048        case 27:
4049          if (options.allowSelect) Selection.release();
4050          break;
4051        case 9:
4052          return true;
4053        }
4054
4055        return false;
4056      }
4057      //}}}
4058
4059      if (options.keySupport) {
4060        $keymgr.keydown(parseKey).blur(onBlur);
4061        if (ie6mode || !options.fixedSupport) {
4062          $keymgr.css({
4063            position: 'absolute',
4064            left: '-20px'
4065          });
4066          $keywrap.append($keymgr).insertBefore($img);
4067        } else {
4068          $keymgr.insertBefore($img);
4069        }
4070      }
4071
4072
4073      return {
4074        watchKeys: watchKeys
4075      };
4076    }());
4077    //}}}
4078    // }}}
4079    // API methods {{{
4080    function setClass(cname) //{{{
4081    {
4082      $div.removeClass().addClass(cssClass('holder')).addClass(cname);
4083    }
4084    //}}}
4085    function animateTo(a, callback) //{{{
4086    {
4087      var x1 = a[0] / xscale,
4088          y1 = a[1] / yscale,
4089          x2 = a[2] / xscale,
4090          y2 = a[3] / yscale;
4091
4092      if (animating) {
4093        return;
4094      }
4095
4096      var animto = Coords.flipCoords(x1, y1, x2, y2),
4097          c = Coords.getFixed(),
4098          initcr = [c.x, c.y, c.x2, c.y2],
4099          animat = initcr,
4100          interv = options.animationDelay,
4101          ix1 = animto[0] - initcr[0],
4102          iy1 = animto[1] - initcr[1],
4103          ix2 = animto[2] - initcr[2],
4104          iy2 = animto[3] - initcr[3],
4105          pcent = 0,
4106          velocity = options.swingSpeed;
4107
4108      x1 = animat[0];
4109      y1 = animat[1];
4110      x2 = animat[2];
4111      y2 = animat[3];
4112
4113      Selection.animMode(true);
4114      var anim_timer;
4115
4116      function queueAnimator() {
4117        window.setTimeout(animator, interv);
4118      }
4119      var animator = (function () {
4120        return function () {
4121          pcent += (100 - pcent) / velocity;
4122
4123          animat[0] = Math.round(x1 + ((pcent / 100) * ix1));
4124          animat[1] = Math.round(y1 + ((pcent / 100) * iy1));
4125          animat[2] = Math.round(x2 + ((pcent / 100) * ix2));
4126          animat[3] = Math.round(y2 + ((pcent / 100) * iy2));
4127
4128          if (pcent >= 99.8) {
4129            pcent = 100;
4130          }
4131          if (pcent < 100) {
4132            setSelectRaw(animat);
4133            queueAnimator();
4134          } else {
4135            Selection.done();
4136            Selection.animMode(false);
4137            if (typeof(callback) === 'function') {
4138              callback.call(api);
4139            }
4140          }
4141        };
4142      }());
4143      queueAnimator();
4144    }
4145    //}}}
4146    function setSelect(rect) //{{{
4147    {
4148      setSelectRaw([rect[0] / xscale, rect[1] / yscale, rect[2] / xscale, rect[3] / yscale]);
4149      options.onSelect.call(api, unscale(Coords.getFixed()));
4150      Selection.enableHandles();
4151    }
4152    //}}}
4153    function setSelectRaw(l) //{{{
4154    {
4155      Coords.setPressed([l[0], l[1]]);
4156      Coords.setCurrent([l[2], l[3]]);
4157      Selection.update();
4158    }
4159    //}}}
4160    function tellSelect() //{{{
4161    {
4162      return unscale(Coords.getFixed());
4163    }
4164    //}}}
4165    function tellScaled() //{{{
4166    {
4167      return Coords.getFixed();
4168    }
4169    //}}}
4170    function setOptionsNew(opt) //{{{
4171    {
4172      setOptions(opt);
4173      interfaceUpdate();
4174    }
4175    //}}}
4176    function disableCrop() //{{{
4177    {
4178      options.disabled = true;
4179      Selection.disableHandles();
4180      Selection.setCursor('default');
4181      Tracker.setCursor('default');
4182    }
4183    //}}}
4184    function enableCrop() //{{{
4185    {
4186      options.disabled = false;
4187      interfaceUpdate();
4188    }
4189    //}}}
4190    function cancelCrop() //{{{
4191    {
4192      Selection.done();
4193      Tracker.activateHandlers(null, null);
4194    }
4195    //}}}
4196    function destroy() //{{{
4197    {
4198      $div.remove();
4199      $origimg.show();
4200      $origimg.css('visibility','visible');
4201      $(obj).removeData('Jcrop');
4202    }
4203    //}}}
4204    function setImage(src, callback) //{{{
4205    {
4206      Selection.release();
4207      disableCrop();
4208      var img = new Image();
4209      img.onload = function () {
4210        var iw = img.width;
4211        var ih = img.height;
4212        var bw = options.boxWidth;
4213        var bh = options.boxHeight;
4214        $img.width(iw).height(ih);
4215        $img.attr('src', src);
4216        $img2.attr('src', src);
4217        presize($img, bw, bh);
4218        boundx = $img.width();
4219        boundy = $img.height();
4220        $img2.width(boundx).height(boundy);
4221        $trk.width(boundx + (bound * 2)).height(boundy + (bound * 2));
4222        $div.width(boundx).height(boundy);
4223        Shade.resize(boundx,boundy);
4224        enableCrop();
4225
4226        if (typeof(callback) === 'function') {
4227          callback.call(api);
4228        }
4229      };
4230      img.src = src;
4231    }
4232    //}}}
4233    function colorChangeMacro($obj,color,now) {
4234      var mycolor = color || options.bgColor;
4235      if (options.bgFade && supportsColorFade() && options.fadeTime && !now) {
4236        $obj.animate({
4237          backgroundColor: mycolor
4238        }, {
4239          queue: false,
4240          duration: options.fadeTime
4241        });
4242      } else {
4243        $obj.css('backgroundColor', mycolor);
4244      }
4245    }
4246    function interfaceUpdate(alt) //{{{
4247    // This method tweaks the interface based on options object.
4248    // Called when options are changed and at end of initialization.
4249    {
4250      if (options.allowResize) {
4251        if (alt) {
4252          Selection.enableOnly();
4253        } else {
4254          Selection.enableHandles();
4255        }
4256      } else {
4257        Selection.disableHandles();
4258      }
4259
4260      Tracker.setCursor(options.allowSelect ? 'crosshair' : 'default');
4261      Selection.setCursor(options.allowMove ? 'move' : 'default');
4262
4263      if (options.hasOwnProperty('trueSize')) {
4264        xscale = options.trueSize[0] / boundx;
4265        yscale = options.trueSize[1] / boundy;
4266      }
4267
4268      if (options.hasOwnProperty('setSelect')) {
4269        setSelect(options.setSelect);
4270        Selection.done();
4271        delete(options.setSelect);
4272      }
4273
4274      Shade.refresh();
4275
4276      if (options.bgColor != bgcolor) {
4277        colorChangeMacro(
4278          options.shade? Shade.getShades(): $div,
4279          options.shade?
4280            (options.shadeColor || options.bgColor):
4281            options.bgColor
4282        );
4283        bgcolor = options.bgColor;
4284      }
4285
4286      if (bgopacity != options.bgOpacity) {
4287        bgopacity = options.bgOpacity;
4288        if (options.shade) Shade.refresh();
4289          else Selection.setBgOpacity(bgopacity);
4290      }
4291
4292      xlimit = options.maxSize[0] || 0;
4293      ylimit = options.maxSize[1] || 0;
4294      xmin = options.minSize[0] || 0;
4295      ymin = options.minSize[1] || 0;
4296
4297      if (options.hasOwnProperty('outerImage')) {
4298        $img.attr('src', options.outerImage);
4299        delete(options.outerImage);
4300      }
4301
4302      Selection.refresh();
4303    }
4304    //}}}
4305    //}}}
4306
4307    if (Touch.support) $trk.bind('touchstart.jcrop', Touch.newSelection);
4308
4309    $hdl_holder.hide();
4310    interfaceUpdate(true);
4311
4312    var api = {
4313      setImage: setImage,
4314      animateTo: animateTo,
4315      setSelect: setSelect,
4316      setOptions: setOptionsNew,
4317      tellSelect: tellSelect,
4318      tellScaled: tellScaled,
4319      setClass: setClass,
4320
4321      disable: disableCrop,
4322      enable: enableCrop,
4323      cancel: cancelCrop,
4324      release: Selection.release,
4325      destroy: destroy,
4326
4327      focus: KeyManager.watchKeys,
4328
4329      getBounds: function () {
4330        return [boundx * xscale, boundy * yscale];
4331      },
4332      getWidgetSize: function () {
4333        return [boundx, boundy];
4334      },
4335      getScaleFactor: function () {
4336        return [xscale, yscale];
4337      },
4338      getOptions: function() {
4339        // careful: internal values are returned
4340        return options;
4341      },
4342
4343      ui: {
4344        holder: $div,
4345        selection: $sel
4346      }
4347    };
4348
4349    if (is_msie) $div.bind('selectstart', function () { return false; });
4350
4351    $origimg.data('Jcrop', api);
4352    return api;
4353  };
4354  $.fn.Jcrop = function (options, callback) //{{{
4355  {
4356    var api;
4357    // Iterate over each object, attach Jcrop
4358    this.each(function () {
4359      // If we've already attached to this object
4360      if ($(this).data('Jcrop')) {
4361        // The API can be requested this way (undocumented)
4362        if (options === 'api') return $(this).data('Jcrop');
4363        // Otherwise, we just reset the options...
4364        else $(this).data('Jcrop').setOptions(options);
4365      }
4366      // If we haven't been attached, preload and attach
4367      else {
4368        if (this.tagName == 'IMG')
4369          $.Jcrop.Loader(this,function(){
4370            $(this).css({display:'block',visibility:'hidden'});
4371            api = $.Jcrop(this, options);
4372            if ($.isFunction(callback)) callback.call(api);
4373          });
4374        else {
4375          $(this).css({display:'block',visibility:'hidden'});
4376          api = $.Jcrop(this, options);
4377          if ($.isFunction(callback)) callback.call(api);
4378        }
4379      }
4380    });
4381
4382    // Return "this" so the object is chainable (jQuery-style)
4383    return this;
4384  };
4385  //}}}
4386  // $.Jcrop.Loader - basic image loader {{{
4387
4388  $.Jcrop.Loader = function(imgobj,success,error){
4389    var $img = $(imgobj), img = $img[0];
4390
4391    function completeCheck(){
4392      if (img.complete) {
4393        $img.unbind('.jcloader');
4394        if ($.isFunction(success)) success.call(img);
4395      }
4396      else window.setTimeout(completeCheck,50);
4397    }
4398
4399    $img
4400      .bind('load.jcloader',completeCheck)
4401      .bind('error.jcloader',function(e){
4402        $img.unbind('.jcloader');
4403        if ($.isFunction(error)) error.call(img);
4404      });
4405
4406    if (img.complete && $.isFunction(success)){
4407      $img.unbind('.jcloader');
4408      success.call(img);
4409    }
4410  };
4411
4412  //}}}
4413  // Global Defaults {{{
4414  $.Jcrop.defaults = {
4415
4416    // Basic Settings
4417    allowSelect: true,
4418    allowMove: true,
4419    allowResize: true,
4420
4421    trackDocument: true,
4422
4423    // Styling Options
4424    baseClass: 'jcrop',
4425    addClass: null,
4426    bgColor: 'black',
4427    bgOpacity: 0.6,
4428    bgFade: false,
4429    borderOpacity: 0.4,
4430    handleOpacity: 0.5,
4431    handleSize: null,
4432
4433    aspectRatio: 0,
4434    keySupport: true,
4435    createHandles: ['n','s','e','w','nw','ne','se','sw'],
4436    createDragbars: ['n','s','e','w'],
4437    createBorders: ['n','s','e','w'],
4438    drawBorders: true,
4439    dragEdges: true,
4440    fixedSupport: true,
4441    touchSupport: null,
4442
4443    shade: null,
4444
4445    boxWidth: 0,
4446    boxHeight: 0,
4447    boundary: 2,
4448    fadeTime: 400,
4449    animationDelay: 20,
4450    swingSpeed: 3,
4451
4452    minSelect: [0, 0],
4453    maxSize: [0, 0],
4454    minSize: [0, 0],
4455
4456    // Callbacks / Event Handlers
4457    onChange: function () {},
4458    onSelect: function () {},
4459    onDblClick: function () {},
4460    onRelease: function () {}
4461  };
4462
4463  // }}}
4464}(jQuery));
4465
4466/*
4467 * jScrollPane - v2.0.0beta12 - 2012-09-27
4468 * http://jscrollpane.kelvinluck.com/
4469 *
4470 * Copyright (c) 2010 Kelvin Luck
4471 * Dual licensed under the MIT or GPL licenses.
4472 */
4473(function(b,a,c){b.fn.jScrollPane=function(e){function d(D,O){var ay,Q=this,Y,aj,v,al,T,Z,y,q,az,aE,au,i,I,h,j,aa,U,ap,X,t,A,aq,af,am,G,l,at,ax,x,av,aH,f,L,ai=true,P=true,aG=false,k=false,ao=D.clone(false,false).empty(),ac=b.fn.mwheelIntent?"mwheelIntent.jsp":"mousewheel.jsp";aH=D.css("paddingTop")+" "+D.css("paddingRight")+" "+D.css("paddingBottom")+" "+D.css("paddingLeft");f=(parseInt(D.css("paddingLeft"),10)||0)+(parseInt(D.css("paddingRight"),10)||0);function ar(aQ){var aL,aN,aM,aJ,aI,aP,aO=false,aK=false;ay=aQ;if(Y===c){aI=D.scrollTop();aP=D.scrollLeft();D.css({overflow:"hidden",padding:0});aj=D.innerWidth()+f;v=D.innerHeight();D.width(aj);Y=b('<div class="jspPane" />').css("padding",aH).append(D.children());al=b('<div class="jspContainer" />').css({width:aj+"px",height:v+"px"}).append(Y).appendTo(D)}else{D.css("width","");aO=ay.stickToBottom&&K();aK=ay.stickToRight&&B();aJ=D.innerWidth()+f!=aj||D.outerHeight()!=v;if(aJ){aj=D.innerWidth()+f;v=D.innerHeight();al.css({width:aj+"px",height:v+"px"})}if(!aJ&&L==T&&Y.outerHeight()==Z){D.width(aj);return}L=T;Y.css("width","");D.width(aj);al.find(">.jspVerticalBar,>.jspHorizontalBar").remove().end()}Y.css("overflow","auto");if(aQ.contentWidth){T=aQ.contentWidth}else{T=Y[0].scrollWidth}Z=Y[0].scrollHeight;Y.css("overflow","");y=T/aj;q=Z/v;az=q>1;aE=y>1;if(!(aE||az)){D.removeClass("jspScrollable");Y.css({top:0,width:al.width()-f});n();E();R();w()}else{D.addClass("jspScrollable");aL=ay.maintainPosition&&(I||aa);if(aL){aN=aC();aM=aA()}aF();z();F();if(aL){N(aK?(T-aj):aN,false);M(aO?(Z-v):aM,false)}J();ag();an();if(ay.enableKeyboardNavigation){S()}if(ay.clickOnTrack){p()}C();if(ay.hijackInternalLinks){m()}}if(ay.autoReinitialise&&!av){av=setInterval(function(){ar(ay)},ay.autoReinitialiseDelay)}else{if(!ay.autoReinitialise&&av){clearInterval(av)}}aI&&D.scrollTop(0)&&M(aI,false);aP&&D.scrollLeft(0)&&N(aP,false);D.trigger("jsp-initialised",[aE||az])}function aF(){if(az){al.append(b('<div class="jspVerticalBar" />').append(b('<div class="jspCap jspCapTop" />'),b('<div class="jspTrack" />').append(b('<div class="jspDrag" />').append(b('<div class="jspDragTop" />'),b('<div class="jspDragBottom" />'))),b('<div class="jspCap jspCapBottom" />')));U=al.find(">.jspVerticalBar");ap=U.find(">.jspTrack");au=ap.find(">.jspDrag");if(ay.showArrows){aq=b('<a class="jspArrow jspArrowUp" />').bind("mousedown.jsp",aD(0,-1)).bind("click.jsp",aB);af=b('<a class="jspArrow jspArrowDown" />').bind("mousedown.jsp",aD(0,1)).bind("click.jsp",aB);if(ay.arrowScrollOnHover){aq.bind("mouseover.jsp",aD(0,-1,aq));af.bind("mouseover.jsp",aD(0,1,af))}ak(ap,ay.verticalArrowPositions,aq,af)}t=v;al.find(">.jspVerticalBar>.jspCap:visible,>.jspVerticalBar>.jspArrow").each(function(){t-=b(this).outerHeight()});au.hover(function(){au.addClass("jspHover")},function(){au.removeClass("jspHover")}).bind("mousedown.jsp",function(aI){b("html").bind("dragstart.jsp selectstart.jsp",aB);au.addClass("jspActive");var s=aI.pageY-au.position().top;b("html").bind("mousemove.jsp",function(aJ){V(aJ.pageY-s,false)}).bind("mouseup.jsp mouseleave.jsp",aw);return false});o()}}function o(){ap.height(t+"px");I=0;X=ay.verticalGutter+ap.outerWidth();Y.width(aj-X-f);try{if(U.position().left===0){Y.css("margin-left",X+"px")}}catch(s){}}function z(){if(aE){al.append(b('<div class="jspHorizontalBar" />').append(b('<div class="jspCap jspCapLeft" />'),b('<div class="jspTrack" />').append(b('<div class="jspDrag" />').append(b('<div class="jspDragLeft" />'),b('<div class="jspDragRight" />'))),b('<div class="jspCap jspCapRight" />')));am=al.find(">.jspHorizontalBar");G=am.find(">.jspTrack");h=G.find(">.jspDrag");
4473if(ay.showArrows){ax=b('<a class="jspArrow jspArrowLeft" />').bind("mousedown.jsp",aD(-1,0)).bind("click.jsp",aB);x=b('<a class="jspArrow jspArrowRight" />').bind("mousedown.jsp",aD(1,0)).bind("click.jsp",aB);
4474if(ay.arrowScrollOnHover){ax.bind("mouseover.jsp",aD(-1,0,ax));x.bind("mouseover.jsp",aD(1,0,x))}ak(G,ay.horizontalArrowPositions,ax,x)}h.hover(function(){h.addClass("jspHover")},function(){h.removeClass("jspHover")}).bind("mousedown.jsp",function(aI){b("html").bind("dragstart.jsp selectstart.jsp",aB);h.addClass("jspActive");var s=aI.pageX-h.position().left;b("html").bind("mousemove.jsp",function(aJ){W(aJ.pageX-s,false)}).bind("mouseup.jsp mouseleave.jsp",aw);return false});l=al.innerWidth();ah()}}function ah(){al.find(">.jspHorizontalBar>.jspCap:visible,>.jspHorizontalBar>.jspArrow").each(function(){l-=b(this).outerWidth()});G.width(l+"px");aa=0}function F(){if(aE&&az){var aI=G.outerHeight(),s=ap.outerWidth();t-=aI;b(am).find(">.jspCap:visible,>.jspArrow").each(function(){l+=b(this).outerWidth()});l-=s;v-=s;aj-=aI;G.parent().append(b('<div class="jspCorner" />').css("width",aI+"px"));o();ah()}if(aE){Y.width((al.outerWidth()-f)+"px")}Z=Y.outerHeight();q=Z/v;if(aE){at=Math.ceil(1/y*l);if(at>ay.horizontalDragMaxWidth){at=ay.horizontalDragMaxWidth}else{if(at<ay.horizontalDragMinWidth){at=ay.horizontalDragMinWidth}}h.width(at+"px");j=l-at;ae(aa)}if(az){A=Math.ceil(1/q*t);if(A>ay.verticalDragMaxHeight){A=ay.verticalDragMaxHeight}else{if(A<ay.verticalDragMinHeight){A=ay.verticalDragMinHeight}}au.height(A+"px");i=t-A;ad(I)}}function ak(aJ,aL,aI,s){var aN="before",aK="after",aM;if(aL=="os"){aL=/Mac/.test(navigator.platform)?"after":"split"}if(aL==aN){aK=aL}else{if(aL==aK){aN=aL;aM=aI;aI=s;s=aM}}aJ[aN](aI)[aK](s)}function aD(aI,s,aJ){return function(){H(aI,s,this,aJ);this.blur();return false}}function H(aL,aK,aO,aN){aO=b(aO).addClass("jspActive");var aM,aJ,aI=true,s=function(){if(aL!==0){Q.scrollByX(aL*ay.arrowButtonSpeed)}if(aK!==0){Q.scrollByY(aK*ay.arrowButtonSpeed)}aJ=setTimeout(s,aI?ay.initialDelay:ay.arrowRepeatFreq);aI=false};s();aM=aN?"mouseout.jsp":"mouseup.jsp";aN=aN||b("html");aN.bind(aM,function(){aO.removeClass("jspActive");aJ&&clearTimeout(aJ);aJ=null;aN.unbind(aM)})}function p(){w();if(az){ap.bind("mousedown.jsp",function(aN){if(aN.originalTarget===c||aN.originalTarget==aN.currentTarget){var aL=b(this),aO=aL.offset(),aM=aN.pageY-aO.top-I,aJ,aI=true,s=function(){var aR=aL.offset(),aS=aN.pageY-aR.top-A/2,aP=v*ay.scrollPagePercent,aQ=i*aP/(Z-v);if(aM<0){if(I-aQ>aS){Q.scrollByY(-aP)}else{V(aS)}}else{if(aM>0){if(I+aQ<aS){Q.scrollByY(aP)}else{V(aS)}}else{aK();return}}aJ=setTimeout(s,aI?ay.initialDelay:ay.trackClickRepeatFreq);aI=false},aK=function(){aJ&&clearTimeout(aJ);aJ=null;b(document).unbind("mouseup.jsp",aK)};s();b(document).bind("mouseup.jsp",aK);return false}})}if(aE){G.bind("mousedown.jsp",function(aN){if(aN.originalTarget===c||aN.originalTarget==aN.currentTarget){var aL=b(this),aO=aL.offset(),aM=aN.pageX-aO.left-aa,aJ,aI=true,s=function(){var aR=aL.offset(),aS=aN.pageX-aR.left-at/2,aP=aj*ay.scrollPagePercent,aQ=j*aP/(T-aj);if(aM<0){if(aa-aQ>aS){Q.scrollByX(-aP)}else{W(aS)}}else{if(aM>0){if(aa+aQ<aS){Q.scrollByX(aP)}else{W(aS)}}else{aK();return}}aJ=setTimeout(s,aI?ay.initialDelay:ay.trackClickRepeatFreq);aI=false},aK=function(){aJ&&clearTimeout(aJ);aJ=null;b(document).unbind("mouseup.jsp",aK)};s();b(document).bind("mouseup.jsp",aK);return false}})}}function w(){if(G){G.unbind("mousedown.jsp")}if(ap){ap.unbind("mousedown.jsp")}}function aw(){b("html").unbind("dragstart.jsp selectstart.jsp mousemove.jsp mouseup.jsp mouseleave.jsp");if(au){au.removeClass("jspActive")}if(h){h.removeClass("jspActive")}}function V(s,aI){if(!az){return}if(s<0){s=0}else{if(s>i){s=i}}if(aI===c){aI=ay.animateScroll}if(aI){Q.animate(au,"top",s,ad)}else{au.css("top",s);ad(s)}}function ad(aI){if(aI===c){aI=au.position().top}al.scrollTop(0);I=aI;var aL=I===0,aJ=I==i,aK=aI/i,s=-aK*(Z-v);if(ai!=aL||aG!=aJ){ai=aL;aG=aJ;D.trigger("jsp-arrow-change",[ai,aG,P,k])}u(aL,aJ);Y.css("top",s);D.trigger("jsp-scroll-y",[-s,aL,aJ]).trigger("scroll")}function W(aI,s){if(!aE){return}if(aI<0){aI=0}else{if(aI>j){aI=j}}if(s===c){s=ay.animateScroll}if(s){Q.animate(h,"left",aI,ae)
4475}else{h.css("left",aI);ae(aI)}}function ae(aI){if(aI===c){aI=h.position().left}al.scrollTop(0);aa=aI;var aL=aa===0,aK=aa==j,aJ=aI/j,s=-aJ*(T-aj);if(P!=aL||k!=aK){P=aL;k=aK;D.trigger("jsp-arrow-change",[ai,aG,P,k])}r(aL,aK);Y.css("left",s);D.trigger("jsp-scroll-x",[-s,aL,aK]).trigger("scroll")}function u(aI,s){if(ay.showArrows){aq[aI?"addClass":"removeClass"]("jspDisabled");af[s?"addClass":"removeClass"]("jspDisabled")}}function r(aI,s){if(ay.showArrows){ax[aI?"addClass":"removeClass"]("jspDisabled");x[s?"addClass":"removeClass"]("jspDisabled")}}function M(s,aI){var aJ=s/(Z-v);V(aJ*i,aI)}function N(aI,s){var aJ=aI/(T-aj);W(aJ*j,s)}function ab(aV,aQ,aJ){var aN,aK,aL,s=0,aU=0,aI,aP,aO,aS,aR,aT;try{aN=b(aV)}catch(aM){return}aK=aN.outerHeight();aL=aN.outerWidth();al.scrollTop(0);al.scrollLeft(0);while(!aN.is(".jspPane")){s+=aN.position().top;aU+=aN.position().left;aN=aN.offsetParent();if(/^body|html$/i.test(aN[0].nodeName)){return}}aI=aA();aO=aI+v;if(s<aI||aQ){aR=s-ay.verticalGutter}else{if(s+aK>aO){aR=s-v+aK+ay.verticalGutter}}if(aR){M(aR,aJ)}aP=aC();aS=aP+aj;if(aU<aP||aQ){aT=aU-ay.horizontalGutter}else{if(aU+aL>aS){aT=aU-aj+aL+ay.horizontalGutter}}if(aT){N(aT,aJ)}}function aC(){return -Y.position().left}function aA(){return -Y.position().top}function K(){var s=Z-v;return(s>
447520)&&(s-aA()<10)}function B(){var s=T-aj;return(s>20)&&(s-aC()<10)}function ag(){al.unbind(ac).bind(ac,function(aL,aM,aK,aI){var aJ=aa,s=I;Q.scrollBy(aK*ay.mouseWheelSpeed,-aI*ay.mouseWheelSpeed,false);return aJ==aa&&s==I})}function n(){al.unbind(ac)}function aB(){return false}function J(){Y.find(":input,a").unbind("focus.jsp").bind("focus.jsp",function(s){ab(s.target,false)})}function E(){Y.find(":input,a").unbind("focus.jsp")}function S(){var s,aI,aK=[];aE&&aK.push(am[0]);az&&aK.push(U[0]);Y.focus(function(){D.focus()});D.attr("tabindex",0).unbind("keydown.jsp keypress.jsp").bind("keydown.jsp",function(aN){if(aN.target!==this&&!(aK.length&&b(aN.target).closest(aK).length)){return}var aM=aa,aL=I;switch(aN.keyCode){case 40:case 38:case 34:case 32:case 33:case 39:case 37:s=aN.keyCode;aJ();break;case 35:M(Z-v);s=null;break;case 36:M(0);s=null;break}aI=aN.keyCode==s&&aM!=aa||aL!=I;return !aI}).bind("keypress.jsp",function(aL){if(aL.keyCode==s){aJ()}return !aI});if(ay.hideFocus){D.css("outline","none");if("hideFocus" in al[0]){D.attr("hideFocus",true)}}else{D.css("outline","");if("hideFocus" in al[0]){D.attr("hideFocus",false)}}function aJ(){var aM=aa,aL=I;switch(s){case 40:Q.scrollByY(ay.keyboardSpeed,false);break;case 38:Q.scrollByY(-ay.keyboardSpeed,false);break;case 34:case 32:Q.scrollByY(v*ay.scrollPagePercent,false);break;case 33:Q.scrollByY(-v*ay.scrollPagePercent,false);break;case 39:Q.scrollByX(ay.keyboardSpeed,false);break;case 37:Q.scrollByX(-ay.keyboardSpeed,false);break}aI=aM!=aa||aL!=I;return aI}}function R(){D.attr("tabindex","-1").removeAttr("tabindex").unbind("keydown.jsp keypress.jsp")}function C(){if(location.hash&&location.hash.length>1){var aK,aI,aJ=escape(location.hash.substr(1));try{aK=b("#"+aJ+', a[name="'+aJ+'"]')}catch(s){return}if(aK.length&&Y.find(aJ)){if(al.scrollTop()===0){aI=setInterval(function(){if(al.scrollTop()>0){ab(aK,true);b(document).scrollTop(al.position().top);clearInterval(aI)}},50)}else{ab(aK,true);b(document).scrollTop(al.position().top)}}}}function m(){if(b(document.body).data("jspHijack")){return}b(document.body).data("jspHijack",true);b(document.body).delegate("a[href*=#]","click",function(s){var aI=this.href.substr(0,this.href.indexOf("#")),aK=location.href,aO,aP,aJ,aM,aL,aN;if(location.href.indexOf("#")!==-1){aK=location.href.substr(0,location.href.indexOf("#"))}if(aI!==aK){return}aO=escape(this.href.substr(this.href.indexOf("#")+1));aP;try{aP=b("#"+aO+', a[name="'+aO+'"]')}catch(aQ){return}if(!aP.length){return}aJ=aP.closest(".jspScrollable");aM=aJ.data("jsp");aM.scrollToElement(aP,true);if(aJ[0].scrollIntoView){aL=b(a).scrollTop();aN=aP.offset().top;if(aN<aL||aN>aL+b(a).height()){aJ[0].scrollIntoView()}}s.preventDefault()
4476})}function an(){var aJ,aI,aL,aK,aM,s=false;al.unbind("touchstart.jsp touchmove.jsp touchend.jsp click.jsp-touchclick").bind("touchstart.jsp",function(aN){var aO=aN.originalEvent.touches[0];aJ=aC();aI=aA();aL=aO.pageX;aK=aO.pageY;aM=false;s=true}).bind("touchmove.jsp",function(aQ){if(!s){return}var aP=aQ.originalEvent.touches[0],aO=aa,aN=I;Q.scrollTo(aJ+aL-aP.pageX,aI+aK-aP.pageY);aM=aM||Math.abs(aL-aP.pageX)>5||Math.abs(aK-aP.pageY)>5;return aO==aa&&aN==I}).bind("touchend.jsp",function(aN){s=false}).bind("click.jsp-touchclick",function(aN){if(aM){aM=false;return false}})}function g(){var s=aA(),aI=aC();D.removeClass("jspScrollable").unbind(".jsp");D.replaceWith(ao.append(Y.children()));ao.scrollTop(s);ao.scrollLeft(aI);if(av){clearInterval(av)}}b.extend(Q,{reinitialise:function(aI){aI=b.extend({},ay,aI);ar(aI)},scrollToElement:function(aJ,aI,s){ab(aJ,aI,s)},scrollTo:function(aJ,s,aI){N(aJ,aI);M(s,aI)},scrollToX:function(aI,s){N(aI,s)},scrollToY:function(s,aI){M(s,aI)},scrollToPercentX:function(aI,s){N(aI*(T-aj),s)},scrollToPercentY:function(aI,s){M(aI*(Z-v),s)},scrollBy:function(aI,s,aJ){Q.scrollByX(aI,aJ);Q.scrollByY(s,aJ)},scrollByX:function(s,aJ){var aI=aC()+Math[s<0?"floor":"ceil"](s),aK=aI/(T-aj);W(aK*j,aJ)},scrollByY:function(s,aJ){var aI=aA()+Math[s<0?"floor":"ceil"](s),aK=aI/(Z-v);V(aK*i,aJ)},positionDragX:function(s,aI){W(s,aI)},positionDragY:function(aI,s){V(aI,s)},animate:function(aI,aL,s,aK){var aJ={};aJ[aL]=s;aI.animate(aJ,{duration:ay.animateDuration,easing:ay.animateEase,queue:false,step:aK})},getContentPositionX:function(){return aC()},getContentPositionY:function(){return aA()},getContentWidth:function(){return T},getContentHeight:function(){return Z},getPercentScrolledX:function(){return aC()/(T-aj)},getPercentScrolledY:function(){return aA()/(Z-v)},getIsScrollableH:function(){return aE},getIsScrollableV:function(){return az},getContentPane:function(){return Y},scrollToBottom:function(s){V(i,s)},hijackInternalLinks:b.noop,destroy:function(){g()}});ar(O)}e=b.extend({},b.fn.jScrollPane.defaults,e);b.each(["mouseWheelSpeed","arrowButtonSpeed","trackClickSpeed","keyboardSpeed"],function(){e[this]=e[this]||e.speed});return this.each(function(){var f=b(this),g=f.data("jsp");if(g){g.reinitialise(e)}else{b("script",f).filter('[type="text/javascript"],:not([type])').remove();g=new d(f,e);f.data("jsp",g)}})};b.fn.jScrollPane.defaults={showArrows:false,maintainPosition:true,stickToBottom:false,stickToRight:false,clickOnTrack:true,autoReinitialise:false,autoReinitialiseDelay:500,verticalDragMinHeight:0,verticalDragMaxHeight:99999,horizontalDragMinWidth:0,horizontalDragMaxWidth:99999,contentWidth:c,animateScroll:false,animateDuration:300,animateEase:"linear",hijackInternalLinks:false,verticalGutter:4,horizontalGutter:4,mouseWheelSpeed:0,arrowButtonSpeed:0,arrowRepeatFreq:50,arrowScrollOnHover:false,trackClickSpeed:0,trackClickRepeatFreq:70,verticalArrowPositions:"split",horizontalArrowPositions:"split",enableKeyboardNavigation:true,hideFocus:false,keyboardSpeed:0,initialDelay:300,speed:30,scrollPagePercent:0.8}})(jQuery,this);
4477/* Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
4478 * Licensed under the MIT License (LICENSE.txt).
4479 *
4480 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
4481 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
4482 * Thanks to: Seamus Leahy for adding deltaX and deltaY
4483 *
4484 * Version: 3.0.6
4485 * 
4486 * Requires: 1.2.2+
4487 */
4488(function(d){var b=["DOMMouseScroll","mousewheel"];if(d.event.fixHooks){for(var a=b.length;a;){d.event.fixHooks[b[--a]]=d.event.mouseHooks}}d.event.special.mousewheel={setup:function(){if(this.addEventListener){for(var e=b.length;e;){this.addEventListener(b[--e],c,false)}}else{this.onmousewheel=c}},teardown:function(){if(this.removeEventListener){for(var e=b.length;e;){this.removeEventListener(b[--e],c,false)}}else{this.onmousewheel=null}}};d.fn.extend({mousewheel:function(e){return e?this.bind("mousewheel",e):this.trigger("mousewheel")},unmousewheel:function(e){return this.unbind("mousewheel",e)}});
4488function c(j){var h=j||window.event,g=[].slice.call(arguments,1),k=0,i=true,f=0,e=0;j=d.event.fix(h);j.type="mousewheel";if(h.wheelDelta){k=h.wheelDelta/120}if(h.detail){k=-h.detail/3}e=k;if(h.axis!==undefined&&h.axis===h.HORIZONTAL_AXIS){e=0;f=-1*k}if(h.wheelDeltaY!==undefined){e=h.wheelDeltaY/120}if(h.wheelDeltaX!==undefined){f=-1*h.wheelDeltaX/120}g.unshift(j,k,f,e);return(d.event.dispatch||d.event.handle).apply(this,g)}})(jQuery);
4489(function($){
4490    var class_prefix    = 'nc-',
4491        latency_timeout = false,
4492        loaded_widgets  = [];
4493
4494    $(window).resize(function(){
4495        if (latency_timeout !== false) {
4496            return;
4497        }
4498        latency_timeout = setTimeout(function(){
4499            latency_timeout = false;
4500            for (var i=0; i<loaded_widgets.length; i++) {
4501                var widget    = loaded_widgets[i],
4502                    className = class_prefix + 'widget-' + widget.widget_id,
4503                    width     = widget.node.width();
4504
4505                for (var j=0; j<widget.breakpoints.length; j++) {
4506                    var breakpoint = widget.breakpoints[j];
4507                    className += ' ' + class_prefix + (width >= breakpoint ? 'lg' : 'sm') + '-' + breakpoint;
4508                }
4509
4510                widget.node[0].className = className;
4511            }
4512        }, 100);
4513    });
4514
4515    $.fn.nc_widget = function(options) {
4516        var css_loaded = false,
4517            widget = $.extend({
4518                node:        this,
4519                css:         false,
4520                breakpoints: [],
4521                widget_id:   0
4522            }, options);
4523
4524        for (var i=0; i<loaded_widgets.length; i++) {
4525            if (loaded_widgets[i].widget_id == widget.widget_id) {
4526                css_loaded = true;
4527                break;
4528            }
4529        }
4530
4531        if (!css_loaded) {
4532            $('head').append('<link rel="stylesheet" href="' + widget.css + '">');
4533        }
4534        
4535        widget.node.css({overflow:'hidden'});
4536        loaded_widgets.push(widget);
4537
4538        $(window).resize();
4539
4540        return this;
4541    };
4542 
4543}(jQuery));
4544if (typeof(lsDisplayLibLoaded) == 'undefined') {
4545    var lsDisplayLibLoaded = true;
4546    var E_CLICK  = 0,
4547        E_SUBMIT = 1;
4548
4549    jQuery(function(){
4550        var bindEvents = function($container){
4551            jQuery('[data-nc-ls-display-link]', $container).click(function(){
4552                eventHandler(this, true, E_CLICK);
4553                return false;
4554            });
4555            jQuery('form[data-nc-ls-display-form]', $container).submit(function(){
4556                eventHandler(this, true, E_SUBMIT);
4557                return false;
4558            });
4559        }
4560
4561        var eventHandler = function(element, callBindEvents, event_type){
4562
4563            switch (event_type) {
4564
4565                case E_SUBMIT:
4566                    var url_attr  = 'action';
4567                    var data_attr = 'data-nc-ls-display-form';
4568                    break;
4569
4570                case E_CLICK:
4571                default:
4572                    var url_attr  = 'href';
4573                    var data_attr = 'data-nc-ls-display-link';
4574                    break;
4575            }
4576
4577            var $this    = jQuery(element);
4578            var url      = $this.attr(url_attr);
4579            var obj_data = $this.attr(data_attr);
4580
4581            if (obj_data) {
4582                obj_data = jQuery.parseJSON(obj_data);
4583            }
4584            else {
4585                return false;
4586            }
4587
4588            var replace_content = obj_data.subdivisionId !== false;
4589
4590            if (url) {
4591                if (obj_data.displayType == 'shortpage' || (obj_data.displayType == 'longpage_vertical' && typeof(obj_data.subdivisionId) == 'undefined')) {
4592
4593                    var send_as_post = event_type === E_SUBMIT && $this.attr('method').toLowerCase() === 'post';
4594                    var send_data    = jQuery.extend({}, obj_data.query); // clone
4595
4596                    send_data.isNaked       = parseInt(typeof send_data.isNaked !== 'undefined' ? send_data.isNaked : 1);
4597                    send_data.lsDisplayType = obj_data.displayType;
4598                    send_data.skipTemplate  = parseInt(send_data.skipTemplate ? send_data.skipTemplate : obj_data.displayType == 'shortpage' && typeof(obj_data.subdivisionId) != 'undefined' ? 1 : 0);
4599
4600                    if (send_as_post) {
4601                        url += (url.indexOf('?') >= 0 ? '&' : '?') + jQuery.param(send_data);
4602                        send_data = $this.serialize();
4603                    }
4604
4605                    jQuery.ajax({
4606                        type:    send_as_post ? 'POST' : 'GET',
4607                        url:     url,
4608                        data:    send_data,
4609                        success: function(data){
4610                            var $container = [];
4611
4612                            if (typeof(obj_data.onSubmit) !== 'undefined') {
4613                                if (data[0] == '{' || data[0] == '[') {
4614                                    data = jQuery.parseJSON(data);
4615                                }
4616
4617                                if ((eval(obj_data.onSubmit)).call($this.get(0), data) === false) {
4618                                    replace_content = false;
4619                                }
4620                            }
4621
4622                            if ( ! replace_content) {
4623                                return false;
4624                            }
4625
4626                            if (typeof(obj_data.subdivisionId) == 'undefined') {
4627                                $container = $this.closest('[data-nc-ls-display-container]');
4628                            } else {
4629                                jQuery('[data-nc-ls-display-container]').each(function(){
4630                                    var $element = jQuery(this);
4631                                    var containerData = $element.attr('data-nc-ls-display-container');
4632                                    if (containerData) {
4633                                        containerData = jQuery.parseJSON(containerData);
4634                                        if (containerData.subdivisionId == obj_data.subdivisionId) {
4635                                            $container = $element;
4636                                            return false;
4637                                        }
4638                                    }
4639
4640                                    return true;
4641                                });
4642                            }
4643
4644                            if (!$container.length) {
4645                                $container = jQuery('[data-nc-ls-display-container]');
4646                            }
4647
4648                            $container.html(data);
4649
4650                            if (callBindEvents) {
4651                                bindEvents($container);
4652                            }
4653
4654                            if (typeof(parent.nc_ls_quickbar) != 'undefined') {
4655                                var quickbar = parent.nc_ls_quickbar;
4656                                if (quickbar) {
4657                                    var $quickbar = jQuery('.nc-navbar').first();
4658                                    $quickbar.find('.nc-quick-menu LI:eq(0) A').attr('href', quickbar.view_link);
4659                                    $quickbar.find('.nc-quick-menu LI:eq(1) A').attr('href', quickbar.edit_link);
4660                                    $quickbar.find('.nc-menu UL LI:eq(0) A').attr('href', quickbar.sub_admin_link);
4661                                    $quickbar.find('.nc-menu UL LI:eq(1) A').attr('href', quickbar.template_admin_link);
4662                                    $quickbar.find('.nc-menu UL LI:eq(2) A').attr('href', quickbar.admin_link);
4663                                }
4664                            }
4665                        }
4666                    });
4667
4668                } else if (obj_data.displayType == 'longpage_vertical') {
4669                    var scrolled = false;
4670
4671                    var scrollToContainer = function(containerData, $element){
4672                        if (containerData) {
4673                            containerData = jQuery.parseJSON(containerData);
4674                            if (containerData.subdivisionId == obj_data.subdivisionId) {
4675                                jQuery('HTML,BODY').animate({
4676                                    scrollTop: $element.offset().top - jQuery('BODY').offset().top
4677                                }, containerData.animationSpeed);
4678                                return true;
4679                            }
4680                        }
4681
4682                        return false;
4683                    };
4684
4685                    jQuery('[data-nc-ls-display-pointer]').each(function(){
4686                        var $element = jQuery(this);
4687                        if (scrollToContainer($element.attr('data-nc-ls-display-pointer'), $element)) {
4688                            scrolled = true;
4689                            return false;
4690                        }
4691
4692                        return true;
4693                    });
4694
4695                    if (!scrolled) {
4696                        jQuery('[data-nc-ls-display-container]').each(function(){
4697                            var $element = jQuery(this);
4698
4699                            if (scrollToContainer($element.attr('data-nc-ls-display-container'), $element)) {
4700                                return false;
4701                            }
4702
4703                            return true;
4704                        });
4705                    }
4706                }
4707
4708                if (replace_content) {
4709                    if (!!(window.history && history.pushState)) {
4710                        window.history.pushState({}, '', url);
4711                    }
4712                }
4713
4714                if (event_type === E_CLICK) {
4715                    if (typeof(obj_data.onClick) == 'undefined') {
4716                        $this.addClass('active').siblings().removeClass('active');
4717                    } else {
4718                        eval('var callback = ' + obj_data.onClick);
4719                        callback.call($this.get(0));
4720                    }
4721                }
4722
4723                return false;
4724            }
4725        }
4726
4727        jQuery('[data-nc-ls-display-link]').click(function(){
4728            eventHandler(this, true, E_CLICK);
4729            return false;
4730        });
4731
4732        jQuery('form[data-nc-ls-display-form]').submit(function(){
4733            eventHandler(this, true, E_SUBMIT);
4734            return false;
4735        });
4736
4737        jQuery('[data-nc-ls-display-pointer]').each(function(){
4738            var $this = jQuery(this);
4739            var data = jQuery.parseJSON($this.attr('data-nc-ls-display-pointer'));
4740            if (data.onReadyScroll) {
4741                setTimeout(function(){
4742                    jQuery('HTML,BODY').scrollTop($this.offset().top);
4743                }, 1000);
4744                return false;
4745            }
4746
4747            return true;
4748        });
4749    });
4750}
4751(function(jQuery) {
4752    /*
4753     * SimpleModal - jQuery Plugin
4754     * http://simplemodal.com/
4755     * Copyright (c) Eric Martin
4756     * Licensed under MIT and GPL
4757     * Date: Nov 10, 2017
4758     */
4759	(function(b){"function"===typeof define&&define.amd?define(["jquery"],b):b(jQuery)})(function(b){var j=[],n=b(document),k=navigator.userAgent.toLowerCase(),l=b(window),g=[],o=null,p=/msie/.test(k)&&!/opera/.test(k),q=/opera/.test(k),m,r,s;m=p&&/msie 6./.test(k)&&"object"!==typeof window.XMLHttpRequest;r=p&&/msie 7.0/.test(k);s="CSS1Compat"===document.compatMode;b.modal=function(a,h){return b.modal.impl.init(a,h)};b.modal.close=function(){b.modal.impl.close()};b.modal.focus=function(a){b.modal.impl.focus(a)};b.modal.setContainerDimensions=function(){b.modal.impl.setContainerDimensions()};b.modal.setPosition=function(){b.modal.impl.setPosition()};b.modal.update=function(a,h){b.modal.impl.update(a,h)};b.fn.modal=function(a){return b.modal.impl.init(this,a)};b.modal.defaults={appendTo:"body",focus:!0,opacity:50,overlayId:"simplemodal-overlay",overlayCss:{},containerId:"simplemodal-container",containerCss:{},dataId:"simplemodal-data",dataCss:{},minHeight:null,minWidth:null,maxHeight:null,maxWidth:null,autoResize:!1,autoPosition:!0,zIndex:1E3,close:!0,closeHTML:'<a class="modalCloseImg" title="Close"></a>',closeClass:"simplemodal-close",escClose:!0,overlayClose:!1,fixed:!0,position:null,persist:!1,modal:!0,onOpen:null,onShow:null,onClose:null};b.modal.impl={d:{},init:function(a,h){if(this.d.data)return!1;o=p&&!s;this.o=b.extend({},b.modal.defaults,h);this.zIndex=this.o.zIndex;this.occb=!1;if("object"===typeof a){if(a=a instanceof b?a:b(a),this.d.placeholder=!1,0<a.parent().parent().length&&(a.before(b("<span></span>").attr("id","simplemodal-placeholder").css({display:"none"})),this.d.placeholder=!0,this.display=a.css("display"),!this.o.persist))this.d.orig=a.clone(!0)}else if("string"===typeof a||"number"===typeof a)a=b("<div></div>").html(a);else return alert("SimpleModal Error: Unsupported data type: "+typeof a),this;this.create(a);this.open();b.isFunction(this.o.onShow)&&this.o.onShow.apply(this,[this.d]);return this},create:function(a){this.getDimensions();if(this.o.modal&&m)this.d.iframe=b('<iframe src="javascript:false;"></iframe>').css(b.extend(this.o.iframeCss,{display:"none",opacity:0,position:"fixed",height:g[0],width:g[1],zIndex:this.o.zIndex,top:0,left:0})).appendTo(this.o.appendTo);this.d.overlay=b("<div></div>").attr("id",this.o.overlayId).addClass("simplemodal-overlay").css(b.extend(this.o.overlayCss,{display:"none",opacity:this.o.opacity/100,height:this.o.modal?j[0]:0,width:this.o.modal?j[1]:0,position:"fixed",left:0,top:0,zIndex:this.o.zIndex+1})).appendTo(this.o.appendTo);this.d.container=b("<div></div>").attr("id",this.o.containerId).attr("role","dialog").addClass("simplemodal-container").css(b.extend({position:this.o.fixed?"fixed":"absolute"},this.o.containerCss,{display:"none",zIndex:this.o.zIndex+2})).append(this.o.close&&this.o.closeHTML?b(this.o.closeHTML).addClass(this.o.closeClass):"").appendTo(this.o.appendTo);this.d.wrap=b("<div></div>").attr("tabIndex",-1).addClass("simplemodal-wrap").css({height:"100%",outline:0,width:"100%"}).appendTo(this.d.container);this.d.data=a.attr("id",a.attr("id")||this.o.dataId).addClass("simplemodal-data").css(b.extend(this.o.dataCss,{display:"none"})).appendTo("body");this.setContainerDimensions();this.d.data.appendTo(this.d.wrap);(m||o)&&this.fixIE()},bindEvents:function(){var a=this;b("."+a.o.closeClass).bind("click.simplemodal",function(b){b.preventDefault();a.close()});a.o.modal&&a.o.close&&a.o.overlayClose&&a.d.overlay.bind("click.simplemodal",function(b){b.preventDefault();a.close()});n.bind("keydown.simplemodal",function(b){a.o.modal&&9===b.keyCode?a.watchTab(b):a.o.close&&a.o.escClose&&27===b.keyCode&&(b.preventDefault(),a.close())});l.bind("resize.simplemodal orientationchange.simplemodal",function(){a.getDimensions();a.o.autoResize?a.setContainerDimensions():a.o.autoPosition&&a.setPosition();m||o?a.fixIE():a.o.modal&&(a.d.iframe&&a.d.iframe.css({height:g[0],width:g[1]}),a.d.overlay.css({height:j[0],width:j[1]}))})},unbindEvents:function(){b("."+this.o.closeClass).unbind("click.simplemodal");
4759n.unbind("keydown.simplemodal");l.unbind(".simplemodal");this.d.overlay.unbind("click.simplemodal")},fixIE:function(){var a=this.o.position;b.each([this.d.iframe||null,!this.o.modal?null:this.d.overlay,"fixed"===this.d.container.css("position")?this.d.container:null],function(b,e){if(e){var f=e[0].style;f.position="absolute";if(2>b)f.removeExpression("height"),f.removeExpression("width"),f.setExpression("height",'document.body.scrollHeight > document.body.clientHeight ? document.body.scrollHeight : document.body.clientHeight + "px"'),f.setExpression("width",'document.body.scrollWidth > document.body.clientWidth ? document.body.scrollWidth : document.body.clientWidth + "px"');else{var c,d;a&&a.constructor===Array?(c=a[0]?"number"===typeof a[0]?a[0].toString():a[0].replace(/px/,""):e.css("top").replace(/px/,""),c=-1===c.indexOf("%")?c+' + (t = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"':parseInt(c.replace(/%/,""))+' * ((document.documentElement.clientHeight || document.body.clientHeight) / 100) + (t = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"',a[1]&&(d="number"===typeof a[1]?a[1].toString():a[1].replace(/px/,""),d=-1===d.indexOf("%")?d+' + (t = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft) + "px"':parseInt(d.replace(/%/,""))+' * ((document.documentElement.clientWidth || document.body.clientWidth) / 100) + (t = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft) + "px"')):(c='(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (t = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"',d='(document.documentElement.clientWidth || document.body.clientWidth) / 2 - (this.offsetWidth / 2) + (t = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft) + "px"');f.removeExpression("top");f.removeExpression("left");f.setExpression("top",c);f.setExpression("left",d)}}})},focus:function(a){var h=this,a=a&&-1!==b.inArray(a,["first","last"])?a:"first",e=b(":input:enabled:visible:"+a,h.d.wrap);setTimeout(function(){0<e.length?e.focus():h.d.wrap.focus()},10)},getDimensions:function(){var a="undefined"===typeof window.innerHeight?l.height():window.innerHeight;j=[n.height(),n.width()];g=[a,l.width()]},getVal:function(a,b){return a?"number"===typeof a?a:"auto"===a?0:0<a.indexOf("%")?parseInt(a.replace(/%/,""))/100*("h"===b?g[0]:g[1]):parseInt(a.replace(/px/,"")):null},update:function(a,b){if(!this.d.data)return!1;this.d.origHeight=this.getVal(a,"h");this.d.origWidth=this.getVal(b,"w");this.d.data.hide();a&&this.d.container.css("height",a);b&&this.d.container.css("width",b);this.setContainerDimensions();this.d.data.show();this.o.focus&&this.focus();this.unbindEvents();this.bindEvents()},setContainerDimensions:function(){var a=m||r,b=this.d.origHeight?this.d.origHeight:q?this.d.container.height():this.getVal(a?this.d.container[0].currentStyle.height:this.d.container.css("height"),"h"),a=this.d.origWidth?this.d.origWidth:q?this.d.container.width():this.getVal(a?this.d.container[0].currentStyle.width:this.d.container.css("width"),"w"),e=this.d.data.outerHeight(!0),f=this.d.data.outerWidth(!0);this.d.origHeight=this.d.origHeight||b;this.d.origWidth=this.d.origWidth||a;var c=this.o.maxHeight?this.getVal(this.o.maxHeight,"h"):null,d=this.o.maxWidth?this.getVal(this.o.maxWidth,"w"):null,c=c&&c<g[0]?c:g[0],d=d&&d<g[1]?d:g[1],i=this.o.minHeight?this.getVal(this.o.minHeight,"h"):"auto",b=b?this.o.autoResize&&b>c?c:b<i?i:b:e?e>c?c:this.o.minHeight&&"auto"!==i&&e<i?i:e:i,c=this.o.minWidth?this.getVal(this.o.minWidth,"w"):"auto",a=a?this.o.autoResize&&a>d?d:a<c?c:a:f?f>d?d:this.o.minWidth&&"auto"!==c&&f<c?c:f:c;this.d.container.css({height:b,width:a});this.d.wrap.css({overflow:e>b||f>a?"auto":"visible"});this.o.autoPosition&&this.setPosition()},setPosition:function(){var a,b;a=g[0]/2-this.d.container.outerHeight(!0)/2;b=g[1]/2-this.d.container.outerWidth(!0)/2;var e="fixed"!==this.d.container.css("position")?l.scrollTop():0;this.o.position&&"[object Array]"===Object.prototype.toString.call(this.o.position)?(a=parseFloat(e)+parseFloat(this.o.position[0]||a),b=this.o.position[1]||b):a=e+a;this.d.container.css({left:b,top:a})}
4759,watchTab:function(a){if(0<b(a.target).parents(".simplemodal-container").length){if(this.inputs=b(":input:enabled:visible:first, :input:enabled:visible:last",this.d.data[0]),!a.shiftKey&&a.target===this.inputs[this.inputs.length-1]||a.shiftKey&&a.target===this.inputs[0]||0===this.inputs.length)a.preventDefault(),this.focus(a.shiftKey?"last":"first")}else a.preventDefault(),this.focus()},open:function(){this.d.iframe&&this.d.iframe.show();b.isFunction(this.o.onOpen)?this.o.onOpen.apply(this,[this.d]):(this.d.overlay.show(),this.d.container.show(),this.d.data.show());this.o.focus&&this.focus();this.bindEvents()},close:function(){if(!this.d.data)return!1;this.unbindEvents();if(b.isFunction(this.o.onClose)&&!this.occb)this.occb=!0,this.o.onClose.apply(this,[this.d]);else{if(this.d.placeholder){var a=b("#simplemodal-placeholder");this.o.persist?a.replaceWith(this.d.data.removeClass("simplemodal-data").css("display",this.display)):(this.d.data.hide().remove(),a.replaceWith(this.d.orig))}else this.d.data.hide().remove();this.d.container.hide().remove();this.d.overlay.hide();this.d.iframe&&this.d.iframe.hide().remove();this.d.overlay.remove();this.d={}}}}});
4760
4761    // Netcat modifications
4762    jQuery.modal.defaults.overlayClose = false;
4763    jQuery.modal.defaults.escClose = false;
4764    jQuery.modal.nc_confirm_close = true; // проверять изменения в форме перед закрытием диалога
4765    jQuery.modal.nc_modal_confirm = false; // есть изменения в форме
4766    jQuery.modal.confirmed = false; // изменения подтверждены пользователем
4767
4768    jQuery.modal.onCloseCheck = function(){
4769        var message = typeof TEXT_SAVE != 'undefined' ? TEXT_SAVE : 'Выйти без сохранения?';
4770        var confirmed_result = false;
4771        var should_ask = this.nc_confirm_close && this.nc_modal_confirm;
4772
4773        if (should_ask && jQuery.modal.confirmed === false) {
4774            confirmed_result = confirm(message);
4775        }
4776
4777        if (should_ask && !confirmed_result) {
4778            jQuery.modal.confirmed = false;
4779            return false;
4780        } else {
4781            this.nc_modal_confirm = false;
4782            jQuery.modal.confirmed = true;
4783            return true;
4784        }
4785    };
4786
4787    jQuery.modal.isOpen = function () {
4788        return jQuery('.simplemodal-container:visible').length > 0;
4789    }
4790
4791    // fix escape in focused fields
4792    jQuery.modal.defaults.onOpen = function (m) {
4793        m.overlay.show();
4794        m.container.show();
4795        m.data.show();
4796
4797        jQuery.modal.nc_confirm_close = (this.o.nc_confirm_close !== undefined ? this.o.nc_confirm_close : true);
4798        jQuery.modal.nc_modal_confirm = false;
4799        jQuery.modal.confirmed = false;
4800
4801        /*
4802        m.overlay.click(function(){
4803            jQuery.modal.onCloseCheck();
4804        });
4805        */
4806
4807        var jQ = window.jQuery && window.jQuery.modal ? 'jQuery' : '$nc';
4808        m.container.find(':input').each(function(){
4809            var self = jQuery(this);
4810            // self.change() - doesn't work in some cases
4811            self.attr('onchange', jQ + '.modal.nc_modal_confirm=true;' + self.attr('onchange') || '');
4812        });
4813        
4814        if (typeof CKEDITOR !== 'undefined') {
4815            for (var i in CKEDITOR.instances) {
4816                CKEDITOR.instances[i].on('change', function() {
4817                    jQuery.modal.nc_modal_confirm=true;
4818                });
4819            }
4820        }
4821
4822        m.container.keydown(function(e) {
4823            if (e.keyCode == 27 /*esc*/) {
4824                // unfocus to call change() if needed
4825                if (jQuery(e.target).is(':input')) {
4826                    jQuery(e.target).blur();
4827                }
4828                var check_result = jQuery.modal.onCloseCheck();
4829                if (check_result === false) {
4830                    return;
4831                } else {
4832                    jQuery.modal.close();
4833                    this.nc_modal_confirm = false;
4834                }
4835            }
4836        });
4837    }
4838})($nc || jQuery);
4839
4840/*
4841 TableDnD plug-in for JQuery
4842 https://github.com/isocra/TableDnD/
4843 Copyright (c) Denis Howlett <[email protected]>
4844 Licensed like jQuery, see http://docs.jquery.com/License.
4845 Fork: https://github.com/k-x/TableDnD/
4846*/
4847(function(a,j,f,s){var n="ontouchstart"in f.documentElement,o=n?"touchstart":"mousedown",p=n?"touchmove":"mousemove",q=n?"touchend":"mouseup";n&&a.each("touchstart touchmove touchend".split(" "),function(b,c){a.event.fixHooks[c]=a.event.mouseHooks});a(f).ready(function(){function b(b){for(var a={},b=b.match(/([^;:]+)/g)||[];b.length;)a[b.shift()]=b.shift().trim();return a}a("table").each(function(){"dnd"==a(this).data("table")&&a(this).tableDnD({onDragStyle:a(this).data("ondragstyle")&&b(a(this).data("ondragstyle"))||
4848null,onDropStyle:a(this).data("ondropstyle")&&b(a(this).data("ondropstyle"))||null,onDragClass:a(this).data("ondragclass")==s&&"tDnD_whileDrag"||a(this).data("ondragclass"),onDrop:a(this).data("ondrop")&&new Function("table","row",a(this).data("ondrop")),onDragStart:a(this).data("ondragstart")&&new Function("table","row",a(this).data("ondragstart")),scrollAmount:a(this).data("scrollamount")||5,sensitivity:a(this).data("sensitivity")||10,hierarchyLevel:a(this).data("hierarchylevel")||0,indentArtifact:a(this).data("indentartifact")||
4849'<div class="indent">&nbsp;</div>',autoWidthAdjust:a(this).data("autowidthadjust")||!0,autoCleanRelations:a(this).data("autocleanrelations")||!0,jsonPretifySeparator:a(this).data("jsonpretifyseparator")||"\t",serializeRegexp:a(this).data("serializeregexp")&&RegExp(a(this).data("serializeregexp"))||/[^\-]*$/,serializeParamName:a(this).data("serializeparamname")||!1,dragHandle:a(this).data("draghandle")||null})})});j.jQuery.tableDnD={currentTable:null,dragObject:null,mouseOffset:null,oldX:0,oldY:0,
4850build:function(b){this.each(function(){this.tableDnDConfig=a.extend({onDragStyle:null,onDropStyle:null,onDrag
4850Class:"tDnD_whileDrag",onDrop:null,onDragStart:null,scrollAmount:5,sensitivity:10,hierarchyLevel:0,indentArtifact:'<div class="indent">&nbsp;</div>',autoWidthAdjust:!0,autoCleanRelations:!0,jsonPretifySeparator:"\t",serializeRegexp:/[^\-]*$/,serializeParamName:!1,dragHandle:null},b||{});a.tableDnD.makeDraggable(this);this.tableDnDConfig.hierarchyLevel&&a.tableDnD.makeIndented(this)});return this},
4851makeIndented:function(b){var c=b.tableDnDConfig,d=b.rows,e=a(d).first().find("td:first")[0],h=0,r=0,f,i;if(a(b).hasClass("indtd"))return null;i=a(b).addClass("indtd").attr("style");a(b).css({whiteSpace:"nowrap"});for(var g=0;g<d.length;g++)if(r<a(d[g]).find("td:first").text().length)r=a(d[g]).find("td:first").text().length,f=g;a(e).css({width:"auto"});for(g=0;g<c.hierarchyLevel;g++)a(d[f]).find("td:first").prepend(c.indentArtifact);e&&a(e).css({width:e.offsetWidth});i&&a(b).css(i);for(g=0;g<c.hierarchyLevel;g++)a(d[f]).find("td:first").children(":first").remove();
4852c.hierarchyLevel&&a(d).each(function(){h=a(this).data("level")||0;h<=c.hierarchyLevel&&a(this).data("level",h)||a(this).data("level",0);for(var b=0;b<a(this).data("level");b++)a(this).find("td:first").prepend(c.indentArtifact)});return this},makeDraggable:function(b){var c=b.tableDnDConfig;c.dragHandle&&a(c.dragHandle,b).each(function(){a(this).bind(o,function(d){a.tableDnD.initialiseDrag(a(this).parents("tr")[0],b,this,d,c);return!1})})||a(b.rows).each(function(){a(this).hasClass("nodrag")||a(this).bind(o,
4853function(d){if("TD"==d.target.tagName)return a.tableDnD.initialiseDrag(this,b,this,d,c),!1}).css("cursor","move")})},currentOrder:function(){return a.map(this.currentTable.rows,function(b){return(a(b).data("level")+b.id).replace(/\s/g,"")}).join("")},initialiseDrag:function(b,c,d,e,h){this.dragObject=b;this.currentTable=c;this.mouseOffset=this.getMouseOffset(d,e);this.originalOrder=this.currentOrder();a(f).bind(p,this.mousemove).bind(q,this.mouseup);h.onDragStart&&h.onDragStart(c,d)},updateTables:function(){this.each(function(){this.tableDnDConfig&&
4854a.tableDnD.makeDraggable(this)})},mouseCoords:function(b){return b.pageX||b.pageY?{x:b.pageX,y:b.pageY}:{x:b.clientX+f.body.scrollLeft-f.body.clientLeft,y:b.clientY+f.body.scrollTop-f.body.clientTop}},getMouseOffset:function(b,a){var d,e,a=a||j.event;e=this.getPosition(b);d=this.mouseCoords(a);return{x:d.x-e.x,y:d.y-e.y}},getPosition:function(b){var a=0,d=0;if(0==b.offsetHeight)b=b.firstChild;for(;b.offsetParent;)a+=b.offsetLeft,d+=b.offsetTop,b=b.offsetParent;a+=b.offsetLeft;d+=b.offsetTop;return{x:a,
4855y:d}},autoScroll:function(a){var c=this.currentTable.tableDnDConfig,d=j.pageYOffset,e=j.innerHeight?j.innerHeight:f.documentElement.clientHeight?f.documentElement.clientHeight:f.body.clientHeight;if(f.all)if("undefined"!=typeof f.compatMode&&"BackCompat"!=f.compatMode)d=f.documentElement.scrollTop;else if("undefined"!=typeof f.body)d=f.body.scrollTop;a.y-d<c.scrollAmount&&j.scrollBy(0,-c.scrollAmount)||e-(a.y-d)<c.scrollAmount&&j.scrollBy(0,c.scrollAmount)},moveVerticle:function(a,c){0!=a.vertical&&
4856c&&this.dragObject!=c&&this.dragObject.parentNode==c.parentNode&&(0>a.vertical&&this.dragObject.parentNode.insertBefore(this.dragObject,c.nextSibling)||0<a.vertical&&this.dragObject.parentNode.insertBefore(this.dragObject,c))},moveHorizontal:function(b,c){var d=this.currentTable.tableDnDConfig,e;if(!d.hierarchyLevel||0==b.horizontal||!c||this.dragObject!=c)return null;e=a(c).data("level");0<b.horizontal&&0<e&&a(c).find("td:first").children(":first").remove()&&a(c).data("level",--e);0>b.horizontal&&
4857e<d.hierarchyLevel&&a(c).prev().data("level")>=e&&a(c).children(":first").prepend(d.indentArtifact)&&a(c).data("level",++e)},mousemove:function(b){var c=a(a.tableDnD.dragObject),d=a.tableDnD.currentTable.tableDnDConfig,e;b&&b.preventDefault();if(!a.tableDnD.dragObject)return!1;"touchmove"==b.type&&event.preventDefault();d.onDragClass&&c.addClass(d.onDragClass)||c.css(d.onDragStyle);e=a.tableDnD.mouseCoords(b);b=e.x-a.tableDnD.mouseOffset.x;d=e.y-a.tableDnD.mouseOffset.y;a.tableDnD.autoScroll(e);c=
4858a.tableDnD.findDropTargetRow(c,d);b=a.tableDnD.findDragDirection(b,d);a.tableDnD.moveVerticle(b,c);a.tableDnD.moveHorizontal(b,c);return!1},findDragDirection:function(a,c){var d=this.currentTable.tableDnDConfig.sensitivity,e=this.oldX,h=this.oldY,d={horizontal:a>=e-d&&a<=e+d?0:a>e?-1:1,vertical:c>=h-d&&c<=h+d?0:c>h?-1:1};if(0!=d.horizontal)this.oldX=a;if(0!=d.vertical)this.oldY=c;return d},findDropTargetRow:function(b,c){for(var d=0,e=this.currentTable.rows,h=this.currentTable.tableDnDConfig,f=0,
4859k=null,i=0;i<e.length;i++){k=e[i];f=this.getPosition(k).y;d=parseInt(k.offsetHeight)/2;if(0==k.offsetHeight)f=this.getPosition(k.firstChild).y,d=parseInt(k.firstChild.offsetHeight)/2;if(c>f-d&&c<f+d)if(k==b||h.onAllowDrop&&!h.onAllowDrop(b,k)||a(k).hasClass("nodrop"))break;else return k}return null},processMouseup:function(){var b=this.currentTable.tableDnDConfig,c=this.dragObject,d=0,e=0;if(!this.currentTable||!c)return null;a(f).unbind(p,this.mousemove).unbind(q,this.mouseup);b.hierarchyLevel&&
4860b.autoCleanRelations&&a(this.currentTable.rows).first().find("td:first").children().each(function(){(e=a(this).parents("tr:first").data("level"))&&a(this).parents("tr:first").data("level",--e)&&a(this).remove()})&&1<b.hierarchyLevel&&a(this.currentTable.rows).each(function(){e=a(this).data("level");if(1<e)for(d=a(this).prev().data("level");e>d+1;)a(this).find("td:first").children(":first").remove(),a(this).data("level",--e)});
4860b.onDragClass&&a(c).removeClass(b.onDragClass)||a(c).css(b.onDropStyle);
4861this.dragObject=null;b.onDrop&&this.originalOrder!=this.currentOrder()&&b.onDrop(this.currentTable,c);this.currentTable=null},mouseup:function(b){b&&b.preventDefault();a.tableDnD.processMouseup();return!1},jsonize:function(a){var c=this.currentTable;return a?JSON.stringify(this.tableData(c),null,c.tableDnDConfig.jsonPretifySeparator):JSON.stringify(this.tableData(c))},serialize:function(){return a.param(this.tableData(this.currentTable))},serializeTable:function(a){for(var c="",d=a.tableDnDConfig.serializeParamName||
4862a.id,e=a.rows,h=0;h<e.length;h++){0<c.length&&(c+="&");var f=e[h].id;f&&a.tableDnDConfig&&a.tableDnDConfig.serializeRegexp&&(f=f.match(a.tableDnDConfig.serializeRegexp)[0],c+=d+"[]="+f)}return c},serializeTables:function(){var b=[];a("table").each(function(){this.id&&b.push(a.param(this.tableData(this)))});return b.join("&")},tableData:function(b){var c=b.tableDnDConfig,d=[],e=0,f=0,f=null,j={},k,i,g;if(!b)b=this.currentTable;if(!b||!b.id||!b.rows||!b.rows.length)return{error:{code:500,message:"Not a valid table, no serializable unique id provided."}};
4863g=c.autoCleanRelations&&b.rows||a.makeArray(b.rows);i=k=c.serializeParamName||b.id;b=function(a){return a&&c&&c.serializeRegexp?a.match(c.serializeRegexp)[0]:a};j[i]=[];!c.autoCleanRelations&&a(g[0]).data("level")&&g.unshift({id:"undefined"});for(var m=0;m<g.length;m++){if(c.hierarchyLevel){f=a(g[m]).data("level")||0;if(0==f)i=k,d=[];else if(f>e)d.push([i,e]),i=b(g[m-1].id);else if(f<e)for(var l=0;l<d.length;l++)d[l][1]==f&&(i=d[l][0]),d[l][1]>=e&&(d[l][1]=0);e=f;a.isArray(j[i])||(j[i]=[])}(f=b(g[m].id))&&
4864j[i].push(f)}return j}};j.jQuery.fn.extend({tableDnD:a.tableDnD.build,tableDnDUpdate:a.tableDnD.updateTables,tableDnDSerialize:a.proxy(a.tableDnD.serialize,a.tableDnD),tableDnDSerializeAll:a.tableDnD.serializeTables,tableDnDData:a.proxy(a.tableDnD.tableData,a.tableDnD)})})(window.jQuery,window,window.document);
4865

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.