OpenShot Video Editor  2.0.0
jquery-ui.js
Go to the documentation of this file.
1 /*! jQuery UI - v1.11.2 - 2015-02-08
2 * http://jqueryui.com
3 * Includes: core.js, widget.js, mouse.js, position.js, draggable.js, droppable.js, resizable.js, selectable.js, sortable.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, menu.js, progressbar.js, selectmenu.js, slider.js, spinner.js, tabs.js, tooltip.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js
4 * Copyright 2015 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  } else {
12 
13  // Browser globals
14  factory( jQuery );
15  }
16 }(function( $ ) {
17 /*!
18  * jQuery UI Core 1.11.2
19  * http://jqueryui.com
20  *
21  * Copyright 2014 jQuery Foundation and other contributors
22  * Released under the MIT license.
23  * http://jquery.org/license
24  *
25  * http://api.jqueryui.com/category/ui-core/
26  */
27 
28 
29 // $.ui might exist from components with no dependencies, e.g., $.ui.position
30 $.ui = $.ui || {};
31 
32 $.extend( $.ui, {
33  version: "1.11.2",
34 
35  keyCode: {
36  BACKSPACE: 8,
37  COMMA: 188,
38  DELETE: 46,
39  DOWN: 40,
40  END: 35,
41  ENTER: 13,
42  ESCAPE: 27,
43  HOME: 36,
44  LEFT: 37,
45  PAGE_DOWN: 34,
46  PAGE_UP: 33,
47  PERIOD: 190,
48  RIGHT: 39,
49  SPACE: 32,
50  TAB: 9,
51  UP: 38
52  }
53 });
54 
55 // plugins
56 $.fn.extend({
57  scrollParent: function( includeHidden ) {
58  var position = this.css( "position" ),
59  excludeStaticParent = position === "absolute",
60  overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
61  scrollParent = this.parents().filter( function() {
62  var parent = $( this );
63  if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
64  return false;
65  }
66  return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
67  }).eq( 0 );
68 
69  return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
70  },
71 
72  uniqueId: (function() {
73  var uuid = 0;
74 
75  return function() {
76  return this.each(function() {
77  if ( !this.id ) {
78  this.id = "ui-id-" + ( ++uuid );
79  }
80  });
81  };
82  })(),
83 
84  removeUniqueId: function() {
85  return this.each(function() {
86  if ( /^ui-id-\d+$/.test( this.id ) ) {
87  $( this ).removeAttr( "id" );
88  }
89  });
90  }
91 });
92 
93 // selectors
94 function focusable( element, isTabIndexNotNaN ) {
95  var map, mapName, img,
96  nodeName = element.nodeName.toLowerCase();
97  if ( "area" === nodeName ) {
98  map = element.parentNode;
99  mapName = map.name;
100  if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
101  return false;
102  }
103  img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
104  return !!img && visible( img );
105  }
106  return ( /input|select|textarea|button|object/.test( nodeName ) ?
107  !element.disabled :
108  "a" === nodeName ?
109  element.href || isTabIndexNotNaN :
110  isTabIndexNotNaN) &&
111  // the element and all of its ancestors must be visible
112  visible( element );
113 }
114 
115 function visible( element ) {
116  return $.expr.filters.visible( element ) &&
117  !$( element ).parents().addBack().filter(function() {
118  return $.css( this, "visibility" ) === "hidden";
119  }).length;
120 }
121 
122 $.extend( $.expr[ ":" ], {
123  data: $.expr.createPseudo ?
124  $.expr.createPseudo(function( dataName ) {
125  return function( elem ) {
126  return !!$.data( elem, dataName );
127  };
128  }) :
129  // support: jQuery <1.8
130  function( elem, i, match ) {
131  return !!$.data( elem, match[ 3 ] );
132  },
133 
134  focusable: function( element ) {
135  return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
136  },
137 
138  tabbable: function( element ) {
139  var tabIndex = $.attr( element, "tabindex" ),
140  isTabIndexNaN = isNaN( tabIndex );
141  return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
142  }
143 });
144 
145 // support: jQuery <1.8
146 if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
147  $.each( [ "Width", "Height" ], function( i, name ) {
148  var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
149  type = name.toLowerCase(),
150  orig = {
151  innerWidth: $.fn.innerWidth,
152  innerHeight: $.fn.innerHeight,
153  outerWidth: $.fn.outerWidth,
154  outerHeight: $.fn.outerHeight
155  };
156 
157  function reduce( elem, size, border, margin ) {
158  $.each( side, function() {
159  size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
160  if ( border ) {
161  size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
162  }
163  if ( margin ) {
164  size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
165  }
166  });
167  return size;
168  }
169 
170  $.fn[ "inner" + name ] = function( size ) {
171  if ( size === undefined ) {
172  return orig[ "inner" + name ].call( this );
173  }
174 
175  return this.each(function() {
176  $( this ).css( type, reduce( this, size ) + "px" );
177  });
178  };
179 
180  $.fn[ "outer" + name] = function( size, margin ) {
181  if ( typeof size !== "number" ) {
182  return orig[ "outer" + name ].call( this, size );
183  }
184 
185  return this.each(function() {
186  $( this).css( type, reduce( this, size, true, margin ) + "px" );
187  });
188  };
189  });
190 }
191 
192 // support: jQuery <1.8
193 if ( !$.fn.addBack ) {
194  $.fn.addBack = function( selector ) {
195  return this.add( selector == null ?
196  this.prevObject : this.prevObject.filter( selector )
197  );
198  };
199 }
200 
201 // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
202 if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
203  $.fn.removeData = (function( removeData ) {
204  return function( key ) {
205  if ( arguments.length ) {
206  return removeData.call( this, $.camelCase( key ) );
207  } else {
208  return removeData.call( this );
209  }
210  };
211  })( $.fn.removeData );
212 }
213 
214 // deprecated
215 $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
216 
217 $.fn.extend({
218  focus: (function( orig ) {
219  return function( delay, fn ) {
220  return typeof delay === "number" ?
221  this.each(function() {
222  var elem = this;
223  setTimeout(function() {
224  $( elem ).focus();
225  if ( fn ) {
226  fn.call( elem );
227  }
228  }, delay );
229  }) :
230  orig.apply( this, arguments );
231  };
232  })( $.fn.focus ),
233 
234  disableSelection: (function() {
235  var eventType = "onselectstart" in document.createElement( "div" ) ?
236  "selectstart" :
237  "mousedown";
238 
239  return function() {
240  return this.bind( eventType + ".ui-disableSelection", function( event ) {
241  event.preventDefault();
242  });
243  };
244  })(),
245 
246  enableSelection: function() {
247  return this.unbind( ".ui-disableSelection" );
248  },
249 
250  zIndex: function( zIndex ) {
251  if ( zIndex !== undefined ) {
252  return this.css( "zIndex", zIndex );
253  }
254 
255  if ( this.length ) {
256  var elem = $( this[ 0 ] ), position, value;
257  while ( elem.length && elem[ 0 ] !== document ) {
258  // Ignore z-index if position is set to a value where z-index is ignored by the browser
259  // This makes behavior of this function consistent across browsers
260  // WebKit always returns auto if the element is positioned
261  position = elem.css( "position" );
262  if ( position === "absolute" || position === "relative" || position === "fixed" ) {
263  // IE returns 0 when zIndex is not specified
264  // other browsers return a string
265  // we ignore the case of nested elements with an explicit value of 0
266  // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
267  value = parseInt( elem.css( "zIndex" ), 10 );
268  if ( !isNaN( value ) && value !== 0 ) {
269  return value;
270  }
271  }
272  elem = elem.parent();
273  }
274  }
275 
276  return 0;
277  }
278 });
279 
280 // $.ui.plugin is deprecated. Use $.widget() extensions instead.
281 $.ui.plugin = {
282  add: function( module, option, set ) {
283  var i,
284  proto = $.ui[ module ].prototype;
285  for ( i in set ) {
286  proto.plugins[ i ] = proto.plugins[ i ] || [];
287  proto.plugins[ i ].push( [ option, set[ i ] ] );
288  }
289  },
290  call: function( instance, name, args, allowDisconnected ) {
291  var i,
292  set = instance.plugins[ name ];
293 
294  if ( !set ) {
295  return;
296  }
297 
298  if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
299  return;
300  }
301 
302  for ( i = 0; i < set.length; i++ ) {
303  if ( instance.options[ set[ i ][ 0 ] ] ) {
304  set[ i ][ 1 ].apply( instance.element, args );
305  }
306  }
307  }
308 };
309 
310 
311 /*!
312  * jQuery UI Widget 1.11.2
313  * http://jqueryui.com
314  *
315  * Copyright 2014 jQuery Foundation and other contributors
316  * Released under the MIT license.
317  * http://jquery.org/license
318  *
319  * http://api.jqueryui.com/jQuery.widget/
320  */
321 
322 
323 var widget_uuid = 0,
324  widget_slice = Array.prototype.slice;
325 
326 $.cleanData = (function( orig ) {
327  return function( elems ) {
328  var events, elem, i;
329  for ( i = 0; (elem = elems[i]) != null; i++ ) {
330  try {
331 
332  // Only trigger remove when necessary to save time
333  events = $._data( elem, "events" );
334  if ( events && events.remove ) {
335  $( elem ).triggerHandler( "remove" );
336  }
337 
338  // http://bugs.jquery.com/ticket/8235
339  } catch ( e ) {}
340  }
341  orig( elems );
342  };
343 })( $.cleanData );
344 
345 $.widget = function( name, base, prototype ) {
346  var fullName, existingConstructor, constructor, basePrototype,
347  // proxiedPrototype allows the provided prototype to remain unmodified
348  // so that it can be used as a mixin for multiple widgets (#8876)
349  proxiedPrototype = {},
350  namespace = name.split( "." )[ 0 ];
351 
352  name = name.split( "." )[ 1 ];
353  fullName = namespace + "-" + name;
354 
355  if ( !prototype ) {
356  prototype = base;
357  base = $.Widget;
358  }
359 
360  // create selector for plugin
361  $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
362  return !!$.data( elem, fullName );
363  };
364 
365  $[ namespace ] = $[ namespace ] || {};
366  existingConstructor = $[ namespace ][ name ];
367  constructor = $[ namespace ][ name ] = function( options, element ) {
368  // allow instantiation without "new" keyword
369  if ( !this._createWidget ) {
370  return new constructor( options, element );
371  }
372 
373  // allow instantiation without initializing for simple inheritance
374  // must use "new" keyword (the code above always passes args)
375  if ( arguments.length ) {
376  this._createWidget( options, element );
377  }
378  };
379  // extend with the existing constructor to carry over any static properties
380  $.extend( constructor, existingConstructor, {
381  version: prototype.version,
382  // copy the object used to create the prototype in case we need to
383  // redefine the widget later
384  _proto: $.extend( {}, prototype ),
385  // track widgets that inherit from this widget in case this widget is
386  // redefined after a widget inherits from it
387  _childConstructors: []
388  });
389 
390  basePrototype = new base();
391  // we need to make the options hash a property directly on the new instance
392  // otherwise we'll modify the options hash on the prototype that we're
393  // inheriting from
394  basePrototype.options = $.widget.extend( {}, basePrototype.options );
395  $.each( prototype, function( prop, value ) {
396  if ( !$.isFunction( value ) ) {
397  proxiedPrototype[ prop ] = value;
398  return;
399  }
400  proxiedPrototype[ prop ] = (function() {
401  var _super = function() {
402  return base.prototype[ prop ].apply( this, arguments );
403  },
404  _superApply = function( args ) {
405  return base.prototype[ prop ].apply( this, args );
406  };
407  return function() {
408  var __super = this._super,
409  __superApply = this._superApply,
410  returnValue;
411 
412  this._super = _super;
413  this._superApply = _superApply;
414 
415  returnValue = value.apply( this, arguments );
416 
417  this._super = __super;
418  this._superApply = __superApply;
419 
420  return returnValue;
421  };
422  })();
423  });
424  constructor.prototype = $.widget.extend( basePrototype, {
425  // TODO: remove support for widgetEventPrefix
426  // always use the name + a colon as the prefix, e.g., draggable:start
427  // don't prefix for widgets that aren't DOM-based
428  widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
429  }, proxiedPrototype, {
430  constructor: constructor,
431  namespace: namespace,
432  widgetName: name,
433  widgetFullName: fullName
434  });
435 
436  // If this widget is being redefined then we need to find all widgets that
437  // are inheriting from it and redefine all of them so that they inherit from
438  // the new version of this widget. We're essentially trying to replace one
439  // level in the prototype chain.
440  if ( existingConstructor ) {
441  $.each( existingConstructor._childConstructors, function( i, child ) {
442  var childPrototype = child.prototype;
443 
444  // redefine the child widget using the same prototype that was
445  // originally used, but inherit from the new version of the base
446  $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
447  });
448  // remove the list of existing child constructors from the old constructor
449  // so the old child constructors can be garbage collected
450  delete existingConstructor._childConstructors;
451  } else {
452  base._childConstructors.push( constructor );
453  }
454 
455  $.widget.bridge( name, constructor );
456 
457  return constructor;
458 };
459 
460 $.widget.extend = function( target ) {
461  var input = widget_slice.call( arguments, 1 ),
462  inputIndex = 0,
463  inputLength = input.length,
464  key,
465  value;
466  for ( ; inputIndex < inputLength; inputIndex++ ) {
467  for ( key in input[ inputIndex ] ) {
468  value = input[ inputIndex ][ key ];
469  if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
470  // Clone objects
471  if ( $.isPlainObject( value ) ) {
472  target[ key ] = $.isPlainObject( target[ key ] ) ?
473  $.widget.extend( {}, target[ key ], value ) :
474  // Don't extend strings, arrays, etc. with objects
475  $.widget.extend( {}, value );
476  // Copy everything else by reference
477  } else {
478  target[ key ] = value;
479  }
480  }
481  }
482  }
483  return target;
484 };
485 
486 $.widget.bridge = function( name, object ) {
487  var fullName = object.prototype.widgetFullName || name;
488  $.fn[ name ] = function( options ) {
489  var isMethodCall = typeof options === "string",
490  args = widget_slice.call( arguments, 1 ),
491  returnValue = this;
492 
493  // allow multiple hashes to be passed on init
494  options = !isMethodCall && args.length ?
495  $.widget.extend.apply( null, [ options ].concat(args) ) :
496  options;
497 
498  if ( isMethodCall ) {
499  this.each(function() {
500  var methodValue,
501  instance = $.data( this, fullName );
502  if ( options === "instance" ) {
503  returnValue = instance;
504  return false;
505  }
506  if ( !instance ) {
507  return $.error( "cannot call methods on " + name + " prior to initialization; " +
508  "attempted to call method '" + options + "'" );
509  }
510  if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
511  return $.error( "no such method '" + options + "' for " + name + " widget instance" );
512  }
513  methodValue = instance[ options ].apply( instance, args );
514  if ( methodValue !== instance && methodValue !== undefined ) {
515  returnValue = methodValue && methodValue.jquery ?
516  returnValue.pushStack( methodValue.get() ) :
517  methodValue;
518  return false;
519  }
520  });
521  } else {
522  this.each(function() {
523  var instance = $.data( this, fullName );
524  if ( instance ) {
525  instance.option( options || {} );
526  if ( instance._init ) {
527  instance._init();
528  }
529  } else {
530  $.data( this, fullName, new object( options, this ) );
531  }
532  });
533  }
534 
535  return returnValue;
536  };
537 };
538 
539 $.Widget = function( /* options, element */ ) {};
540 $.Widget._childConstructors = [];
541 
542 $.Widget.prototype = {
543  widgetName: "widget",
544  widgetEventPrefix: "",
545  defaultElement: "<div>",
546  options: {
547  disabled: false,
548 
549  // callbacks
550  create: null
551  },
552  _createWidget: function( options, element ) {
553  element = $( element || this.defaultElement || this )[ 0 ];
554  this.element = $( element );
555  this.uuid = widget_uuid++;
556  this.eventNamespace = "." + this.widgetName + this.uuid;
557 
558  this.bindings = $();
559  this.hoverable = $();
560  this.focusable = $();
561 
562  if ( element !== this ) {
563  $.data( element, this.widgetFullName, this );
564  this._on( true, this.element, {
565  remove: function( event ) {
566  if ( event.target === element ) {
567  this.destroy();
568  }
569  }
570  });
571  this.document = $( element.style ?
572  // element within the document
573  element.ownerDocument :
574  // element is window or document
575  element.document || element );
576  this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
577  }
578 
579  this.options = $.widget.extend( {},
580  this.options,
581  this._getCreateOptions(),
582  options );
583 
584  this._create();
585  this._trigger( "create", null, this._getCreateEventData() );
586  this._init();
587  },
588  _getCreateOptions: $.noop,
589  _getCreateEventData: $.noop,
590  _create: $.noop,
591  _init: $.noop,
592 
593  destroy: function() {
594  this._destroy();
595  // we can probably remove the unbind calls in 2.0
596  // all event bindings should go through this._on()
597  this.element
598  .unbind( this.eventNamespace )
599  .removeData( this.widgetFullName )
600  // support: jquery <1.6.3
601  // http://bugs.jquery.com/ticket/9413
602  .removeData( $.camelCase( this.widgetFullName ) );
603  this.widget()
604  .unbind( this.eventNamespace )
605  .removeAttr( "aria-disabled" )
606  .removeClass(
607  this.widgetFullName + "-disabled " +
608  "ui-state-disabled" );
609 
610  // clean up events and states
611  this.bindings.unbind( this.eventNamespace );
612  this.hoverable.removeClass( "ui-state-hover" );
613  this.focusable.removeClass( "ui-state-focus" );
614  },
615  _destroy: $.noop,
616 
617  widget: function() {
618  return this.element;
619  },
620 
621  option: function( key, value ) {
622  var options = key,
623  parts,
624  curOption,
625  i;
626 
627  if ( arguments.length === 0 ) {
628  // don't return a reference to the internal hash
629  return $.widget.extend( {}, this.options );
630  }
631 
632  if ( typeof key === "string" ) {
633  // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
634  options = {};
635  parts = key.split( "." );
636  key = parts.shift();
637  if ( parts.length ) {
638  curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
639  for ( i = 0; i < parts.length - 1; i++ ) {
640  curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
641  curOption = curOption[ parts[ i ] ];
642  }
643  key = parts.pop();
644  if ( arguments.length === 1 ) {
645  return curOption[ key ] === undefined ? null : curOption[ key ];
646  }
647  curOption[ key ] = value;
648  } else {
649  if ( arguments.length === 1 ) {
650  return this.options[ key ] === undefined ? null : this.options[ key ];
651  }
652  options[ key ] = value;
653  }
654  }
655 
656  this._setOptions( options );
657 
658  return this;
659  },
660  _setOptions: function( options ) {
661  var key;
662 
663  for ( key in options ) {
664  this._setOption( key, options[ key ] );
665  }
666 
667  return this;
668  },
669  _setOption: function( key, value ) {
670  this.options[ key ] = value;
671 
672  if ( key === "disabled" ) {
673  this.widget()
674  .toggleClass( this.widgetFullName + "-disabled", !!value );
675 
676  // If the widget is becoming disabled, then nothing is interactive
677  if ( value ) {
678  this.hoverable.removeClass( "ui-state-hover" );
679  this.focusable.removeClass( "ui-state-focus" );
680  }
681  }
682 
683  return this;
684  },
685 
686  enable: function() {
687  return this._setOptions({ disabled: false });
688  },
689  disable: function() {
690  return this._setOptions({ disabled: true });
691  },
692 
693  _on: function( suppressDisabledCheck, element, handlers ) {
694  var delegateElement,
695  instance = this;
696 
697  // no suppressDisabledCheck flag, shuffle arguments
698  if ( typeof suppressDisabledCheck !== "boolean" ) {
699  handlers = element;
700  element = suppressDisabledCheck;
701  suppressDisabledCheck = false;
702  }
703 
704  // no element argument, shuffle and use this.element
705  if ( !handlers ) {
706  handlers = element;
707  element = this.element;
708  delegateElement = this.widget();
709  } else {
710  element = delegateElement = $( element );
711  this.bindings = this.bindings.add( element );
712  }
713 
714  $.each( handlers, function( event, handler ) {
715  function handlerProxy() {
716  // allow widgets to customize the disabled handling
717  // - disabled as an array instead of boolean
718  // - disabled class as method for disabling individual parts
719  if ( !suppressDisabledCheck &&
720  ( instance.options.disabled === true ||
721  $( this ).hasClass( "ui-state-disabled" ) ) ) {
722  return;
723  }
724  return ( typeof handler === "string" ? instance[ handler ] : handler )
725  .apply( instance, arguments );
726  }
727 
728  // copy the guid so direct unbinding works
729  if ( typeof handler !== "string" ) {
730  handlerProxy.guid = handler.guid =
731  handler.guid || handlerProxy.guid || $.guid++;
732  }
733 
734  var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
735  eventName = match[1] + instance.eventNamespace,
736  selector = match[2];
737  if ( selector ) {
738  delegateElement.delegate( selector, eventName, handlerProxy );
739  } else {
740  element.bind( eventName, handlerProxy );
741  }
742  });
743  },
744 
745  _off: function( element, eventName ) {
746  eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
747  this.eventNamespace;
748  element.unbind( eventName ).undelegate( eventName );
749 
750  // Clear the stack to avoid memory leaks (#10056)
751  this.bindings = $( this.bindings.not( element ).get() );
752  this.focusable = $( this.focusable.not( element ).get() );
753  this.hoverable = $( this.hoverable.not( element ).get() );
754  },
755 
756  _delay: function( handler, delay ) {
757  function handlerProxy() {
758  return ( typeof handler === "string" ? instance[ handler ] : handler )
759  .apply( instance, arguments );
760  }
761  var instance = this;
762  return setTimeout( handlerProxy, delay || 0 );
763  },
764 
765  _hoverable: function( element ) {
766  this.hoverable = this.hoverable.add( element );
767  this._on( element, {
768  mouseenter: function( event ) {
769  $( event.currentTarget ).addClass( "ui-state-hover" );
770  },
771  mouseleave: function( event ) {
772  $( event.currentTarget ).removeClass( "ui-state-hover" );
773  }
774  });
775  },
776 
777  _focusable: function( element ) {
778  this.focusable = this.focusable.add( element );
779  this._on( element, {
780  focusin: function( event ) {
781  $( event.currentTarget ).addClass( "ui-state-focus" );
782  },
783  focusout: function( event ) {
784  $( event.currentTarget ).removeClass( "ui-state-focus" );
785  }
786  });
787  },
788 
789  _trigger: function( type, event, data ) {
790  var prop, orig,
791  callback = this.options[ type ];
792 
793  data = data || {};
794  event = $.Event( event );
795  event.type = ( type === this.widgetEventPrefix ?
796  type :
797  this.widgetEventPrefix + type ).toLowerCase();
798  // the original event may come from any element
799  // so we need to reset the target on the new event
800  event.target = this.element[ 0 ];
801 
802  // copy original event properties over to the new event
803  orig = event.originalEvent;
804  if ( orig ) {
805  for ( prop in orig ) {
806  if ( !( prop in event ) ) {
807  event[ prop ] = orig[ prop ];
808  }
809  }
810  }
811 
812  this.element.trigger( event, data );
813  return !( $.isFunction( callback ) &&
814  callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
815  event.isDefaultPrevented() );
816  }
817 };
818 
819 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
820  $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
821  if ( typeof options === "string" ) {
822  options = { effect: options };
823  }
824  var hasOptions,
825  effectName = !options ?
826  method :
827  options === true || typeof options === "number" ?
828  defaultEffect :
829  options.effect || defaultEffect;
830  options = options || {};
831  if ( typeof options === "number" ) {
832  options = { duration: options };
833  }
834  hasOptions = !$.isEmptyObject( options );
835  options.complete = callback;
836  if ( options.delay ) {
837  element.delay( options.delay );
838  }
839  if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
840  element[ method ]( options );
841  } else if ( effectName !== method && element[ effectName ] ) {
842  element[ effectName ]( options.duration, options.easing, callback );
843  } else {
844  element.queue(function( next ) {
845  $( this )[ method ]();
846  if ( callback ) {
847  callback.call( element[ 0 ] );
848  }
849  next();
850  });
851  }
852  };
853 });
854 
855 var widget = $.widget;
856 
857 
858 /*!
859  * jQuery UI Mouse 1.11.2
860  * http://jqueryui.com
861  *
862  * Copyright 2014 jQuery Foundation and other contributors
863  * Released under the MIT license.
864  * http://jquery.org/license
865  *
866  * http://api.jqueryui.com/mouse/
867  */
868 
869 
870 var mouseHandled = false;
871 $( document ).mouseup( function() {
872  mouseHandled = false;
873 });
874 
875 var mouse = $.widget("ui.mouse", {
876  version: "1.11.2",
877  options: {
878  cancel: "input,textarea,button,select,option",
879  distance: 1,
880  delay: 0
881  },
882  _mouseInit: function() {
883  var that = this;
884 
885  this.element
886  .bind("mousedown." + this.widgetName, function(event) {
887  return that._mouseDown(event);
888  })
889  .bind("click." + this.widgetName, function(event) {
890  if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
891  $.removeData(event.target, that.widgetName + ".preventClickEvent");
892  event.stopImmediatePropagation();
893  return false;
894  }
895  });
896 
897  this.started = false;
898  },
899 
900  // TODO: make sure destroying one instance of mouse doesn't mess with
901  // other instances of mouse
902  _mouseDestroy: function() {
903  this.element.unbind("." + this.widgetName);
904  if ( this._mouseMoveDelegate ) {
905  this.document
906  .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
907  .unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
908  }
909  },
910 
911  _mouseDown: function(event) {
912  // don't let more than one widget handle mouseStart
913  if ( mouseHandled ) {
914  return;
915  }
916 
917  this._mouseMoved = false;
918 
919  // we may have missed mouseup (out of window)
920  (this._mouseStarted && this._mouseUp(event));
921 
922  this._mouseDownEvent = event;
923 
924  var that = this,
925  btnIsLeft = (event.which === 1),
926  // event.target.nodeName works around a bug in IE 8 with
927  // disabled inputs (#7620)
928  elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
929  if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
930  return true;
931  }
932 
933  this.mouseDelayMet = !this.options.delay;
934  if (!this.mouseDelayMet) {
935  this._mouseDelayTimer = setTimeout(function() {
936  that.mouseDelayMet = true;
937  }, this.options.delay);
938  }
939 
940  if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
941  this._mouseStarted = (this._mouseStart(event) !== false);
942  if (!this._mouseStarted) {
943  event.preventDefault();
944  return true;
945  }
946  }
947 
948  // Click event may never have fired (Gecko & Opera)
949  if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
950  $.removeData(event.target, this.widgetName + ".preventClickEvent");
951  }
952 
953  // these delegates are required to keep context
954  this._mouseMoveDelegate = function(event) {
955  return that._mouseMove(event);
956  };
957  this._mouseUpDelegate = function(event) {
958  return that._mouseUp(event);
959  };
960 
961  this.document
962  .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
963  .bind( "mouseup." + this.widgetName, this._mouseUpDelegate );
964 
965  event.preventDefault();
966 
967  mouseHandled = true;
968  return true;
969  },
970 
971  _mouseMove: function(event) {
972  // Only check for mouseups outside the document if you've moved inside the document
973  // at least once. This prevents the firing of mouseup in the case of IE<9, which will
974  // fire a mousemove event if content is placed under the cursor. See #7778
975  // Support: IE <9
976  if ( this._mouseMoved ) {
977  // IE mouseup check - mouseup happened when mouse was out of window
978  if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
979  return this._mouseUp(event);
980 
981  // Iframe mouseup check - mouseup occurred in another document
982  } else if ( !event.which ) {
983  return this._mouseUp( event );
984  }
985  }
986 
987  if ( event.which || event.button ) {
988  this._mouseMoved = true;
989  }
990 
991  if (this._mouseStarted) {
992  this._mouseDrag(event);
993  return event.preventDefault();
994  }
995 
996  if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
997  this._mouseStarted =
998  (this._mouseStart(this._mouseDownEvent, event) !== false);
999  (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
1000  }
1001 
1002  return !this._mouseStarted;
1003  },
1004 
1005  _mouseUp: function(event) {
1006  this.document
1007  .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1008  .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );
1009 
1010  if (this._mouseStarted) {
1011  this._mouseStarted = false;
1012 
1013  if (event.target === this._mouseDownEvent.target) {
1014  $.data(event.target, this.widgetName + ".preventClickEvent", true);
1015  }
1016 
1017  this._mouseStop(event);
1018  }
1019 
1020  mouseHandled = false;
1021  return false;
1022  },
1023 
1024  _mouseDistanceMet: function(event) {
1025  return (Math.max(
1026  Math.abs(this._mouseDownEvent.pageX - event.pageX),
1027  Math.abs(this._mouseDownEvent.pageY - event.pageY)
1028  ) >= this.options.distance
1029  );
1030  },
1031 
1032  _mouseDelayMet: function(/* event */) {
1033  return this.mouseDelayMet;
1034  },
1035 
1036  // These are placeholder methods, to be overriden by extending plugin
1037  _mouseStart: function(/* event */) {},
1038  _mouseDrag: function(/* event */) {},
1039  _mouseStop: function(/* event */) {},
1040  _mouseCapture: function(/* event */) { return true; }
1041 });
1042 
1043 
1044 /*!
1045  * jQuery UI Position 1.11.2
1046  * http://jqueryui.com
1047  *
1048  * Copyright 2014 jQuery Foundation and other contributors
1049  * Released under the MIT license.
1050  * http://jquery.org/license
1051  *
1052  * http://api.jqueryui.com/position/
1053  */
1054 
1055 (function() {
1056 
1057 $.ui = $.ui || {};
1058 
1059 var cachedScrollbarWidth, supportsOffsetFractions,
1060  max = Math.max,
1061  abs = Math.abs,
1062  round = Math.round,
1063  rhorizontal = /left|center|right/,
1064  rvertical = /top|center|bottom/,
1065  roffset = /[\+\-]\d+(\.[\d]+)?%?/,
1066  rposition = /^\w+/,
1067  rpercent = /%$/,
1068  _position = $.fn.position;
1069 
1070 function getOffsets( offsets, width, height ) {
1071  return [
1072  parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1073  parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1074  ];
1075 }
1076 
1077 function parseCss( element, property ) {
1078  return parseInt( $.css( element, property ), 10 ) || 0;
1079 }
1080 
1081 function getDimensions( elem ) {
1082  var raw = elem[0];
1083  if ( raw.nodeType === 9 ) {
1084  return {
1085  width: elem.width(),
1086  height: elem.height(),
1087  offset: { top: 0, left: 0 }
1088  };
1089  }
1090  if ( $.isWindow( raw ) ) {
1091  return {
1092  width: elem.width(),
1093  height: elem.height(),
1094  offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
1095  };
1096  }
1097  if ( raw.preventDefault ) {
1098  return {
1099  width: 0,
1100  height: 0,
1101  offset: { top: raw.pageY, left: raw.pageX }
1102  };
1103  }
1104  return {
1105  width: elem.outerWidth(),
1106  height: elem.outerHeight(),
1107  offset: elem.offset()
1108  };
1109 }
1110 
1111 $.position = {
1112  scrollbarWidth: function() {
1113  if ( cachedScrollbarWidth !== undefined ) {
1114  return cachedScrollbarWidth;
1115  }
1116  var w1, w2,
1117  div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1118  innerDiv = div.children()[0];
1119 
1120  $( "body" ).append( div );
1121  w1 = innerDiv.offsetWidth;
1122  div.css( "overflow", "scroll" );
1123 
1124  w2 = innerDiv.offsetWidth;
1125 
1126  if ( w1 === w2 ) {
1127  w2 = div[0].clientWidth;
1128  }
1129 
1130  div.remove();
1131 
1132  return (cachedScrollbarWidth = w1 - w2);
1133  },
1134  getScrollInfo: function( within ) {
1135  var overflowX = within.isWindow || within.isDocument ? "" :
1136  within.element.css( "overflow-x" ),
1137  overflowY = within.isWindow || within.isDocument ? "" :
1138  within.element.css( "overflow-y" ),
1139  hasOverflowX = overflowX === "scroll" ||
1140  ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1141  hasOverflowY = overflowY === "scroll" ||
1142  ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1143  return {
1144  width: hasOverflowY ? $.position.scrollbarWidth() : 0,
1145  height: hasOverflowX ? $.position.scrollbarWidth() : 0
1146  };
1147  },
1148  getWithinInfo: function( element ) {
1149  var withinElement = $( element || window ),
1150  isWindow = $.isWindow( withinElement[0] ),
1151  isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
1152  return {
1153  element: withinElement,
1154  isWindow: isWindow,
1155  isDocument: isDocument,
1156  offset: withinElement.offset() || { left: 0, top: 0 },
1157  scrollLeft: withinElement.scrollLeft(),
1158  scrollTop: withinElement.scrollTop(),
1159 
1160  // support: jQuery 1.6.x
1161  // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
1162  width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
1163  height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
1164  };
1165  }
1166 };
1167 
1168 $.fn.position = function( options ) {
1169  if ( !options || !options.of ) {
1170  return _position.apply( this, arguments );
1171  }
1172 
1173  // make a copy, we don't want to modify arguments
1174  options = $.extend( {}, options );
1175 
1176  var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
1177  target = $( options.of ),
1178  within = $.position.getWithinInfo( options.within ),
1179  scrollInfo = $.position.getScrollInfo( within ),
1180  collision = ( options.collision || "flip" ).split( " " ),
1181  offsets = {};
1182 
1183  dimensions = getDimensions( target );
1184  if ( target[0].preventDefault ) {
1185  // force left top to allow flipping
1186  options.at = "left top";
1187  }
1188  targetWidth = dimensions.width;
1189  targetHeight = dimensions.height;
1190  targetOffset = dimensions.offset;
1191  // clone to reuse original targetOffset later
1192  basePosition = $.extend( {}, targetOffset );
1193 
1194  // force my and at to have valid horizontal and vertical positions
1195  // if a value is missing or invalid, it will be converted to center
1196  $.each( [ "my", "at" ], function() {
1197  var pos = ( options[ this ] || "" ).split( " " ),
1198  horizontalOffset,
1199  verticalOffset;
1200 
1201  if ( pos.length === 1) {
1202  pos = rhorizontal.test( pos[ 0 ] ) ?
1203  pos.concat( [ "center" ] ) :
1204  rvertical.test( pos[ 0 ] ) ?
1205  [ "center" ].concat( pos ) :
1206  [ "center", "center" ];
1207  }
1208  pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1209  pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1210 
1211  // calculate offsets
1212  horizontalOffset = roffset.exec( pos[ 0 ] );
1213  verticalOffset = roffset.exec( pos[ 1 ] );
1214  offsets[ this ] = [
1215  horizontalOffset ? horizontalOffset[ 0 ] : 0,
1216  verticalOffset ? verticalOffset[ 0 ] : 0
1217  ];
1218 
1219  // reduce to just the positions without the offsets
1220  options[ this ] = [
1221  rposition.exec( pos[ 0 ] )[ 0 ],
1222  rposition.exec( pos[ 1 ] )[ 0 ]
1223  ];
1224  });
1225 
1226  // normalize collision option
1227  if ( collision.length === 1 ) {
1228  collision[ 1 ] = collision[ 0 ];
1229  }
1230 
1231  if ( options.at[ 0 ] === "right" ) {
1232  basePosition.left += targetWidth;
1233  } else if ( options.at[ 0 ] === "center" ) {
1234  basePosition.left += targetWidth / 2;
1235  }
1236 
1237  if ( options.at[ 1 ] === "bottom" ) {
1238  basePosition.top += targetHeight;
1239  } else if ( options.at[ 1 ] === "center" ) {
1240  basePosition.top += targetHeight / 2;
1241  }
1242 
1243  atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1244  basePosition.left += atOffset[ 0 ];
1245  basePosition.top += atOffset[ 1 ];
1246 
1247  return this.each(function() {
1248  var collisionPosition, using,
1249  elem = $( this ),
1250  elemWidth = elem.outerWidth(),
1251  elemHeight = elem.outerHeight(),
1252  marginLeft = parseCss( this, "marginLeft" ),
1253  marginTop = parseCss( this, "marginTop" ),
1254  collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1255  collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1256  position = $.extend( {}, basePosition ),
1257  myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1258 
1259  if ( options.my[ 0 ] === "right" ) {
1260  position.left -= elemWidth;
1261  } else if ( options.my[ 0 ] === "center" ) {
1262  position.left -= elemWidth / 2;
1263  }
1264 
1265  if ( options.my[ 1 ] === "bottom" ) {
1266  position.top -= elemHeight;
1267  } else if ( options.my[ 1 ] === "center" ) {
1268  position.top -= elemHeight / 2;
1269  }
1270 
1271  position.left += myOffset[ 0 ];
1272  position.top += myOffset[ 1 ];
1273 
1274  // if the browser doesn't support fractions, then round for consistent results
1275  if ( !supportsOffsetFractions ) {
1276  position.left = round( position.left );
1277  position.top = round( position.top );
1278  }
1279 
1280  collisionPosition = {
1281  marginLeft: marginLeft,
1282  marginTop: marginTop
1283  };
1284 
1285  $.each( [ "left", "top" ], function( i, dir ) {
1286  if ( $.ui.position[ collision[ i ] ] ) {
1287  $.ui.position[ collision[ i ] ][ dir ]( position, {
1288  targetWidth: targetWidth,
1289  targetHeight: targetHeight,
1290  elemWidth: elemWidth,
1291  elemHeight: elemHeight,
1292  collisionPosition: collisionPosition,
1293  collisionWidth: collisionWidth,
1294  collisionHeight: collisionHeight,
1295  offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1296  my: options.my,
1297  at: options.at,
1298  within: within,
1299  elem: elem
1300  });
1301  }
1302  });
1303 
1304  if ( options.using ) {
1305  // adds feedback as second argument to using callback, if present
1306  using = function( props ) {
1307  var left = targetOffset.left - position.left,
1308  right = left + targetWidth - elemWidth,
1309  top = targetOffset.top - position.top,
1310  bottom = top + targetHeight - elemHeight,
1311  feedback = {
1312  target: {
1313  element: target,
1314  left: targetOffset.left,
1315  top: targetOffset.top,
1316  width: targetWidth,
1317  height: targetHeight
1318  },
1319  element: {
1320  element: elem,
1321  left: position.left,
1322  top: position.top,
1323  width: elemWidth,
1324  height: elemHeight
1325  },
1326  horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1327  vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1328  };
1329  if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1330  feedback.horizontal = "center";
1331  }
1332  if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1333  feedback.vertical = "middle";
1334  }
1335  if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1336  feedback.important = "horizontal";
1337  } else {
1338  feedback.important = "vertical";
1339  }
1340  options.using.call( this, props, feedback );
1341  };
1342  }
1343 
1344  elem.offset( $.extend( position, { using: using } ) );
1345  });
1346 };
1347 
1348 $.ui.position = {
1349  fit: {
1350  left: function( position, data ) {
1351  var within = data.within,
1352  withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1353  outerWidth = within.width,
1354  collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1355  overLeft = withinOffset - collisionPosLeft,
1356  overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1357  newOverRight;
1358 
1359  // element is wider than within
1360  if ( data.collisionWidth > outerWidth ) {
1361  // element is initially over the left side of within
1362  if ( overLeft > 0 && overRight <= 0 ) {
1363  newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1364  position.left += overLeft - newOverRight;
1365  // element is initially over right side of within
1366  } else if ( overRight > 0 && overLeft <= 0 ) {
1367  position.left = withinOffset;
1368  // element is initially over both left and right sides of within
1369  } else {
1370  if ( overLeft > overRight ) {
1371  position.left = withinOffset + outerWidth - data.collisionWidth;
1372  } else {
1373  position.left = withinOffset;
1374  }
1375  }
1376  // too far left -> align with left edge
1377  } else if ( overLeft > 0 ) {
1378  position.left += overLeft;
1379  // too far right -> align with right edge
1380  } else if ( overRight > 0 ) {
1381  position.left -= overRight;
1382  // adjust based on position and margin
1383  } else {
1384  position.left = max( position.left - collisionPosLeft, position.left );
1385  }
1386  },
1387  top: function( position, data ) {
1388  var within = data.within,
1389  withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1390  outerHeight = data.within.height,
1391  collisionPosTop = position.top - data.collisionPosition.marginTop,
1392  overTop = withinOffset - collisionPosTop,
1393  overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1394  newOverBottom;
1395 
1396  // element is taller than within
1397  if ( data.collisionHeight > outerHeight ) {
1398  // element is initially over the top of within
1399  if ( overTop > 0 && overBottom <= 0 ) {
1400  newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1401  position.top += overTop - newOverBottom;
1402  // element is initially over bottom of within
1403  } else if ( overBottom > 0 && overTop <= 0 ) {
1404  position.top = withinOffset;
1405  // element is initially over both top and bottom of within
1406  } else {
1407  if ( overTop > overBottom ) {
1408  position.top = withinOffset + outerHeight - data.collisionHeight;
1409  } else {
1410  position.top = withinOffset;
1411  }
1412  }
1413  // too far up -> align with top
1414  } else if ( overTop > 0 ) {
1415  position.top += overTop;
1416  // too far down -> align with bottom edge
1417  } else if ( overBottom > 0 ) {
1418  position.top -= overBottom;
1419  // adjust based on position and margin
1420  } else {
1421  position.top = max( position.top - collisionPosTop, position.top );
1422  }
1423  }
1424  },
1425  flip: {
1426  left: function( position, data ) {
1427  var within = data.within,
1428  withinOffset = within.offset.left + within.scrollLeft,
1429  outerWidth = within.width,
1430  offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1431  collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1432  overLeft = collisionPosLeft - offsetLeft,
1433  overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1434  myOffset = data.my[ 0 ] === "left" ?
1435  -data.elemWidth :
1436  data.my[ 0 ] === "right" ?
1437  data.elemWidth :
1438  0,
1439  atOffset = data.at[ 0 ] === "left" ?
1440  data.targetWidth :
1441  data.at[ 0 ] === "right" ?
1442  -data.targetWidth :
1443  0,
1444  offset = -2 * data.offset[ 0 ],
1445  newOverRight,
1446  newOverLeft;
1447 
1448  if ( overLeft < 0 ) {
1449  newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1450  if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1451  position.left += myOffset + atOffset + offset;
1452  }
1453  } else if ( overRight > 0 ) {
1454  newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1455  if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1456  position.left += myOffset + atOffset + offset;
1457  }
1458  }
1459  },
1460  top: function( position, data ) {
1461  var within = data.within,
1462  withinOffset = within.offset.top + within.scrollTop,
1463  outerHeight = within.height,
1464  offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1465  collisionPosTop = position.top - data.collisionPosition.marginTop,
1466  overTop = collisionPosTop - offsetTop,
1467  overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1468  top = data.my[ 1 ] === "top",
1469  myOffset = top ?
1470  -data.elemHeight :
1471  data.my[ 1 ] === "bottom" ?
1472  data.elemHeight :
1473  0,
1474  atOffset = data.at[ 1 ] === "top" ?
1475  data.targetHeight :
1476  data.at[ 1 ] === "bottom" ?
1477  -data.targetHeight :
1478  0,
1479  offset = -2 * data.offset[ 1 ],
1480  newOverTop,
1481  newOverBottom;
1482  if ( overTop < 0 ) {
1483  newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1484  if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
1485  position.top += myOffset + atOffset + offset;
1486  }
1487  } else if ( overBottom > 0 ) {
1488  newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1489  if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
1490  position.top += myOffset + atOffset + offset;
1491  }
1492  }
1493  }
1494  },
1495  flipfit: {
1496  left: function() {
1497  $.ui.position.flip.left.apply( this, arguments );
1498  $.ui.position.fit.left.apply( this, arguments );
1499  },
1500  top: function() {
1501  $.ui.position.flip.top.apply( this, arguments );
1502  $.ui.position.fit.top.apply( this, arguments );
1503  }
1504  }
1505 };
1506 
1507 // fraction support test
1508 (function() {
1509  var testElement, testElementParent, testElementStyle, offsetLeft, i,
1510  body = document.getElementsByTagName( "body" )[ 0 ],
1511  div = document.createElement( "div" );
1512 
1513  //Create a "fake body" for testing based on method used in jQuery.support
1514  testElement = document.createElement( body ? "div" : "body" );
1515  testElementStyle = {
1516  visibility: "hidden",
1517  width: 0,
1518  height: 0,
1519  border: 0,
1520  margin: 0,
1521  background: "none"
1522  };
1523  if ( body ) {
1524  $.extend( testElementStyle, {
1525  position: "absolute",
1526  left: "-1000px",
1527  top: "-1000px"
1528  });
1529  }
1530  for ( i in testElementStyle ) {
1531  testElement.style[ i ] = testElementStyle[ i ];
1532  }
1533  testElement.appendChild( div );
1534  testElementParent = body || document.documentElement;
1535  testElementParent.insertBefore( testElement, testElementParent.firstChild );
1536 
1537  div.style.cssText = "position: absolute; left: 10.7432222px;";
1538 
1539  offsetLeft = $( div ).offset().left;
1540  supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
1541 
1542  testElement.innerHTML = "";
1543  testElementParent.removeChild( testElement );
1544 })();
1545 
1546 })();
1547 
1548 var position = $.ui.position;
1549 
1550 
1551 /*!
1552  * jQuery UI Draggable 1.11.2
1553  * http://jqueryui.com
1554  *
1555  * Copyright 2014 jQuery Foundation and other contributors
1556  * Released under the MIT license.
1557  * http://jquery.org/license
1558  *
1559  * http://api.jqueryui.com/draggable/
1560  */
1561 
1562 
1563 $.widget("ui.draggable", $.ui.mouse, {
1564  version: "1.11.2",
1565  widgetEventPrefix: "drag",
1566  options: {
1567  addClasses: true,
1568  appendTo: "parent",
1569  axis: false,
1570  connectToSortable: false,
1571  containment: false,
1572  cursor: "auto",
1573  cursorAt: false,
1574  grid: false,
1575  handle: false,
1576  helper: "original",
1577  iframeFix: false,
1578  opacity: false,
1579  refreshPositions: false,
1580  revert: false,
1581  revertDuration: 500,
1582  scope: "default",
1583  scroll: true,
1584  scrollSensitivity: 20,
1585  scrollSpeed: 20,
1586  snap: false,
1587  snapMode: "both",
1588  snapTolerance: 20,
1589  stack: false,
1590  zIndex: false,
1591 
1592  // callbacks
1593  drag: null,
1594  start: null,
1595  stop: null
1596  },
1597  _create: function() {
1598 
1599  if ( this.options.helper === "original" ) {
1600  this._setPositionRelative();
1601  }
1602  if (this.options.addClasses){
1603  this.element.addClass("ui-draggable");
1604  }
1605  if (this.options.disabled){
1606  this.element.addClass("ui-draggable-disabled");
1607  }
1608  this._setHandleClassName();
1609 
1610  this._mouseInit();
1611  },
1612 
1613  _setOption: function( key, value ) {
1614  this._super( key, value );
1615  if ( key === "handle" ) {
1616  this._removeHandleClassName();
1617  this._setHandleClassName();
1618  }
1619  },
1620 
1621  _destroy: function() {
1622  if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
1623  this.destroyOnClear = true;
1624  return;
1625  }
1626  this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1627  this._removeHandleClassName();
1628  this._mouseDestroy();
1629  },
1630 
1631  _mouseCapture: function(event) {
1632  var o = this.options;
1633 
1634  this._blurActiveElement( event );
1635 
1636  // among others, prevent a drag on a resizable-handle
1637  if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1638  return false;
1639  }
1640 
1641  //Quit if we're not on a valid handle
1642  this.handle = this._getHandle(event);
1643  if (!this.handle) {
1644  return false;
1645  }
1646 
1647  this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
1648 
1649  return true;
1650 
1651  },
1652 
1653  _blockFrames: function( selector ) {
1654  this.iframeBlocks = this.document.find( selector ).map(function() {
1655  var iframe = $( this );
1656 
1657  return $( "<div>" )
1658  .css( "position", "absolute" )
1659  .appendTo( iframe.parent() )
1660  .outerWidth( iframe.outerWidth() )
1661  .outerHeight( iframe.outerHeight() )
1662  .offset( iframe.offset() )[ 0 ];
1663  });
1664  },
1665 
1666  _unblockFrames: function() {
1667  if ( this.iframeBlocks ) {
1668  this.iframeBlocks.remove();
1669  delete this.iframeBlocks;
1670  }
1671  },
1672 
1673  _blurActiveElement: function( event ) {
1674  var document = this.document[ 0 ];
1675 
1676  // Only need to blur if the event occurred on the draggable itself, see #10527
1677  if ( !this.handleElement.is( event.target ) ) {
1678  return;
1679  }
1680 
1681  // support: IE9
1682  // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
1683  try {
1684 
1685  // Support: IE9, IE10
1686  // If the <body> is blurred, IE will switch windows, see #9520
1687  if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
1688 
1689  // Blur any element that currently has focus, see #4261
1690  $( document.activeElement ).blur();
1691  }
1692  } catch ( error ) {}
1693  },
1694 
1695  _mouseStart: function(event) {
1696 
1697  var o = this.options;
1698 
1699  //Create and append the visible helper
1700  this.helper = this._createHelper(event);
1701 
1702  this.helper.addClass("ui-draggable-dragging");
1703 
1704  //Cache the helper size
1705  this._cacheHelperProportions();
1706 
1707  //If ddmanager is used for droppables, set the global draggable
1708  if ($.ui.ddmanager) {
1709  $.ui.ddmanager.current = this;
1710  }
1711 
1712  /*
1713  * - Position generation -
1714  * This block generates everything position related - it's the core of draggables.
1715  */
1716 
1717  //Cache the margins of the original element
1718  this._cacheMargins();
1719 
1720  //Store the helper's css position
1721  this.cssPosition = this.helper.css( "position" );
1722  this.scrollParent = this.helper.scrollParent( true );
1723  this.offsetParent = this.helper.offsetParent();
1724  this.hasFixedAncestor = this.helper.parents().filter(function() {
1725  return $( this ).css( "position" ) === "fixed";
1726  }).length > 0;
1727 
1728  //The element's absolute position on the page minus margins
1729  this.positionAbs = this.element.offset();
1730  this._refreshOffsets( event );
1731 
1732  //Generate the original position
1733  this.originalPosition = this.position = this._generatePosition( event, false );
1734  this.originalPageX = event.pageX;
1735  this.originalPageY = event.pageY;
1736 
1737  //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1738  (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1739 
1740  //Set a containment if given in the options
1741  this._setContainment();
1742 
1743  //Trigger event + callbacks
1744  if (this._trigger("start", event) === false) {
1745  this._clear();
1746  return false;
1747  }
1748 
1749  //Recache the helper size
1750  this._cacheHelperProportions();
1751 
1752  //Prepare the droppable offsets
1753  if ($.ui.ddmanager && !o.dropBehaviour) {
1754  $.ui.ddmanager.prepareOffsets(this, event);
1755  }
1756 
1757  // Reset helper's right/bottom css if they're set and set explicit width/height instead
1758  // as this prevents resizing of elements with right/bottom set (see #7772)
1759  this._normalizeRightBottom();
1760 
1761  this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1762 
1763  //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1764  if ( $.ui.ddmanager ) {
1765  $.ui.ddmanager.dragStart(this, event);
1766  }
1767 
1768  return true;
1769  },
1770 
1771  _refreshOffsets: function( event ) {
1772  this.offset = {
1773  top: this.positionAbs.top - this.margins.top,
1774  left: this.positionAbs.left - this.margins.left,
1775  scroll: false,
1776  parent: this._getParentOffset(),
1777  relative: this._getRelativeOffset()
1778  };
1779 
1780  this.offset.click = {
1781  left: event.pageX - this.offset.left,
1782  top: event.pageY - this.offset.top
1783  };
1784  },
1785 
1786  _mouseDrag: function(event, noPropagation) {
1787  // reset any necessary cached properties (see #5009)
1788  if ( this.hasFixedAncestor ) {
1789  this.offset.parent = this._getParentOffset();
1790  }
1791 
1792  //Compute the helpers position
1793  this.position = this._generatePosition( event, true );
1794  this.positionAbs = this._convertPositionTo("absolute");
1795 
1796  //Call plugins and callbacks and use the resulting position if something is returned
1797  if (!noPropagation) {
1798  var ui = this._uiHash();
1799  if (this._trigger("drag", event, ui) === false) {
1800  this._mouseUp({});
1801  return false;
1802  }
1803  this.position = ui.position;
1804  }
1805 
1806  this.helper[ 0 ].style.left = this.position.left + "px";
1807  this.helper[ 0 ].style.top = this.position.top + "px";
1808 
1809  if ($.ui.ddmanager) {
1810  $.ui.ddmanager.drag(this, event);
1811  }
1812 
1813  return false;
1814  },
1815 
1816  _mouseStop: function(event) {
1817 
1818  //If we are using droppables, inform the manager about the drop
1819  var that = this,
1820  dropped = false;
1821  if ($.ui.ddmanager && !this.options.dropBehaviour) {
1822  dropped = $.ui.ddmanager.drop(this, event);
1823  }
1824 
1825  //if a drop comes from outside (a sortable)
1826  if (this.dropped) {
1827  dropped = this.dropped;
1828  this.dropped = false;
1829  }
1830 
1831  if ((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
1832  $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1833  if (that._trigger("stop", event) !== false) {
1834  that._clear();
1835  }
1836  });
1837  } else {
1838  if (this._trigger("stop", event) !== false) {
1839  this._clear();
1840  }
1841  }
1842 
1843  return false;
1844  },
1845 
1846  _mouseUp: function( event ) {
1847  this._unblockFrames();
1848 
1849  //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1850  if ( $.ui.ddmanager ) {
1851  $.ui.ddmanager.dragStop(this, event);
1852  }
1853 
1854  // Only need to focus if the event occurred on the draggable itself, see #10527
1855  if ( this.handleElement.is( event.target ) ) {
1856  // The interaction is over; whether or not the click resulted in a drag, focus the element
1857  this.element.focus();
1858  }
1859 
1860  return $.ui.mouse.prototype._mouseUp.call(this, event);
1861  },
1862 
1863  cancel: function() {
1864 
1865  if (this.helper.is(".ui-draggable-dragging")) {
1866  this._mouseUp({});
1867  } else {
1868  this._clear();
1869  }
1870 
1871  return this;
1872 
1873  },
1874 
1875  _getHandle: function(event) {
1876  return this.options.handle ?
1877  !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1878  true;
1879  },
1880 
1881  _setHandleClassName: function() {
1882  this.handleElement = this.options.handle ?
1883  this.element.find( this.options.handle ) : this.element;
1884  this.handleElement.addClass( "ui-draggable-handle" );
1885  },
1886 
1887  _removeHandleClassName: function() {
1888  this.handleElement.removeClass( "ui-draggable-handle" );
1889  },
1890 
1891  _createHelper: function(event) {
1892 
1893  var o = this.options,
1894  helperIsFunction = $.isFunction( o.helper ),
1895  helper = helperIsFunction ?
1896  $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
1897  ( o.helper === "clone" ?
1898  this.element.clone().removeAttr( "id" ) :
1899  this.element );
1900 
1901  if (!helper.parents("body").length) {
1902  helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1903  }
1904 
1905  // http://bugs.jqueryui.com/ticket/9446
1906  // a helper function can return the original element
1907  // which wouldn't have been set to relative in _create
1908  if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
1909  this._setPositionRelative();
1910  }
1911 
1912  if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1913  helper.css("position", "absolute");
1914  }
1915 
1916  return helper;
1917 
1918  },
1919 
1920  _setPositionRelative: function() {
1921  if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
1922  this.element[ 0 ].style.position = "relative";
1923  }
1924  },
1925 
1926  _adjustOffsetFromHelper: function(obj) {
1927  if (typeof obj === "string") {
1928  obj = obj.split(" ");
1929  }
1930  if ($.isArray(obj)) {
1931  obj = { left: +obj[0], top: +obj[1] || 0 };
1932  }
1933  if ("left" in obj) {
1934  this.offset.click.left = obj.left + this.margins.left;
1935  }
1936  if ("right" in obj) {
1937  this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1938  }
1939  if ("top" in obj) {
1940  this.offset.click.top = obj.top + this.margins.top;
1941  }
1942  if ("bottom" in obj) {
1943  this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1944  }
1945  },
1946 
1947  _isRootNode: function( element ) {
1948  return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
1949  },
1950 
1951  _getParentOffset: function() {
1952 
1953  //Get the offsetParent and cache its position
1954  var po = this.offsetParent.offset(),
1955  document = this.document[ 0 ];
1956 
1957  // This is a special case where we need to modify a offset calculated on start, since the following happened:
1958  // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1959  // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1960  // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1961  if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1962  po.left += this.scrollParent.scrollLeft();
1963  po.top += this.scrollParent.scrollTop();
1964  }
1965 
1966  if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
1967  po = { top: 0, left: 0 };
1968  }
1969 
1970  return {
1971  top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
1972  left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
1973  };
1974 
1975  },
1976 
1977  _getRelativeOffset: function() {
1978  if ( this.cssPosition !== "relative" ) {
1979  return { top: 0, left: 0 };
1980  }
1981 
1982  var p = this.element.position(),
1983  scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
1984 
1985  return {
1986  top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
1987  left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
1988  };
1989 
1990  },
1991 
1992  _cacheMargins: function() {
1993  this.margins = {
1994  left: (parseInt(this.element.css("marginLeft"), 10) || 0),
1995  top: (parseInt(this.element.css("marginTop"), 10) || 0),
1996  right: (parseInt(this.element.css("marginRight"), 10) || 0),
1997  bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
1998  };
1999  },
2000 
2001  _cacheHelperProportions: function() {
2002  this.helperProportions = {
2003  width: this.helper.outerWidth(),
2004  height: this.helper.outerHeight()
2005  };
2006  },
2007 
2008  _setContainment: function() {
2009 
2010  var isUserScrollable, c, ce,
2011  o = this.options,
2012  document = this.document[ 0 ];
2013 
2014  this.relativeContainer = null;
2015 
2016  if ( !o.containment ) {
2017  this.containment = null;
2018  return;
2019  }
2020 
2021  if ( o.containment === "window" ) {
2022  this.containment = [
2023  $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
2024  $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
2025  $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
2026  $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
2027  ];
2028  return;
2029  }
2030 
2031  if ( o.containment === "document") {
2032  this.containment = [
2033  0,
2034  0,
2035  $( document ).width() - this.helperProportions.width - this.margins.left,
2036  ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
2037  ];
2038  return;
2039  }
2040 
2041  if ( o.containment.constructor === Array ) {
2042  this.containment = o.containment;
2043  return;
2044  }
2045 
2046  if ( o.containment === "parent" ) {
2047  o.containment = this.helper[ 0 ].parentNode;
2048  }
2049 
2050  c = $( o.containment );
2051  ce = c[ 0 ];
2052 
2053  if ( !ce ) {
2054  return;
2055  }
2056 
2057  isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
2058 
2059  this.containment = [
2060  ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
2061  ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
2062  ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
2063  ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
2064  ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
2065  this.helperProportions.width -
2066  this.margins.left -
2067  this.margins.right,
2068  ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
2069  ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
2070  ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
2071  this.helperProportions.height -
2072  this.margins.top -
2073  this.margins.bottom
2074  ];
2075  this.relativeContainer = c;
2076  },
2077 
2078  _convertPositionTo: function(d, pos) {
2079 
2080  if (!pos) {
2081  pos = this.position;
2082  }
2083 
2084  var mod = d === "absolute" ? 1 : -1,
2085  scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
2086 
2087  return {
2088  top: (
2089  pos.top + // The absolute mouse position
2090  this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
2091  this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border)
2092  ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
2093  ),
2094  left: (
2095  pos.left + // The absolute mouse position
2096  this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
2097  this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border)
2098  ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
2099  )
2100  };
2101 
2102  },
2103 
2104  _generatePosition: function( event, constrainPosition ) {
2105 
2106  var containment, co, top, left,
2107  o = this.options,
2108  scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
2109  pageX = event.pageX,
2110  pageY = event.pageY;
2111 
2112  // Cache the scroll
2113  if ( !scrollIsRootNode || !this.offset.scroll ) {
2114  this.offset.scroll = {
2115  top: this.scrollParent.scrollTop(),
2116  left: this.scrollParent.scrollLeft()
2117  };
2118  }
2119 
2120  /*
2121  * - Position constraining -
2122  * Constrain the position to a mix of grid, containment.
2123  */
2124 
2125  // If we are not dragging yet, we won't check for options
2126  if ( constrainPosition ) {
2127  if ( this.containment ) {
2128  if ( this.relativeContainer ){
2129  co = this.relativeContainer.offset();
2130  containment = [
2131  this.containment[ 0 ] + co.left,
2132  this.containment[ 1 ] + co.top,
2133  this.containment[ 2 ] + co.left,
2134  this.containment[ 3 ] + co.top
2135  ];
2136  } else {
2137  containment = this.containment;
2138  }
2139 
2140  if (event.pageX - this.offset.click.left < containment[0]) {
2141  pageX = containment[0] + this.offset.click.left;
2142  }
2143  if (event.pageY - this.offset.click.top < containment[1]) {
2144  pageY = containment[1] + this.offset.click.top;
2145  }
2146  if (event.pageX - this.offset.click.left > containment[2]) {
2147  pageX = containment[2] + this.offset.click.left;
2148  }
2149  if (event.pageY - this.offset.click.top > containment[3]) {
2150  pageY = containment[3] + this.offset.click.top;
2151  }
2152  }
2153 
2154  if (o.grid) {
2155  //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
2156  top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
2157  pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
2158 
2159  left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
2160  pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
2161  }
2162 
2163  if ( o.axis === "y" ) {
2164  pageX = this.originalPageX;
2165  }
2166 
2167  if ( o.axis === "x" ) {
2168  pageY = this.originalPageY;
2169  }
2170  }
2171 
2172  return {
2173  top: (
2174  pageY - // The absolute mouse position
2175  this.offset.click.top - // Click offset (relative to the element)
2176  this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
2177  this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
2178  ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
2179  ),
2180  left: (
2181  pageX - // The absolute mouse position
2182  this.offset.click.left - // Click offset (relative to the element)
2183  this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
2184  this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
2185  ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
2186  )
2187  };
2188 
2189  },
2190 
2191  _clear: function() {
2192  this.helper.removeClass("ui-draggable-dragging");
2193  if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
2194  this.helper.remove();
2195  }
2196  this.helper = null;
2197  this.cancelHelperRemoval = false;
2198  if ( this.destroyOnClear ) {
2199  this.destroy();
2200  }
2201  },
2202 
2203  _normalizeRightBottom: function() {
2204  if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
2205  this.helper.width( this.helper.width() );
2206  this.helper.css( "right", "auto" );
2207  }
2208  if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
2209  this.helper.height( this.helper.height() );
2210  this.helper.css( "bottom", "auto" );
2211  }
2212  },
2213 
2214  // From now on bulk stuff - mainly helpers
2215 
2216  _trigger: function( type, event, ui ) {
2217  ui = ui || this._uiHash();
2218  $.ui.plugin.call( this, type, [ event, ui, this ], true );
2219 
2220  // Absolute position and offset (see #6884 ) have to be recalculated after plugins
2221  if ( /^(drag|start|stop)/.test( type ) ) {
2222  this.positionAbs = this._convertPositionTo( "absolute" );
2223  ui.offset = this.positionAbs;
2224  }
2225  return $.Widget.prototype._trigger.call( this, type, event, ui );
2226  },
2227 
2228  plugins: {},
2229 
2230  _uiHash: function() {
2231  return {
2232  helper: this.helper,
2233  position: this.position,
2234  originalPosition: this.originalPosition,
2235  offset: this.positionAbs
2236  };
2237  }
2238 
2239 });
2240 
2241 $.ui.plugin.add( "draggable", "connectToSortable", {
2242  start: function( event, ui, draggable ) {
2243  var uiSortable = $.extend( {}, ui, {
2244  item: draggable.element
2245  });
2246 
2247  draggable.sortables = [];
2248  $( draggable.options.connectToSortable ).each(function() {
2249  var sortable = $( this ).sortable( "instance" );
2250 
2251  if ( sortable && !sortable.options.disabled ) {
2252  draggable.sortables.push( sortable );
2253 
2254  // refreshPositions is called at drag start to refresh the containerCache
2255  // which is used in drag. This ensures it's initialized and synchronized
2256  // with any changes that might have happened on the page since initialization.
2257  sortable.refreshPositions();
2258  sortable._trigger("activate", event, uiSortable);
2259  }
2260  });
2261  },
2262  stop: function( event, ui, draggable ) {
2263  var uiSortable = $.extend( {}, ui, {
2264  item: draggable.element
2265  });
2266 
2267  draggable.cancelHelperRemoval = false;
2268 
2269  $.each( draggable.sortables, function() {
2270  var sortable = this;
2271 
2272  if ( sortable.isOver ) {
2273  sortable.isOver = 0;
2274 
2275  // Allow this sortable to handle removing the helper
2276  draggable.cancelHelperRemoval = true;
2277  sortable.cancelHelperRemoval = false;
2278 
2279  // Use _storedCSS To restore properties in the sortable,
2280  // as this also handles revert (#9675) since the draggable
2281  // may have modified them in unexpected ways (#8809)
2282  sortable._storedCSS = {
2283  position: sortable.placeholder.css( "position" ),
2284  top: sortable.placeholder.css( "top" ),
2285  left: sortable.placeholder.css( "left" )
2286  };
2287 
2288  sortable._mouseStop(event);
2289 
2290  // Once drag has ended, the sortable should return to using
2291  // its original helper, not the shared helper from draggable
2292  sortable.options.helper = sortable.options._helper;
2293  } else {
2294  // Prevent this Sortable from removing the helper.
2295  // However, don't set the draggable to remove the helper
2296  // either as another connected Sortable may yet handle the removal.
2297  sortable.cancelHelperRemoval = true;
2298 
2299  sortable._trigger( "deactivate", event, uiSortable );
2300  }
2301  });
2302  },
2303  drag: function( event, ui, draggable ) {
2304  $.each( draggable.sortables, function() {
2305  var innermostIntersecting = false,
2306  sortable = this;
2307 
2308  // Copy over variables that sortable's _intersectsWith uses
2309  sortable.positionAbs = draggable.positionAbs;
2310  sortable.helperProportions = draggable.helperProportions;
2311  sortable.offset.click = draggable.offset.click;
2312 
2313  if ( sortable._intersectsWith( sortable.containerCache ) ) {
2314  innermostIntersecting = true;
2315 
2316  $.each( draggable.sortables, function() {
2317  // Copy over variables that sortable's _intersectsWith uses
2318  this.positionAbs = draggable.positionAbs;
2319  this.helperProportions = draggable.helperProportions;
2320  this.offset.click = draggable.offset.click;
2321 
2322  if ( this !== sortable &&
2323  this._intersectsWith( this.containerCache ) &&
2324  $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
2325  innermostIntersecting = false;
2326  }
2327 
2328  return innermostIntersecting;
2329  });
2330  }
2331 
2332  if ( innermostIntersecting ) {
2333  // If it intersects, we use a little isOver variable and set it once,
2334  // so that the move-in stuff gets fired only once.
2335  if ( !sortable.isOver ) {
2336  sortable.isOver = 1;
2337 
2338  sortable.currentItem = ui.helper
2339  .appendTo( sortable.element )
2340  .data( "ui-sortable-item", true );
2341 
2342  // Store helper option to later restore it
2343  sortable.options._helper = sortable.options.helper;
2344 
2345  sortable.options.helper = function() {
2346  return ui.helper[ 0 ];
2347  };
2348 
2349  // Fire the start events of the sortable with our passed browser event,
2350  // and our own helper (so it doesn't create a new one)
2351  event.target = sortable.currentItem[ 0 ];
2352  sortable._mouseCapture( event, true );
2353  sortable._mouseStart( event, true, true );
2354 
2355  // Because the browser event is way off the new appended portlet,
2356  // modify necessary variables to reflect the changes
2357  sortable.offset.click.top = draggable.offset.click.top;
2358  sortable.offset.click.left = draggable.offset.click.left;
2359  sortable.offset.parent.left -= draggable.offset.parent.left -
2360  sortable.offset.parent.left;
2361  sortable.offset.parent.top -= draggable.offset.parent.top -
2362  sortable.offset.parent.top;
2363 
2364  draggable._trigger( "toSortable", event );
2365 
2366  // Inform draggable that the helper is in a valid drop zone,
2367  // used solely in the revert option to handle "valid/invalid".
2368  draggable.dropped = sortable.element;
2369 
2370  // Need to refreshPositions of all sortables in the case that
2371  // adding to one sortable changes the location of the other sortables (#9675)
2372  $.each( draggable.sortables, function() {
2373  this.refreshPositions();
2374  });
2375 
2376  // hack so receive/update callbacks work (mostly)
2377  draggable.currentItem = draggable.element;
2378  sortable.fromOutside = draggable;
2379  }
2380 
2381  if ( sortable.currentItem ) {
2382  sortable._mouseDrag( event );
2383  // Copy the sortable's position because the draggable's can potentially reflect
2384  // a relative position, while sortable is always absolute, which the dragged
2385  // element has now become. (#8809)
2386  ui.position = sortable.position;
2387  }
2388  } else {
2389  // If it doesn't intersect with the sortable, and it intersected before,
2390  // we fake the drag stop of the sortable, but make sure it doesn't remove
2391  // the helper by using cancelHelperRemoval.
2392  if ( sortable.isOver ) {
2393 
2394  sortable.isOver = 0;
2395  sortable.cancelHelperRemoval = true;
2396 
2397  // Calling sortable's mouseStop would trigger a revert,
2398  // so revert must be temporarily false until after mouseStop is called.
2399  sortable.options._revert = sortable.options.revert;
2400  sortable.options.revert = false;
2401 
2402  sortable._trigger( "out", event, sortable._uiHash( sortable ) );
2403  sortable._mouseStop( event, true );
2404 
2405  // restore sortable behaviors that were modfied
2406  // when the draggable entered the sortable area (#9481)
2407  sortable.options.revert = sortable.options._revert;
2408  sortable.options.helper = sortable.options._helper;
2409 
2410  if ( sortable.placeholder ) {
2411  sortable.placeholder.remove();
2412  }
2413 
2414  // Recalculate the draggable's offset considering the sortable
2415  // may have modified them in unexpected ways (#8809)
2416  draggable._refreshOffsets( event );
2417  ui.position = draggable._generatePosition( event, true );
2418 
2419  draggable._trigger( "fromSortable", event );
2420 
2421  // Inform draggable that the helper is no longer in a valid drop zone
2422  draggable.dropped = false;
2423 
2424  // Need to refreshPositions of all sortables just in case removing
2425  // from one sortable changes the location of other sortables (#9675)
2426  $.each( draggable.sortables, function() {
2427  this.refreshPositions();
2428  });
2429  }
2430  }
2431  });
2432  }
2433 });
2434 
2435 $.ui.plugin.add("draggable", "cursor", {
2436  start: function( event, ui, instance ) {
2437  var t = $( "body" ),
2438  o = instance.options;
2439 
2440  if (t.css("cursor")) {
2441  o._cursor = t.css("cursor");
2442  }
2443  t.css("cursor", o.cursor);
2444  },
2445  stop: function( event, ui, instance ) {
2446  var o = instance.options;
2447  if (o._cursor) {
2448  $("body").css("cursor", o._cursor);
2449  }
2450  }
2451 });
2452 
2453 $.ui.plugin.add("draggable", "opacity", {
2454  start: function( event, ui, instance ) {
2455  var t = $( ui.helper ),
2456  o = instance.options;
2457  if (t.css("opacity")) {
2458  o._opacity = t.css("opacity");
2459  }
2460  t.css("opacity", o.opacity);
2461  },
2462  stop: function( event, ui, instance ) {
2463  var o = instance.options;
2464  if (o._opacity) {
2465  $(ui.helper).css("opacity", o._opacity);
2466  }
2467  }
2468 });
2469 
2470 $.ui.plugin.add("draggable", "scroll", {
2471  start: function( event, ui, i ) {
2472  if ( !i.scrollParentNotHidden ) {
2473  i.scrollParentNotHidden = i.helper.scrollParent( false );
2474  }
2475 
2476  if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
2477  i.overflowOffset = i.scrollParentNotHidden.offset();
2478  }
2479  },
2480  drag: function( event, ui, i ) {
2481 
2482  var o = i.options,
2483  scrolled = false,
2484  scrollParent = i.scrollParentNotHidden[ 0 ],
2485  document = i.document[ 0 ];
2486 
2487  if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
2488  if ( !o.axis || o.axis !== "x" ) {
2489  if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
2490  scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
2491  } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
2492  scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
2493  }
2494  }
2495 
2496  if ( !o.axis || o.axis !== "y" ) {
2497  if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
2498  scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
2499  } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
2500  scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
2501  }
2502  }
2503 
2504  } else {
2505 
2506  if (!o.axis || o.axis !== "x") {
2507  if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
2508  scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
2509  } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
2510  scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
2511  }
2512  }
2513 
2514  if (!o.axis || o.axis !== "y") {
2515  if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
2516  scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
2517  } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
2518  scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
2519  }
2520  }
2521 
2522  }
2523 
2524  if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
2525  $.ui.ddmanager.prepareOffsets(i, event);
2526  }
2527 
2528  }
2529 });
2530 
2531 $.ui.plugin.add("draggable", "snap", {
2532  start: function( event, ui, i ) {
2533 
2534  var o = i.options;
2535 
2536  i.snapElements = [];
2537 
2538  $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
2539  var $t = $(this),
2540  $o = $t.offset();
2541  if (this !== i.element[0]) {
2542  i.snapElements.push({
2543  item: this,
2544  width: $t.outerWidth(), height: $t.outerHeight(),
2545  top: $o.top, left: $o.left
2546  });
2547  }
2548  });
2549 
2550  },
2551  drag: function( event, ui, inst ) {
2552 
2553  var ts, bs, ls, rs, l, r, t, b, i, first,
2554  o = inst.options,
2555  d = o.snapTolerance,
2556  x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
2557  y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
2558 
2559  for (i = inst.snapElements.length - 1; i >= 0; i--){
2560 
2561  l = inst.snapElements[i].left - inst.margins.left;
2562  r = l + inst.snapElements[i].width;
2563  t = inst.snapElements[i].top - inst.margins.top;
2564  b = t + inst.snapElements[i].height;
2565 
2566  if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
2567  if (inst.snapElements[i].snapping) {
2568  (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2569  }
2570  inst.snapElements[i].snapping = false;
2571  continue;
2572  }
2573 
2574  if (o.snapMode !== "inner") {
2575  ts = Math.abs(t - y2) <= d;
2576  bs = Math.abs(b - y1) <= d;
2577  ls = Math.abs(l - x2) <= d;
2578  rs = Math.abs(r - x1) <= d;
2579  if (ts) {
2580  ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
2581  }
2582  if (bs) {
2583  ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
2584  }
2585  if (ls) {
2586  ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
2587  }
2588  if (rs) {
2589  ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
2590  }
2591  }
2592 
2593  first = (ts || bs || ls || rs);
2594 
2595  if (o.snapMode !== "outer") {
2596  ts = Math.abs(t - y1) <= d;
2597  bs = Math.abs(b - y2) <= d;
2598  ls = Math.abs(l - x1) <= d;
2599  rs = Math.abs(r - x2) <= d;
2600  if (ts) {
2601  ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
2602  }
2603  if (bs) {
2604  ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
2605  }
2606  if (ls) {
2607  ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
2608  }
2609  if (rs) {
2610  ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
2611  }
2612  }
2613 
2614  if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
2615  (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2616  }
2617  inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
2618 
2619  }
2620 
2621  }
2622 });
2623 
2624 $.ui.plugin.add("draggable", "stack", {
2625  start: function( event, ui, instance ) {
2626  var min,
2627  o = instance.options,
2628  group = $.makeArray($(o.stack)).sort(function(a, b) {
2629  return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
2630  });
2631 
2632  if (!group.length) { return; }
2633 
2634  min = parseInt($(group[0]).css("zIndex"), 10) || 0;
2635  $(group).each(function(i) {
2636  $(this).css("zIndex", min + i);
2637  });
2638  this.css("zIndex", (min + group.length));
2639  }
2640 });
2641 
2642 $.ui.plugin.add("draggable", "zIndex", {
2643  start: function( event, ui, instance ) {
2644  var t = $( ui.helper ),
2645  o = instance.options;
2646 
2647  if (t.css("zIndex")) {
2648  o._zIndex = t.css("zIndex");
2649  }
2650  t.css("zIndex", o.zIndex);
2651  },
2652  stop: function( event, ui, instance ) {
2653  var o = instance.options;
2654 
2655  if (o._zIndex) {
2656  $(ui.helper).css("zIndex", o._zIndex);
2657  }
2658  }
2659 });
2660 
2661 var draggable = $.ui.draggable;
2662 
2663 
2664 /*!
2665  * jQuery UI Droppable 1.11.2
2666  * http://jqueryui.com
2667  *
2668  * Copyright 2014 jQuery Foundation and other contributors
2669  * Released under the MIT license.
2670  * http://jquery.org/license
2671  *
2672  * http://api.jqueryui.com/droppable/
2673  */
2674 
2675 
2676 $.widget( "ui.droppable", {
2677  version: "1.11.2",
2678  widgetEventPrefix: "drop",
2679  options: {
2680  accept: "*",
2681  activeClass: false,
2682  addClasses: true,
2683  greedy: false,
2684  hoverClass: false,
2685  scope: "default",
2686  tolerance: "intersect",
2687 
2688  // callbacks
2689  activate: null,
2690  deactivate: null,
2691  drop: null,
2692  out: null,
2693  over: null
2694  },
2695  _create: function() {
2696 
2697  var proportions,
2698  o = this.options,
2699  accept = o.accept;
2700 
2701  this.isover = false;
2702  this.isout = true;
2703 
2704  this.accept = $.isFunction( accept ) ? accept : function( d ) {
2705  return d.is( accept );
2706  };
2707 
2708  this.proportions = function( /* valueToWrite */ ) {
2709  if ( arguments.length ) {
2710  // Store the droppable's proportions
2711  proportions = arguments[ 0 ];
2712  } else {
2713  // Retrieve or derive the droppable's proportions
2714  return proportions ?
2715  proportions :
2716  proportions = {
2717  width: this.element[ 0 ].offsetWidth,
2718  height: this.element[ 0 ].offsetHeight
2719  };
2720  }
2721  };
2722 
2723  this._addToManager( o.scope );
2724 
2725  o.addClasses && this.element.addClass( "ui-droppable" );
2726 
2727  },
2728 
2729  _addToManager: function( scope ) {
2730  // Add the reference and positions to the manager
2731  $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
2732  $.ui.ddmanager.droppables[ scope ].push( this );
2733  },
2734 
2735  _splice: function( drop ) {
2736  var i = 0;
2737  for ( ; i < drop.length; i++ ) {
2738  if ( drop[ i ] === this ) {
2739  drop.splice( i, 1 );
2740  }
2741  }
2742  },
2743 
2744  _destroy: function() {
2745  var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2746 
2747  this._splice( drop );
2748 
2749  this.element.removeClass( "ui-droppable ui-droppable-disabled" );
2750  },
2751 
2752  _setOption: function( key, value ) {
2753 
2754  if ( key === "accept" ) {
2755  this.accept = $.isFunction( value ) ? value : function( d ) {
2756  return d.is( value );
2757  };
2758  } else if ( key === "scope" ) {
2759  var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2760 
2761  this._splice( drop );
2762  this._addToManager( value );
2763  }
2764 
2765  this._super( key, value );
2766  },
2767 
2768  _activate: function( event ) {
2769  var draggable = $.ui.ddmanager.current;
2770  if ( this.options.activeClass ) {
2771  this.element.addClass( this.options.activeClass );
2772  }
2773  if ( draggable ){
2774  this._trigger( "activate", event, this.ui( draggable ) );
2775  }
2776  },
2777 
2778  _deactivate: function( event ) {
2779  var draggable = $.ui.ddmanager.current;
2780  if ( this.options.activeClass ) {
2781  this.element.removeClass( this.options.activeClass );
2782  }
2783  if ( draggable ){
2784  this._trigger( "deactivate", event, this.ui( draggable ) );
2785  }
2786  },
2787 
2788  _over: function( event ) {
2789 
2790  var draggable = $.ui.ddmanager.current;
2791 
2792  // Bail if draggable and droppable are same element
2793  if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2794  return;
2795  }
2796 
2797  if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2798  if ( this.options.hoverClass ) {
2799  this.element.addClass( this.options.hoverClass );
2800  }
2801  this._trigger( "over", event, this.ui( draggable ) );
2802  }
2803 
2804  },
2805 
2806  _out: function( event ) {
2807 
2808  var draggable = $.ui.ddmanager.current;
2809 
2810  // Bail if draggable and droppable are same element
2811  if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2812  return;
2813  }
2814 
2815  if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2816  if ( this.options.hoverClass ) {
2817  this.element.removeClass( this.options.hoverClass );
2818  }
2819  this._trigger( "out", event, this.ui( draggable ) );
2820  }
2821 
2822  },
2823 
2824  _drop: function( event, custom ) {
2825 
2826  var draggable = custom || $.ui.ddmanager.current,
2827  childrenIntersection = false;
2828 
2829  // Bail if draggable and droppable are same element
2830  if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2831  return false;
2832  }
2833 
2834  this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
2835  var inst = $( this ).droppable( "instance" );
2836  if (
2837  inst.options.greedy &&
2838  !inst.options.disabled &&
2839  inst.options.scope === draggable.options.scope &&
2840  inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
2841  $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
2842  ) { childrenIntersection = true; return false; }
2843  });
2844  if ( childrenIntersection ) {
2845  return false;
2846  }
2847 
2848  if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2849  if ( this.options.activeClass ) {
2850  this.element.removeClass( this.options.activeClass );
2851  }
2852  if ( this.options.hoverClass ) {
2853  this.element.removeClass( this.options.hoverClass );
2854  }
2855  this._trigger( "drop", event, this.ui( draggable ) );
2856  return this.element;
2857  }
2858 
2859  return false;
2860 
2861  },
2862 
2863  ui: function( c ) {
2864  return {
2865  draggable: ( c.currentItem || c.element ),
2866  helper: c.helper,
2867  position: c.position,
2868  offset: c.positionAbs
2869  };
2870  }
2871 
2872 });
2873 
2874 $.ui.intersect = (function() {
2875  function isOverAxis( x, reference, size ) {
2876  return ( x >= reference ) && ( x < ( reference + size ) );
2877  }
2878 
2879  return function( draggable, droppable, toleranceMode, event ) {
2880 
2881  if ( !droppable.offset ) {
2882  return false;
2883  }
2884 
2885  var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
2886  y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
2887  x2 = x1 + draggable.helperProportions.width,
2888  y2 = y1 + draggable.helperProportions.height,
2889  l = droppable.offset.left,
2890  t = droppable.offset.top,
2891  r = l + droppable.proportions().width,
2892  b = t + droppable.proportions().height;
2893 
2894  switch ( toleranceMode ) {
2895  case "fit":
2896  return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
2897  case "intersect":
2898  return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
2899  x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
2900  t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
2901  y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
2902  case "pointer":
2903  return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
2904  case "touch":
2905  return (
2906  ( y1 >= t && y1 <= b ) || // Top edge touching
2907  ( y2 >= t && y2 <= b ) || // Bottom edge touching
2908  ( y1 < t && y2 > b ) // Surrounded vertically
2909  ) && (
2910  ( x1 >= l && x1 <= r ) || // Left edge touching
2911  ( x2 >= l && x2 <= r ) || // Right edge touching
2912  ( x1 < l && x2 > r ) // Surrounded horizontally
2913  );
2914  default:
2915  return false;
2916  }
2917  };
2918 })();
2919 
2920 /*
2921  This manager tracks offsets of draggables and droppables
2922 */
2923 $.ui.ddmanager = {
2924  current: null,
2925  droppables: { "default": [] },
2926  prepareOffsets: function( t, event ) {
2927 
2928  var i, j,
2929  m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
2930  type = event ? event.type : null, // workaround for #2317
2931  list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
2932 
2933  droppablesLoop: for ( i = 0; i < m.length; i++ ) {
2934 
2935  // No disabled and non-accepted
2936  if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
2937  continue;
2938  }
2939 
2940  // Filter out elements in the current dragged item
2941  for ( j = 0; j < list.length; j++ ) {
2942  if ( list[ j ] === m[ i ].element[ 0 ] ) {
2943  m[ i ].proportions().height = 0;
2944  continue droppablesLoop;
2945  }
2946  }
2947 
2948  m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
2949  if ( !m[ i ].visible ) {
2950  continue;
2951  }
2952 
2953  // Activate the droppable if used directly from draggables
2954  if ( type === "mousedown" ) {
2955  m[ i ]._activate.call( m[ i ], event );
2956  }
2957 
2958  m[ i ].offset = m[ i ].element.offset();
2959  m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
2960 
2961  }
2962 
2963  },
2964  drop: function( draggable, event ) {
2965 
2966  var dropped = false;
2967  // Create a copy of the droppables in case the list changes during the drop (#9116)
2968  $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
2969 
2970  if ( !this.options ) {
2971  return;
2972  }
2973  if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
2974  dropped = this._drop.call( this, event ) || dropped;
2975  }
2976 
2977  if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2978  this.isout = true;
2979  this.isover = false;
2980  this._deactivate.call( this, event );
2981  }
2982 
2983  });
2984  return dropped;
2985 
2986  },
2987  dragStart: function( draggable, event ) {
2988  // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2989  draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2990  if ( !draggable.options.refreshPositions ) {
2991  $.ui.ddmanager.prepareOffsets( draggable, event );
2992  }
2993  });
2994  },
2995  drag: function( draggable, event ) {
2996 
2997  // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2998  if ( draggable.options.refreshPositions ) {
2999  $.ui.ddmanager.prepareOffsets( draggable, event );
3000  }
3001 
3002  // Run through all droppables and check their positions based on specific tolerance options
3003  $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
3004 
3005  if ( this.options.disabled || this.greedyChild || !this.visible ) {
3006  return;
3007  }
3008 
3009  var parentInstance, scope, parent,
3010  intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
3011  c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
3012  if ( !c ) {
3013  return;
3014  }
3015 
3016  if ( this.options.greedy ) {
3017  // find droppable parents with same scope
3018  scope = this.options.scope;
3019  parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
3020  return $( this ).droppable( "instance" ).options.scope === scope;
3021  });
3022 
3023  if ( parent.length ) {
3024  parentInstance = $( parent[ 0 ] ).droppable( "instance" );
3025  parentInstance.greedyChild = ( c === "isover" );
3026  }
3027  }
3028 
3029  // we just moved into a greedy child
3030  if ( parentInstance && c === "isover" ) {
3031  parentInstance.isover = false;
3032  parentInstance.isout = true;
3033  parentInstance._out.call( parentInstance, event );
3034  }
3035 
3036  this[ c ] = true;
3037  this[c === "isout" ? "isover" : "isout"] = false;
3038  this[c === "isover" ? "_over" : "_out"].call( this, event );
3039 
3040  // we just moved out of a greedy child
3041  if ( parentInstance && c === "isout" ) {
3042  parentInstance.isout = false;
3043  parentInstance.isover = true;
3044  parentInstance._over.call( parentInstance, event );
3045  }
3046  });
3047 
3048  },
3049  dragStop: function( draggable, event ) {
3050  draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
3051  // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
3052  if ( !draggable.options.refreshPositions ) {
3053  $.ui.ddmanager.prepareOffsets( draggable, event );
3054  }
3055  }
3056 };
3057 
3058 var droppable = $.ui.droppable;
3059 
3060 
3061 /*!
3062  * jQuery UI Resizable 1.11.2
3063  * http://jqueryui.com
3064  *
3065  * Copyright 2014 jQuery Foundation and other contributors
3066  * Released under the MIT license.
3067  * http://jquery.org/license
3068  *
3069  * http://api.jqueryui.com/resizable/
3070  */
3071 
3072 
3073 $.widget("ui.resizable", $.ui.mouse, {
3074  version: "1.11.2",
3075  widgetEventPrefix: "resize",
3076  options: {
3077  alsoResize: false,
3078  animate: false,
3079  animateDuration: "slow",
3080  animateEasing: "swing",
3081  aspectRatio: false,
3082  autoHide: false,
3083  containment: false,
3084  ghost: false,
3085  grid: false,
3086  handles: "e,s,se",
3087  helper: false,
3088  maxHeight: null,
3089  maxWidth: null,
3090  minHeight: 10,
3091  minWidth: 10,
3092  // See #7960
3093  zIndex: 90,
3094 
3095  // callbacks
3096  resize: null,
3097  start: null,
3098  stop: null
3099  },
3100 
3101  _num: function( value ) {
3102  return parseInt( value, 10 ) || 0;
3103  },
3104 
3105  _isNumber: function( value ) {
3106  return !isNaN( parseInt( value, 10 ) );
3107  },
3108 
3109  _hasScroll: function( el, a ) {
3110 
3111  if ( $( el ).css( "overflow" ) === "hidden") {
3112  return false;
3113  }
3114 
3115  var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
3116  has = false;
3117 
3118  if ( el[ scroll ] > 0 ) {
3119  return true;
3120  }
3121 
3122  // TODO: determine which cases actually cause this to happen
3123  // if the element doesn't have the scroll set, see if it's possible to
3124  // set the scroll
3125  el[ scroll ] = 1;
3126  has = ( el[ scroll ] > 0 );
3127  el[ scroll ] = 0;
3128  return has;
3129  },
3130 
3131  _create: function() {
3132 
3133  var n, i, handle, axis, hname,
3134  that = this,
3135  o = this.options;
3136  this.element.addClass("ui-resizable");
3137 
3138  $.extend(this, {
3139  _aspectRatio: !!(o.aspectRatio),
3140  aspectRatio: o.aspectRatio,
3141  originalElement: this.element,
3142  _proportionallyResizeElements: [],
3143  _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
3144  });
3145 
3146  // Wrap the element if it cannot hold child nodes
3147  if (this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
3148 
3149  this.element.wrap(
3150  $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
3151  position: this.element.css("position"),
3152  width: this.element.outerWidth(),
3153  height: this.element.outerHeight(),
3154  top: this.element.css("top"),
3155  left: this.element.css("left")
3156  })
3157  );
3158 
3159  this.element = this.element.parent().data(
3160  "ui-resizable", this.element.resizable( "instance" )
3161  );
3162 
3163  this.elementIsWrapper = true;
3164 
3165  this.element.css({
3166  marginLeft: this.originalElement.css("marginLeft"),
3167  marginTop: this.originalElement.css("marginTop"),
3168  marginRight: this.originalElement.css("marginRight"),
3169  marginBottom: this.originalElement.css("marginBottom")
3170  });
3171  this.originalElement.css({
3172  marginLeft: 0,
3173  marginTop: 0,
3174  marginRight: 0,
3175  marginBottom: 0
3176  });
3177  // support: Safari
3178  // Prevent Safari textarea resize
3179  this.originalResizeStyle = this.originalElement.css("resize");
3180  this.originalElement.css("resize", "none");
3181 
3182  this._proportionallyResizeElements.push( this.originalElement.css({
3183  position: "static",
3184  zoom: 1,
3185  display: "block"
3186  }) );
3187 
3188  // support: IE9
3189  // avoid IE jump (hard set the margin)
3190  this.originalElement.css({ margin: this.originalElement.css("margin") });
3191 
3192  this._proportionallyResize();
3193  }
3194 
3195  this.handles = o.handles ||
3196  ( !$(".ui-resizable-handle", this.element).length ?
3197  "e,s,se" : {
3198  n: ".ui-resizable-n",
3199  e: ".ui-resizable-e",
3200  s: ".ui-resizable-s",
3201  w: ".ui-resizable-w",
3202  se: ".ui-resizable-se",
3203  sw: ".ui-resizable-sw",
3204  ne: ".ui-resizable-ne",
3205  nw: ".ui-resizable-nw"
3206  } );
3207 
3208  if (this.handles.constructor === String) {
3209 
3210  if ( this.handles === "all") {
3211  this.handles = "n,e,s,w,se,sw,ne,nw";
3212  }
3213 
3214  n = this.handles.split(",");
3215  this.handles = {};
3216 
3217  for (i = 0; i < n.length; i++) {
3218 
3219  handle = $.trim(n[i]);
3220  hname = "ui-resizable-" + handle;
3221  axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
3222 
3223  axis.css({ zIndex: o.zIndex });
3224 
3225  // TODO : What's going on here?
3226  if ("se" === handle) {
3227  axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
3228  }
3229 
3230  this.handles[handle] = ".ui-resizable-" + handle;
3231  this.element.append(axis);
3232  }
3233 
3234  }
3235 
3236  this._renderAxis = function(target) {
3237 
3238  var i, axis, padPos, padWrapper;
3239 
3240  target = target || this.element;
3241 
3242  for (i in this.handles) {
3243 
3244  if (this.handles[i].constructor === String) {
3245  this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
3246  }
3247 
3248  if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
3249 
3250  axis = $(this.handles[i], this.element);
3251 
3252  padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
3253 
3254  padPos = [ "padding",
3255  /ne|nw|n/.test(i) ? "Top" :
3256  /se|sw|s/.test(i) ? "Bottom" :
3257  /^e$/.test(i) ? "Right" : "Left" ].join("");
3258 
3259  target.css(padPos, padWrapper);
3260 
3261  this._proportionallyResize();
3262 
3263  }
3264 
3265  // TODO: What's that good for? There's not anything to be executed left
3266  if (!$(this.handles[i]).length) {
3267  continue;
3268  }
3269  }
3270  };
3271 
3272  // TODO: make renderAxis a prototype function
3273  this._renderAxis(this.element);
3274 
3275  this._handles = $(".ui-resizable-handle", this.element)
3276  .disableSelection();
3277 
3278  this._handles.mouseover(function() {
3279  if (!that.resizing) {
3280  if (this.className) {
3281  axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
3282  }
3283  that.axis = axis && axis[1] ? axis[1] : "se";
3284  }
3285  });
3286 
3287  if (o.autoHide) {
3288  this._handles.hide();
3289  $(this.element)
3290  .addClass("ui-resizable-autohide")
3291  .mouseenter(function() {
3292  if (o.disabled) {
3293  return;
3294  }
3295  $(this).removeClass("ui-resizable-autohide");
3296  that._handles.show();
3297  })
3298  .mouseleave(function() {
3299  if (o.disabled) {
3300  return;
3301  }
3302  if (!that.resizing) {
3303  $(this).addClass("ui-resizable-autohide");
3304  that._handles.hide();
3305  }
3306  });
3307  }
3308 
3309  this._mouseInit();
3310 
3311  },
3312 
3313  _destroy: function() {
3314 
3315  this._mouseDestroy();
3316 
3317  var wrapper,
3318  _destroy = function(exp) {
3319  $(exp)
3320  .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
3321  .removeData("resizable")
3322  .removeData("ui-resizable")
3323  .unbind(".resizable")
3324  .find(".ui-resizable-handle")
3325  .remove();
3326  };
3327 
3328  // TODO: Unwrap at same DOM position
3329  if (this.elementIsWrapper) {
3330  _destroy(this.element);
3331  wrapper = this.element;
3332  this.originalElement.css({
3333  position: wrapper.css("position"),
3334  width: wrapper.outerWidth(),
3335  height: wrapper.outerHeight(),
3336  top: wrapper.css("top"),
3337  left: wrapper.css("left")
3338  }).insertAfter( wrapper );
3339  wrapper.remove();
3340  }
3341 
3342  this.originalElement.css("resize", this.originalResizeStyle);
3343  _destroy(this.originalElement);
3344 
3345  return this;
3346  },
3347 
3348  _mouseCapture: function(event) {
3349  var i, handle,
3350  capture = false;
3351 
3352  for (i in this.handles) {
3353  handle = $(this.handles[i])[0];
3354  if (handle === event.target || $.contains(handle, event.target)) {
3355  capture = true;
3356  }
3357  }
3358 
3359  return !this.options.disabled && capture;
3360  },
3361 
3362  _mouseStart: function(event) {
3363 
3364  var curleft, curtop, cursor,
3365  o = this.options,
3366  el = this.element;
3367 
3368  this.resizing = true;
3369 
3370  this._renderProxy();
3371 
3372  curleft = this._num(this.helper.css("left"));
3373  curtop = this._num(this.helper.css("top"));
3374 
3375  if (o.containment) {
3376  curleft += $(o.containment).scrollLeft() || 0;
3377  curtop += $(o.containment).scrollTop() || 0;
3378  }
3379 
3380  this.offset = this.helper.offset();
3381  this.position = { left: curleft, top: curtop };
3382 
3383  this.size = this._helper ? {
3384  width: this.helper.width(),
3385  height: this.helper.height()
3386  } : {
3387  width: el.width(),
3388  height: el.height()
3389  };
3390 
3391  this.originalSize = this._helper ? {
3392  width: el.outerWidth(),
3393  height: el.outerHeight()
3394  } : {
3395  width: el.width(),
3396  height: el.height()
3397  };
3398 
3399  this.sizeDiff = {
3400  width: el.outerWidth() - el.width(),
3401  height: el.outerHeight() - el.height()
3402  };
3403 
3404  this.originalPosition = { left: curleft, top: curtop };
3405  this.originalMousePosition = { left: event.pageX, top: event.pageY };
3406 
3407  this.aspectRatio = (typeof o.aspectRatio === "number") ?
3408  o.aspectRatio :
3409  ((this.originalSize.width / this.originalSize.height) || 1);
3410 
3411  cursor = $(".ui-resizable-" + this.axis).css("cursor");
3412  $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
3413 
3414  el.addClass("ui-resizable-resizing");
3415  this._propagate("start", event);
3416  return true;
3417  },
3418 
3419  _mouseDrag: function(event) {
3420 
3421  var data, props,
3422  smp = this.originalMousePosition,
3423  a = this.axis,
3424  dx = (event.pageX - smp.left) || 0,
3425  dy = (event.pageY - smp.top) || 0,
3426  trigger = this._change[a];
3427 
3428  this._updatePrevProperties();
3429 
3430  if (!trigger) {
3431  return false;
3432  }
3433 
3434  data = trigger.apply(this, [ event, dx, dy ]);
3435 
3436  this._updateVirtualBoundaries(event.shiftKey);
3437  if (this._aspectRatio || event.shiftKey) {
3438  data = this._updateRatio(data, event);
3439  }
3440 
3441  data = this._respectSize(data, event);
3442 
3443  this._updateCache(data);
3444 
3445  this._propagate("resize", event);
3446 
3447  props = this._applyChanges();
3448 
3449  if ( !this._helper && this._proportionallyResizeElements.length ) {
3450  this._proportionallyResize();
3451  }
3452 
3453  if ( !$.isEmptyObject( props ) ) {
3454  this._updatePrevProperties();
3455  this._trigger( "resize", event, this.ui() );
3456  this._applyChanges();
3457  }
3458 
3459  return false;
3460  },
3461 
3462  _mouseStop: function(event) {
3463 
3464  this.resizing = false;
3465  var pr, ista, soffseth, soffsetw, s, left, top,
3466  o = this.options, that = this;
3467 
3468  if (this._helper) {
3469 
3470  pr = this._proportionallyResizeElements;
3471  ista = pr.length && (/textarea/i).test(pr[0].nodeName);
3472  soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
3473  soffsetw = ista ? 0 : that.sizeDiff.width;
3474 
3475  s = {
3476  width: (that.helper.width() - soffsetw),
3477  height: (that.helper.height() - soffseth)
3478  };
3479  left = (parseInt(that.element.css("left"), 10) +
3480  (that.position.left - that.originalPosition.left)) || null;
3481  top = (parseInt(that.element.css("top"), 10) +
3482  (that.position.top - that.originalPosition.top)) || null;
3483 
3484  if (!o.animate) {
3485  this.element.css($.extend(s, { top: top, left: left }));
3486  }
3487 
3488  that.helper.height(that.size.height);
3489  that.helper.width(that.size.width);
3490 
3491  if (this._helper && !o.animate) {
3492  this._proportionallyResize();
3493  }
3494  }
3495 
3496  $("body").css("cursor", "auto");
3497 
3498  this.element.removeClass("ui-resizable-resizing");
3499 
3500  this._propagate("stop", event);
3501 
3502  if (this._helper) {
3503  this.helper.remove();
3504  }
3505 
3506  return false;
3507 
3508  },
3509 
3510  _updatePrevProperties: function() {
3511  this.prevPosition = {
3512  top: this.position.top,
3513  left: this.position.left
3514  };
3515  this.prevSize = {
3516  width: this.size.width,
3517  height: this.size.height
3518  };
3519  },
3520 
3521  _applyChanges: function() {
3522  var props = {};
3523 
3524  if ( this.position.top !== this.prevPosition.top ) {
3525  props.top = this.position.top + "px";
3526  }
3527  if ( this.position.left !== this.prevPosition.left ) {
3528  props.left = this.position.left + "px";
3529  }
3530  if ( this.size.width !== this.prevSize.width ) {
3531  props.width = this.size.width + "px";
3532  }
3533  if ( this.size.height !== this.prevSize.height ) {
3534  props.height = this.size.height + "px";
3535  }
3536 
3537  this.helper.css( props );
3538 
3539  return props;
3540  },
3541 
3542  _updateVirtualBoundaries: function(forceAspectRatio) {
3543  var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
3544  o = this.options;
3545 
3546  b = {
3547  minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
3548  maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
3549  minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
3550  maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
3551  };
3552 
3553  if (this._aspectRatio || forceAspectRatio) {
3554  pMinWidth = b.minHeight * this.aspectRatio;
3555  pMinHeight = b.minWidth / this.aspectRatio;
3556  pMaxWidth = b.maxHeight * this.aspectRatio;
3557  pMaxHeight = b.maxWidth / this.aspectRatio;
3558 
3559  if (pMinWidth > b.minWidth) {
3560  b.minWidth = pMinWidth;
3561  }
3562  if (pMinHeight > b.minHeight) {
3563  b.minHeight = pMinHeight;
3564  }
3565  if (pMaxWidth < b.maxWidth) {
3566  b.maxWidth = pMaxWidth;
3567  }
3568  if (pMaxHeight < b.maxHeight) {
3569  b.maxHeight = pMaxHeight;
3570  }
3571  }
3572  this._vBoundaries = b;
3573  },
3574 
3575  _updateCache: function(data) {
3576  this.offset = this.helper.offset();
3577  if (this._isNumber(data.left)) {
3578  this.position.left = data.left;
3579  }
3580  if (this._isNumber(data.top)) {
3581  this.position.top = data.top;
3582  }
3583  if (this._isNumber(data.height)) {
3584  this.size.height = data.height;
3585  }
3586  if (this._isNumber(data.width)) {
3587  this.size.width = data.width;
3588  }
3589  },
3590 
3591  _updateRatio: function( data ) {
3592 
3593  var cpos = this.position,
3594  csize = this.size,
3595  a = this.axis;
3596 
3597  if (this._isNumber(data.height)) {
3598  data.width = (data.height * this.aspectRatio);
3599  } else if (this._isNumber(data.width)) {
3600  data.height = (data.width / this.aspectRatio);
3601  }
3602 
3603  if (a === "sw") {
3604  data.left = cpos.left + (csize.width - data.width);
3605  data.top = null;
3606  }
3607  if (a === "nw") {
3608  data.top = cpos.top + (csize.height - data.height);
3609  data.left = cpos.left + (csize.width - data.width);
3610  }
3611 
3612  return data;
3613  },
3614 
3615  _respectSize: function( data ) {
3616 
3617  var o = this._vBoundaries,
3618  a = this.axis,
3619  ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
3620  ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
3621  isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
3622  isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
3623  dw = this.originalPosition.left + this.originalSize.width,
3624  dh = this.position.top + this.size.height,
3625  cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
3626  if (isminw) {
3627  data.width = o.minWidth;
3628  }
3629  if (isminh) {
3630  data.height = o.minHeight;
3631  }
3632  if (ismaxw) {
3633  data.width = o.maxWidth;
3634  }
3635  if (ismaxh) {
3636  data.height = o.maxHeight;
3637  }
3638 
3639  if (isminw && cw) {
3640  data.left = dw - o.minWidth;
3641  }
3642  if (ismaxw && cw) {
3643  data.left = dw - o.maxWidth;
3644  }
3645  if (isminh && ch) {
3646  data.top = dh - o.minHeight;
3647  }
3648  if (ismaxh && ch) {
3649  data.top = dh - o.maxHeight;
3650  }
3651 
3652  // Fixing jump error on top/left - bug #2330
3653  if (!data.width && !data.height && !data.left && data.top) {
3654  data.top = null;
3655  } else if (!data.width && !data.height && !data.top && data.left) {
3656  data.left = null;
3657  }
3658 
3659  return data;
3660  },
3661 
3662  _getPaddingPlusBorderDimensions: function( element ) {
3663  var i = 0,
3664  widths = [],
3665  borders = [
3666  element.css( "borderTopWidth" ),
3667  element.css( "borderRightWidth" ),
3668  element.css( "borderBottomWidth" ),
3669  element.css( "borderLeftWidth" )
3670  ],
3671  paddings = [
3672  element.css( "paddingTop" ),
3673  element.css( "paddingRight" ),
3674  element.css( "paddingBottom" ),
3675  element.css( "paddingLeft" )
3676  ];
3677 
3678  for ( ; i < 4; i++ ) {
3679  widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );
3680  widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );
3681  }
3682 
3683  return {
3684  height: widths[ 0 ] + widths[ 2 ],
3685  width: widths[ 1 ] + widths[ 3 ]
3686  };
3687  },
3688 
3689  _proportionallyResize: function() {
3690 
3691  if (!this._proportionallyResizeElements.length) {
3692  return;
3693  }
3694 
3695  var prel,
3696  i = 0,
3697  element = this.helper || this.element;
3698 
3699  for ( ; i < this._proportionallyResizeElements.length; i++) {
3700 
3701  prel = this._proportionallyResizeElements[i];
3702 
3703  // TODO: Seems like a bug to cache this.outerDimensions
3704  // considering that we are in a loop.
3705  if (!this.outerDimensions) {
3706  this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
3707  }
3708 
3709  prel.css({
3710  height: (element.height() - this.outerDimensions.height) || 0,
3711  width: (element.width() - this.outerDimensions.width) || 0
3712  });
3713 
3714  }
3715 
3716  },
3717 
3718  _renderProxy: function() {
3719 
3720  var el = this.element, o = this.options;
3721  this.elementOffset = el.offset();
3722 
3723  if (this._helper) {
3724 
3725  this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
3726 
3727  this.helper.addClass(this._helper).css({
3728  width: this.element.outerWidth() - 1,
3729  height: this.element.outerHeight() - 1,
3730  position: "absolute",
3731  left: this.elementOffset.left + "px",
3732  top: this.elementOffset.top + "px",
3733  zIndex: ++o.zIndex //TODO: Don't modify option
3734  });
3735 
3736  this.helper
3737  .appendTo("body")
3738  .disableSelection();
3739 
3740  } else {
3741  this.helper = this.element;
3742  }
3743 
3744  },
3745 
3746  _change: {
3747  e: function(event, dx) {
3748  return { width: this.originalSize.width + dx };
3749  },
3750  w: function(event, dx) {
3751  var cs = this.originalSize, sp = this.originalPosition;
3752  return { left: sp.left + dx, width: cs.width - dx };
3753  },
3754  n: function(event, dx, dy) {
3755  var cs = this.originalSize, sp = this.originalPosition;
3756  return { top: sp.top + dy, height: cs.height - dy };
3757  },
3758  s: function(event, dx, dy) {
3759  return { height: this.originalSize.height + dy };
3760  },
3761  se: function(event, dx, dy) {
3762  return $.extend(this._change.s.apply(this, arguments),
3763  this._change.e.apply(this, [ event, dx, dy ]));
3764  },
3765  sw: function(event, dx, dy) {
3766  return $.extend(this._change.s.apply(this, arguments),
3767  this._change.w.apply(this, [ event, dx, dy ]));
3768  },
3769  ne: function(event, dx, dy) {
3770  return $.extend(this._change.n.apply(this, arguments),
3771  this._change.e.apply(this, [ event, dx, dy ]));
3772  },
3773  nw: function(event, dx, dy) {
3774  return $.extend(this._change.n.apply(this, arguments),
3775  this._change.w.apply(this, [ event, dx, dy ]));
3776  }
3777  },
3778 
3779  _propagate: function(n, event) {
3780  $.ui.plugin.call(this, n, [ event, this.ui() ]);
3781  (n !== "resize" && this._trigger(n, event, this.ui()));
3782  },
3783 
3784  plugins: {},
3785 
3786  ui: function() {
3787  return {
3788  originalElement: this.originalElement,
3789  element: this.element,
3790  helper: this.helper,
3791  position: this.position,
3792  size: this.size,
3793  originalSize: this.originalSize,
3794  originalPosition: this.originalPosition
3795  };
3796  }
3797 
3798 });
3799 
3800 /*
3801  * Resizable Extensions
3802  */
3803 
3804 $.ui.plugin.add("resizable", "animate", {
3805 
3806  stop: function( event ) {
3807  var that = $(this).resizable( "instance" ),
3808  o = that.options,
3809  pr = that._proportionallyResizeElements,
3810  ista = pr.length && (/textarea/i).test(pr[0].nodeName),
3811  soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
3812  soffsetw = ista ? 0 : that.sizeDiff.width,
3813  style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
3814  left = (parseInt(that.element.css("left"), 10) +
3815  (that.position.left - that.originalPosition.left)) || null,
3816  top = (parseInt(that.element.css("top"), 10) +
3817  (that.position.top - that.originalPosition.top)) || null;
3818 
3819  that.element.animate(
3820  $.extend(style, top && left ? { top: top, left: left } : {}), {
3821  duration: o.animateDuration,
3822  easing: o.animateEasing,
3823  step: function() {
3824 
3825  var data = {
3826  width: parseInt(that.element.css("width"), 10),
3827  height: parseInt(that.element.css("height"), 10),
3828  top: parseInt(that.element.css("top"), 10),
3829  left: parseInt(that.element.css("left"), 10)
3830  };
3831 
3832  if (pr && pr.length) {
3833  $(pr[0]).css({ width: data.width, height: data.height });
3834  }
3835 
3836  // propagating resize, and updating values for each animation step
3837  that._updateCache(data);
3838  that._propagate("resize", event);
3839 
3840  }
3841  }
3842  );
3843  }
3844 
3845 });
3846 
3847 $.ui.plugin.add( "resizable", "containment", {
3848 
3849  start: function() {
3850  var element, p, co, ch, cw, width, height,
3851  that = $( this ).resizable( "instance" ),
3852  o = that.options,
3853  el = that.element,
3854  oc = o.containment,
3855  ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
3856 
3857  if ( !ce ) {
3858  return;
3859  }
3860 
3861  that.containerElement = $( ce );
3862 
3863  if ( /document/.test( oc ) || oc === document ) {
3864  that.containerOffset = {
3865  left: 0,
3866  top: 0
3867  };
3868  that.containerPosition = {
3869  left: 0,
3870  top: 0
3871  };
3872 
3873  that.parentData = {
3874  element: $( document ),
3875  left: 0,
3876  top: 0,
3877  width: $( document ).width(),
3878  height: $( document ).height() || document.body.parentNode.scrollHeight
3879  };
3880  } else {
3881  element = $( ce );
3882  p = [];
3883  $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
3884  p[ i ] = that._num( element.css( "padding" + name ) );
3885  });
3886 
3887  that.containerOffset = element.offset();
3888  that.containerPosition = element.position();
3889  that.containerSize = {
3890  height: ( element.innerHeight() - p[ 3 ] ),
3891  width: ( element.innerWidth() - p[ 1 ] )
3892  };
3893 
3894  co = that.containerOffset;
3895  ch = that.containerSize.height;
3896  cw = that.containerSize.width;
3897  width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
3898  height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
3899 
3900  that.parentData = {
3901  element: ce,
3902  left: co.left,
3903  top: co.top,
3904  width: width,
3905  height: height
3906  };
3907  }
3908  },
3909 
3910  resize: function( event ) {
3911  var woset, hoset, isParent, isOffsetRelative,
3912  that = $( this ).resizable( "instance" ),
3913  o = that.options,
3914  co = that.containerOffset,
3915  cp = that.position,
3916  pRatio = that._aspectRatio || event.shiftKey,
3917  cop = {
3918  top: 0,
3919  left: 0
3920  },
3921  ce = that.containerElement,
3922  continueResize = true;
3923 
3924  if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
3925  cop = co;
3926  }
3927 
3928  if ( cp.left < ( that._helper ? co.left : 0 ) ) {
3929  that.size.width = that.size.width +
3930  ( that._helper ?
3931  ( that.position.left - co.left ) :
3932  ( that.position.left - cop.left ) );
3933 
3934  if ( pRatio ) {
3935  that.size.height = that.size.width / that.aspectRatio;
3936  continueResize = false;
3937  }
3938  that.position.left = o.helper ? co.left : 0;
3939  }
3940 
3941  if ( cp.top < ( that._helper ? co.top : 0 ) ) {
3942  that.size.height = that.size.height +
3943  ( that._helper ?
3944  ( that.position.top - co.top ) :
3945  that.position.top );
3946 
3947  if ( pRatio ) {
3948  that.size.width = that.size.height * that.aspectRatio;
3949  continueResize = false;
3950  }
3951  that.position.top = that._helper ? co.top : 0;
3952  }
3953 
3954  isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
3955  isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
3956 
3957  if ( isParent && isOffsetRelative ) {
3958  that.offset.left = that.parentData.left + that.position.left;
3959  that.offset.top = that.parentData.top + that.position.top;
3960  } else {
3961  that.offset.left = that.element.offset().left;
3962  that.offset.top = that.element.offset().top;
3963  }
3964 
3965  woset = Math.abs( that.sizeDiff.width +
3966  (that._helper ?
3967  that.offset.left - cop.left :
3968  (that.offset.left - co.left)) );
3969 
3970  hoset = Math.abs( that.sizeDiff.height +
3971  (that._helper ?
3972  that.offset.top - cop.top :
3973  (that.offset.top - co.top)) );
3974 
3975  if ( woset + that.size.width >= that.parentData.width ) {
3976  that.size.width = that.parentData.width - woset;
3977  if ( pRatio ) {
3978  that.size.height = that.size.width / that.aspectRatio;
3979  continueResize = false;
3980  }
3981  }
3982 
3983  if ( hoset + that.size.height >= that.parentData.height ) {
3984  that.size.height = that.parentData.height - hoset;
3985  if ( pRatio ) {
3986  that.size.width = that.size.height * that.aspectRatio;
3987  continueResize = false;
3988  }
3989  }
3990 
3991  if ( !continueResize ){
3992  that.position.left = that.prevPosition.left;
3993  that.position.top = that.prevPosition.top;
3994  that.size.width = that.prevSize.width;
3995  that.size.height = that.prevSize.height;
3996  }
3997  },
3998 
3999  stop: function() {
4000  var that = $( this ).resizable( "instance" ),
4001  o = that.options,
4002  co = that.containerOffset,
4003  cop = that.containerPosition,
4004  ce = that.containerElement,
4005  helper = $( that.helper ),
4006  ho = helper.offset(),
4007  w = helper.outerWidth() - that.sizeDiff.width,
4008  h = helper.outerHeight() - that.sizeDiff.height;
4009 
4010  if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
4011  $( this ).css({
4012  left: ho.left - cop.left - co.left,
4013  width: w,
4014  height: h
4015  });
4016  }
4017 
4018  if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
4019  $( this ).css({
4020  left: ho.left - cop.left - co.left,
4021  width: w,
4022  height: h
4023  });
4024  }
4025  }
4026 });
4027 
4028 $.ui.plugin.add("resizable", "alsoResize", {
4029 
4030  start: function() {
4031  var that = $(this).resizable( "instance" ),
4032  o = that.options,
4033  _store = function(exp) {
4034  $(exp).each(function() {
4035  var el = $(this);
4036  el.data("ui-resizable-alsoresize", {
4037  width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
4038  left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
4039  });
4040  });
4041  };
4042 
4043  if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
4044  if (o.alsoResize.length) {
4045  o.alsoResize = o.alsoResize[0];
4046  _store(o.alsoResize);
4047  } else {
4048  $.each(o.alsoResize, function(exp) {
4049  _store(exp);
4050  });
4051  }
4052  } else {
4053  _store(o.alsoResize);
4054  }
4055  },
4056 
4057  resize: function(event, ui) {
4058  var that = $(this).resizable( "instance" ),
4059  o = that.options,
4060  os = that.originalSize,
4061  op = that.originalPosition,
4062  delta = {
4063  height: (that.size.height - os.height) || 0,
4064  width: (that.size.width - os.width) || 0,
4065  top: (that.position.top - op.top) || 0,
4066  left: (that.position.left - op.left) || 0
4067  },
4068 
4069  _alsoResize = function(exp, c) {
4070  $(exp).each(function() {
4071  var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
4072  css = c && c.length ?
4073  c :
4074  el.parents(ui.originalElement[0]).length ?
4075  [ "width", "height" ] :
4076  [ "width", "height", "top", "left" ];
4077 
4078  $.each(css, function(i, prop) {
4079  var sum = (start[prop] || 0) + (delta[prop] || 0);
4080  if (sum && sum >= 0) {
4081  style[prop] = sum || null;
4082  }
4083  });
4084 
4085  el.css(style);
4086  });
4087  };
4088 
4089  if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
4090  $.each(o.alsoResize, function(exp, c) {
4091  _alsoResize(exp, c);
4092  });
4093  } else {
4094  _alsoResize(o.alsoResize);
4095  }
4096  },
4097 
4098  stop: function() {
4099  $(this).removeData("resizable-alsoresize");
4100  }
4101 });
4102 
4103 $.ui.plugin.add("resizable", "ghost", {
4104 
4105  start: function() {
4106 
4107  var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;
4108 
4109  that.ghost = that.originalElement.clone();
4110  that.ghost
4111  .css({
4112  opacity: 0.25,
4113  display: "block",
4114  position: "relative",
4115  height: cs.height,
4116  width: cs.width,
4117  margin: 0,
4118  left: 0,
4119  top: 0
4120  })
4121  .addClass("ui-resizable-ghost")
4122  .addClass(typeof o.ghost === "string" ? o.ghost : "");
4123 
4124  that.ghost.appendTo(that.helper);
4125 
4126  },
4127 
4128  resize: function() {
4129  var that = $(this).resizable( "instance" );
4130  if (that.ghost) {
4131  that.ghost.css({
4132  position: "relative",
4133  height: that.size.height,
4134  width: that.size.width
4135  });
4136  }
4137  },
4138 
4139  stop: function() {
4140  var that = $(this).resizable( "instance" );
4141  if (that.ghost && that.helper) {
4142  that.helper.get(0).removeChild(that.ghost.get(0));
4143  }
4144  }
4145 
4146 });
4147 
4148 $.ui.plugin.add("resizable", "grid", {
4149 
4150  resize: function() {
4151  var outerDimensions,
4152  that = $(this).resizable( "instance" ),
4153  o = that.options,
4154  cs = that.size,
4155  os = that.originalSize,
4156  op = that.originalPosition,
4157  a = that.axis,
4158  grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
4159  gridX = (grid[0] || 1),
4160  gridY = (grid[1] || 1),
4161  ox = Math.round((cs.width - os.width) / gridX) * gridX,
4162  oy = Math.round((cs.height - os.height) / gridY) * gridY,
4163  newWidth = os.width + ox,
4164  newHeight = os.height + oy,
4165  isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
4166  isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
4167  isMinWidth = o.minWidth && (o.minWidth > newWidth),
4168  isMinHeight = o.minHeight && (o.minHeight > newHeight);
4169 
4170  o.grid = grid;
4171 
4172  if (isMinWidth) {
4173  newWidth += gridX;
4174  }
4175  if (isMinHeight) {
4176  newHeight += gridY;
4177  }
4178  if (isMaxWidth) {
4179  newWidth -= gridX;
4180  }
4181  if (isMaxHeight) {
4182  newHeight -= gridY;
4183  }
4184 
4185  if (/^(se|s|e)$/.test(a)) {
4186  that.size.width = newWidth;
4187  that.size.height = newHeight;
4188  } else if (/^(ne)$/.test(a)) {
4189  that.size.width = newWidth;
4190  that.size.height = newHeight;
4191  that.position.top = op.top - oy;
4192  } else if (/^(sw)$/.test(a)) {
4193  that.size.width = newWidth;
4194  that.size.height = newHeight;
4195  that.position.left = op.left - ox;
4196  } else {
4197  if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {
4198  outerDimensions = that._getPaddingPlusBorderDimensions( this );
4199  }
4200 
4201  if ( newHeight - gridY > 0 ) {
4202  that.size.height = newHeight;
4203  that.position.top = op.top - oy;
4204  } else {
4205  newHeight = gridY - outerDimensions.height;
4206  that.size.height = newHeight;
4207  that.position.top = op.top + os.height - newHeight;
4208  }
4209  if ( newWidth - gridX > 0 ) {
4210  that.size.width = newWidth;
4211  that.position.left = op.left - ox;
4212  } else {
4213  newWidth = gridY - outerDimensions.height;
4214  that.size.width = newWidth;
4215  that.position.left = op.left + os.width - newWidth;
4216  }
4217  }
4218  }
4219 
4220 });
4221 
4222 var resizable = $.ui.resizable;
4223 
4224 
4225 /*!
4226  * jQuery UI Selectable 1.11.2
4227  * http://jqueryui.com
4228  *
4229  * Copyright 2014 jQuery Foundation and other contributors
4230  * Released under the MIT license.
4231  * http://jquery.org/license
4232  *
4233  * http://api.jqueryui.com/selectable/
4234  */
4235 
4236 
4237 var selectable = $.widget("ui.selectable", $.ui.mouse, {
4238  version: "1.11.2",
4239  options: {
4240  appendTo: "body",
4241  autoRefresh: true,
4242  distance: 0,
4243  filter: "*",
4244  tolerance: "touch",
4245 
4246  // callbacks
4247  selected: null,
4248  selecting: null,
4249  start: null,
4250  stop: null,
4251  unselected: null,
4252  unselecting: null
4253  },
4254  _create: function() {
4255  var selectees,
4256  that = this;
4257 
4258  this.element.addClass("ui-selectable");
4259 
4260  this.dragged = false;
4261 
4262  // cache selectee children based on filter
4263  this.refresh = function() {
4264  selectees = $(that.options.filter, that.element[0]);
4265  selectees.addClass("ui-selectee");
4266  selectees.each(function() {
4267  var $this = $(this),
4268  pos = $this.offset();
4269  $.data(this, "selectable-item", {
4270  element: this,
4271  $element: $this,
4272  left: pos.left,
4273  top: pos.top,
4274  right: pos.left + $this.outerWidth(),
4275  bottom: pos.top + $this.outerHeight(),
4276  startselected: false,
4277  selected: $this.hasClass("ui-selected"),
4278  selecting: $this.hasClass("ui-selecting"),
4279  unselecting: $this.hasClass("ui-unselecting")
4280  });
4281  });
4282  };
4283  this.refresh();
4284 
4285  this.selectees = selectees.addClass("ui-selectee");
4286 
4287  this._mouseInit();
4288 
4289  this.helper = $("<div class='ui-selectable-helper'></div>");
4290  },
4291 
4292  _destroy: function() {
4293  this.selectees
4294  .removeClass("ui-selectee")
4295  .removeData("selectable-item");
4296  this.element
4297  .removeClass("ui-selectable ui-selectable-disabled");
4298  this._mouseDestroy();
4299  },
4300 
4301  _mouseStart: function(event) {
4302  var that = this,
4303  options = this.options;
4304 
4305  this.opos = [ event.pageX, event.pageY ];
4306 
4307  if (this.options.disabled) {
4308  return;
4309  }
4310 
4311  this.selectees = $(options.filter, this.element[0]);
4312 
4313  this._trigger("start", event);
4314 
4315  $(options.appendTo).append(this.helper);
4316  // position helper (lasso)
4317  this.helper.css({
4318  "left": event.pageX,
4319  "top": event.pageY,
4320  "width": 0,
4321  "height": 0
4322  });
4323 
4324  if (options.autoRefresh) {
4325  this.refresh();
4326  }
4327 
4328  this.selectees.filter(".ui-selected").each(function() {
4329  var selectee = $.data(this, "selectable-item");
4330  selectee.startselected = true;
4331  if (!event.metaKey && !event.ctrlKey) {
4332  selectee.$element.removeClass("ui-selected");
4333  selectee.selected = false;
4334  selectee.$element.addClass("ui-unselecting");
4335  selectee.unselecting = true;
4336  // selectable UNSELECTING callback
4337  that._trigger("unselecting", event, {
4338  unselecting: selectee.element
4339  });
4340  }
4341  });
4342 
4343  $(event.target).parents().addBack().each(function() {
4344  var doSelect,
4345  selectee = $.data(this, "selectable-item");
4346  if (selectee) {
4347  doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
4348  selectee.$element
4349  .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
4350  .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
4351  selectee.unselecting = !doSelect;
4352  selectee.selecting = doSelect;
4353  selectee.selected = doSelect;
4354  // selectable (UN)SELECTING callback
4355  if (doSelect) {
4356  that._trigger("selecting", event, {
4357  selecting: selectee.element
4358  });
4359  } else {
4360  that._trigger("unselecting", event, {
4361  unselecting: selectee.element
4362  });
4363  }
4364  return false;
4365  }
4366  });
4367 
4368  },
4369 
4370  _mouseDrag: function(event) {
4371 
4372  this.dragged = true;
4373 
4374  if (this.options.disabled) {
4375  return;
4376  }
4377 
4378  var tmp,
4379  that = this,
4380  options = this.options,
4381  x1 = this.opos[0],
4382  y1 = this.opos[1],
4383  x2 = event.pageX,
4384  y2 = event.pageY;
4385 
4386  if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
4387  if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
4388  this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
4389 
4390  this.selectees.each(function() {
4391  var selectee = $.data(this, "selectable-item"),
4392  hit = false;
4393 
4394  //prevent helper from being selected if appendTo: selectable
4395  if (!selectee || selectee.element === that.element[0]) {
4396  return;
4397  }
4398 
4399  if (options.tolerance === "touch") {
4400  hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
4401  } else if (options.tolerance === "fit") {
4402  hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
4403  }
4404 
4405  if (hit) {
4406  // SELECT
4407  if (selectee.selected) {
4408  selectee.$element.removeClass("ui-selected");
4409  selectee.selected = false;
4410  }
4411  if (selectee.unselecting) {
4412  selectee.$element.removeClass("ui-unselecting");
4413  selectee.unselecting = false;
4414  }
4415  if (!selectee.selecting) {
4416  selectee.$element.addClass("ui-selecting");
4417  selectee.selecting = true;
4418  // selectable SELECTING callback
4419  that._trigger("selecting", event, {
4420  selecting: selectee.element
4421  });
4422  }
4423  } else {
4424  // UNSELECT
4425  if (selectee.selecting) {
4426  if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
4427  selectee.$element.removeClass("ui-selecting");
4428  selectee.selecting = false;
4429  selectee.$element.addClass("ui-selected");
4430  selectee.selected = true;
4431  } else {
4432  selectee.$element.removeClass("ui-selecting");
4433  selectee.selecting = false;
4434  if (selectee.startselected) {
4435  selectee.$element.addClass("ui-unselecting");
4436  selectee.unselecting = true;
4437  }
4438  // selectable UNSELECTING callback
4439  that._trigger("unselecting", event, {
4440  unselecting: selectee.element
4441  });
4442  }
4443  }
4444  if (selectee.selected) {
4445  if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
4446  selectee.$element.removeClass("ui-selected");
4447  selectee.selected = false;
4448 
4449  selectee.$element.addClass("ui-unselecting");
4450  selectee.unselecting = true;
4451  // selectable UNSELECTING callback
4452  that._trigger("unselecting", event, {
4453  unselecting: selectee.element
4454  });
4455  }
4456  }
4457  }
4458  });
4459 
4460  return false;
4461  },
4462 
4463  _mouseStop: function(event) {
4464  var that = this;
4465 
4466  this.dragged = false;
4467 
4468  $(".ui-unselecting", this.element[0]).each(function() {
4469  var selectee = $.data(this, "selectable-item");
4470  selectee.$element.removeClass("ui-unselecting");
4471  selectee.unselecting = false;
4472  selectee.startselected = false;
4473  that._trigger("unselected", event, {
4474  unselected: selectee.element
4475  });
4476  });
4477  $(".ui-selecting", this.element[0]).each(function() {
4478  var selectee = $.data(this, "selectable-item");
4479  selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
4480  selectee.selecting = false;
4481  selectee.selected = true;
4482  selectee.startselected = true;
4483  that._trigger("selected", event, {
4484  selected: selectee.element
4485  });
4486  });
4487  this._trigger("stop", event);
4488 
4489  this.helper.remove();
4490 
4491  return false;
4492  }
4493 
4494 });
4495 
4496 
4497 /*!
4498  * jQuery UI Sortable 1.11.2
4499  * http://jqueryui.com
4500  *
4501  * Copyright 2014 jQuery Foundation and other contributors
4502  * Released under the MIT license.
4503  * http://jquery.org/license
4504  *
4505  * http://api.jqueryui.com/sortable/
4506  */
4507 
4508 
4509 var sortable = $.widget("ui.sortable", $.ui.mouse, {
4510  version: "1.11.2",
4511  widgetEventPrefix: "sort",
4512  ready: false,
4513  options: {
4514  appendTo: "parent",
4515  axis: false,
4516  connectWith: false,
4517  containment: false,
4518  cursor: "auto",
4519  cursorAt: false,
4520  dropOnEmpty: true,
4521  forcePlaceholderSize: false,
4522  forceHelperSize: false,
4523  grid: false,
4524  handle: false,
4525  helper: "original",
4526  items: "> *",
4527  opacity: false,
4528  placeholder: false,
4529  revert: false,
4530  scroll: true,
4531  scrollSensitivity: 20,
4532  scrollSpeed: 20,
4533  scope: "default",
4534  tolerance: "intersect",
4535  zIndex: 1000,
4536 
4537  // callbacks
4538  activate: null,
4539  beforeStop: null,
4540  change: null,
4541  deactivate: null,
4542  out: null,
4543  over: null,
4544  receive: null,
4545  remove: null,
4546  sort: null,
4547  start: null,
4548  stop: null,
4549  update: null
4550  },
4551 
4552  _isOverAxis: function( x, reference, size ) {
4553  return ( x >= reference ) && ( x < ( reference + size ) );
4554  },
4555 
4556  _isFloating: function( item ) {
4557  return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
4558  },
4559 
4560  _create: function() {
4561 
4562  var o = this.options;
4563  this.containerCache = {};
4564  this.element.addClass("ui-sortable");
4565 
4566  //Get the items
4567  this.refresh();
4568 
4569  //Let's determine if the items are being displayed horizontally
4570  this.floating = this.items.length ? o.axis === "x" || this._isFloating(this.items[0].item) : false;
4571 
4572  //Let's determine the parent's offset
4573  this.offset = this.element.offset();
4574 
4575  //Initialize mouse events for interaction
4576  this._mouseInit();
4577 
4578  this._setHandleClassName();
4579 
4580  //We're ready to go
4581  this.ready = true;
4582 
4583  },
4584 
4585  _setOption: function( key, value ) {
4586  this._super( key, value );
4587 
4588  if ( key === "handle" ) {
4589  this._setHandleClassName();
4590  }
4591  },
4592 
4593  _setHandleClassName: function() {
4594  this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
4595  $.each( this.items, function() {
4596  ( this.instance.options.handle ?
4597  this.item.find( this.instance.options.handle ) : this.item )
4598  .addClass( "ui-sortable-handle" );
4599  });
4600  },
4601 
4602  _destroy: function() {
4603  this.element
4604  .removeClass( "ui-sortable ui-sortable-disabled" )
4605  .find( ".ui-sortable-handle" )
4606  .removeClass( "ui-sortable-handle" );
4607  this._mouseDestroy();
4608 
4609  for ( var i = this.items.length - 1; i >= 0; i-- ) {
4610  this.items[i].item.removeData(this.widgetName + "-item");
4611  }
4612 
4613  return this;
4614  },
4615 
4616  _mouseCapture: function(event, overrideHandle) {
4617  var currentItem = null,
4618  validHandle = false,
4619  that = this;
4620 
4621  if (this.reverting) {
4622  return false;
4623  }
4624 
4625  if(this.options.disabled || this.options.type === "static") {
4626  return false;
4627  }
4628 
4629  //We have to refresh the items data once first
4630  this._refreshItems(event);
4631 
4632  //Find out if the clicked node (or one of its parents) is a actual item in this.items
4633  $(event.target).parents().each(function() {
4634  if($.data(this, that.widgetName + "-item") === that) {
4635  currentItem = $(this);
4636  return false;
4637  }
4638  });
4639  if($.data(event.target, that.widgetName + "-item") === that) {
4640  currentItem = $(event.target);
4641  }
4642 
4643  if(!currentItem) {
4644  return false;
4645  }
4646  if(this.options.handle && !overrideHandle) {
4647  $(this.options.handle, currentItem).find("*").addBack().each(function() {
4648  if(this === event.target) {
4649  validHandle = true;
4650  }
4651  });
4652  if(!validHandle) {
4653  return false;
4654  }
4655  }
4656 
4657  this.currentItem = currentItem;
4658  this._removeCurrentsFromItems();
4659  return true;
4660 
4661  },
4662 
4663  _mouseStart: function(event, overrideHandle, noActivation) {
4664 
4665  var i, body,
4666  o = this.options;
4667 
4668  this.currentContainer = this;
4669 
4670  //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
4671  this.refreshPositions();
4672 
4673  //Create and append the visible helper
4674  this.helper = this._createHelper(event);
4675 
4676  //Cache the helper size
4677  this._cacheHelperProportions();
4678 
4679  /*
4680  * - Position generation -
4681  * This block generates everything position related - it's the core of draggables.
4682  */
4683 
4684  //Cache the margins of the original element
4685  this._cacheMargins();
4686 
4687  //Get the next scrolling parent
4688  this.scrollParent = this.helper.scrollParent();
4689 
4690  //The element's absolute position on the page minus margins
4691  this.offset = this.currentItem.offset();
4692  this.offset = {
4693  top: this.offset.top - this.margins.top,
4694  left: this.offset.left - this.margins.left
4695  };
4696 
4697  $.extend(this.offset, {
4698  click: { //Where the click happened, relative to the element
4699  left: event.pageX - this.offset.left,
4700  top: event.pageY - this.offset.top
4701  },
4702  parent: this._getParentOffset(),
4703  relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
4704  });
4705 
4706  // Only after we got the offset, we can change the helper's position to absolute
4707  // TODO: Still need to figure out a way to make relative sorting possible
4708  this.helper.css("position", "absolute");
4709  this.cssPosition = this.helper.css("position");
4710 
4711  //Generate the original position
4712  this.originalPosition = this._generatePosition(event);
4713  this.originalPageX = event.pageX;
4714  this.originalPageY = event.pageY;
4715 
4716  //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
4717  (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
4718 
4719  //Cache the former DOM position
4720  this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
4721 
4722  //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
4723  if(this.helper[0] !== this.currentItem[0]) {
4724  this.currentItem.hide();
4725  }
4726 
4727  //Create the placeholder
4728  this._createPlaceholder();
4729 
4730  //Set a containment if given in the options
4731  if(o.containment) {
4732  this._setContainment();
4733  }
4734 
4735  if( o.cursor && o.cursor !== "auto" ) { // cursor option
4736  body = this.document.find( "body" );
4737 
4738  // support: IE
4739  this.storedCursor = body.css( "cursor" );
4740  body.css( "cursor", o.cursor );
4741 
4742  this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
4743  }
4744 
4745  if(o.opacity) { // opacity option
4746  if (this.helper.css("opacity")) {
4747  this._storedOpacity = this.helper.css("opacity");
4748  }
4749  this.helper.css("opacity", o.opacity);
4750  }
4751 
4752  if(o.zIndex) { // zIndex option
4753  if (this.helper.css("zIndex")) {
4754  this._storedZIndex = this.helper.css("zIndex");
4755  }
4756  this.helper.css("zIndex", o.zIndex);
4757  }
4758 
4759  //Prepare scrolling
4760  if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
4761  this.overflowOffset = this.scrollParent.offset();
4762  }
4763 
4764  //Call callbacks
4765  this._trigger("start", event, this._uiHash());
4766 
4767  //Recache the helper size
4768  if(!this._preserveHelperProportions) {
4769  this._cacheHelperProportions();
4770  }
4771 
4772 
4773  //Post "activate" events to possible containers
4774  if( !noActivation ) {
4775  for ( i = this.containers.length - 1; i >= 0; i-- ) {
4776  this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
4777  }
4778  }
4779 
4780  //Prepare possible droppables
4781  if($.ui.ddmanager) {
4782  $.ui.ddmanager.current = this;
4783  }
4784 
4785  if ($.ui.ddmanager && !o.dropBehaviour) {
4786  $.ui.ddmanager.prepareOffsets(this, event);
4787  }
4788 
4789  this.dragging = true;
4790 
4791  this.helper.addClass("ui-sortable-helper");
4792  this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
4793  return true;
4794 
4795  },
4796 
4797  _mouseDrag: function(event) {
4798  var i, item, itemElement, intersection,
4799  o = this.options,
4800  scrolled = false;
4801 
4802  //Compute the helpers position
4803  this.position = this._generatePosition(event);
4804  this.positionAbs = this._convertPositionTo("absolute");
4805 
4806  if (!this.lastPositionAbs) {
4807  this.lastPositionAbs = this.positionAbs;
4808  }
4809 
4810  //Do scrolling
4811  if(this.options.scroll) {
4812  if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
4813 
4814  if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
4815  this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
4816  } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
4817  this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
4818  }
4819 
4820  if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
4821  this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
4822  } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
4823  this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
4824  }
4825 
4826  } else {
4827 
4828  if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
4829  scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
4830  } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
4831  scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
4832  }
4833 
4834  if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
4835  scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
4836  } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
4837  scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
4838  }
4839 
4840  }
4841 
4842  if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
4843  $.ui.ddmanager.prepareOffsets(this, event);
4844  }
4845  }
4846 
4847  //Regenerate the absolute position used for position checks
4848  this.positionAbs = this._convertPositionTo("absolute");
4849 
4850  //Set the helper position
4851  if(!this.options.axis || this.options.axis !== "y") {
4852  this.helper[0].style.left = this.position.left+"px";
4853  }
4854  if(!this.options.axis || this.options.axis !== "x") {
4855  this.helper[0].style.top = this.position.top+"px";
4856  }
4857 
4858  //Rearrange
4859  for (i = this.items.length - 1; i >= 0; i--) {
4860 
4861  //Cache variables and intersection, continue if no intersection
4862  item = this.items[i];
4863  itemElement = item.item[0];
4864  intersection = this._intersectsWithPointer(item);
4865  if (!intersection) {
4866  continue;
4867  }
4868 
4869  // Only put the placeholder inside the current Container, skip all
4870  // items from other containers. This works because when moving
4871  // an item from one container to another the
4872  // currentContainer is switched before the placeholder is moved.
4873  //
4874  // Without this, moving items in "sub-sortables" can cause
4875  // the placeholder to jitter between the outer and inner container.
4876  if (item.instance !== this.currentContainer) {
4877  continue;
4878  }
4879 
4880  // cannot intersect with itself
4881  // no useless actions that have been done before
4882  // no action if the item moved is the parent of the item checked
4883  if (itemElement !== this.currentItem[0] &&
4884  this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
4885  !$.contains(this.placeholder[0], itemElement) &&
4886  (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
4887  ) {
4888 
4889  this.direction = intersection === 1 ? "down" : "up";
4890 
4891  if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
4892  this._rearrange(event, item);
4893  } else {
4894  break;
4895  }
4896 
4897  this._trigger("change", event, this._uiHash());
4898  break;
4899  }
4900  }
4901 
4902  //Post events to containers
4903  this._contactContainers(event);
4904 
4905  //Interconnect with droppables
4906  if($.ui.ddmanager) {
4907  $.ui.ddmanager.drag(this, event);
4908  }
4909 
4910  //Call callbacks
4911  this._trigger("sort", event, this._uiHash());
4912 
4913  this.lastPositionAbs = this.positionAbs;
4914  return false;
4915 
4916  },
4917 
4918  _mouseStop: function(event, noPropagation) {
4919 
4920  if(!event) {
4921  return;
4922  }
4923 
4924  //If we are using droppables, inform the manager about the drop
4925  if ($.ui.ddmanager && !this.options.dropBehaviour) {
4926  $.ui.ddmanager.drop(this, event);
4927  }
4928 
4929  if(this.options.revert) {
4930  var that = this,
4931  cur = this.placeholder.offset(),
4932  axis = this.options.axis,
4933  animation = {};
4934 
4935  if ( !axis || axis === "x" ) {
4936  animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
4937  }
4938  if ( !axis || axis === "y" ) {
4939  animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
4940  }
4941  this.reverting = true;
4942  $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
4943  that._clear(event);
4944  });
4945  } else {
4946  this._clear(event, noPropagation);
4947  }
4948 
4949  return false;
4950 
4951  },
4952 
4953  cancel: function() {
4954 
4955  if(this.dragging) {
4956 
4957  this._mouseUp({ target: null });
4958 
4959  if(this.options.helper === "original") {
4960  this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4961  } else {
4962  this.currentItem.show();
4963  }
4964 
4965  //Post deactivating events to containers
4966  for (var i = this.containers.length - 1; i >= 0; i--){
4967  this.containers[i]._trigger("deactivate", null, this._uiHash(this));
4968  if(this.containers[i].containerCache.over) {
4969  this.containers[i]._trigger("out", null, this._uiHash(this));
4970  this.containers[i].containerCache.over = 0;
4971  }
4972  }
4973 
4974  }
4975 
4976  if (this.placeholder) {
4977  //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4978  if(this.placeholder[0].parentNode) {
4979  this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4980  }
4981  if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
4982  this.helper.remove();
4983  }
4984 
4985  $.extend(this, {
4986  helper: null,
4987  dragging: false,
4988  reverting: false,
4989  _noFinalSort: null
4990  });
4991 
4992  if(this.domPosition.prev) {
4993  $(this.domPosition.prev).after(this.currentItem);
4994  } else {
4995  $(this.domPosition.parent).prepend(this.currentItem);
4996  }
4997  }
4998 
4999  return this;
5000 
5001  },
5002 
5003  serialize: function(o) {
5004 
5005  var items = this._getItemsAsjQuery(o && o.connected),
5006  str = [];
5007  o = o || {};
5008 
5009  $(items).each(function() {
5010  var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
5011  if (res) {
5012  str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
5013  }
5014  });
5015 
5016  if(!str.length && o.key) {
5017  str.push(o.key + "=");
5018  }
5019 
5020  return str.join("&");
5021 
5022  },
5023 
5024  toArray: function(o) {
5025 
5026  var items = this._getItemsAsjQuery(o && o.connected),
5027  ret = [];
5028 
5029  o = o || {};
5030 
5031  items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
5032  return ret;
5033 
5034  },
5035 
5036  /* Be careful with the following core functions */
5037  _intersectsWith: function(item) {
5038 
5039  var x1 = this.positionAbs.left,
5040  x2 = x1 + this.helperProportions.width,
5041  y1 = this.positionAbs.top,
5042  y2 = y1 + this.helperProportions.height,
5043  l = item.left,
5044  r = l + item.width,
5045  t = item.top,
5046  b = t + item.height,
5047  dyClick = this.offset.click.top,
5048  dxClick = this.offset.click.left,
5049  isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
5050  isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
5051  isOverElement = isOverElementHeight && isOverElementWidth;
5052 
5053  if ( this.options.tolerance === "pointer" ||
5054  this.options.forcePointerForContainers ||
5055  (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
5056  ) {
5057  return isOverElement;
5058  } else {
5059 
5060  return (l < x1 + (this.helperProportions.width / 2) && // Right Half
5061  x2 - (this.helperProportions.width / 2) < r && // Left Half
5062  t < y1 + (this.helperProportions.height / 2) && // Bottom Half
5063  y2 - (this.helperProportions.height / 2) < b ); // Top Half
5064 
5065  }
5066  },
5067 
5068  _intersectsWithPointer: function(item) {
5069 
5070  var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
5071  isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
5072  isOverElement = isOverElementHeight && isOverElementWidth,
5073  verticalDirection = this._getDragVerticalDirection(),
5074  horizontalDirection = this._getDragHorizontalDirection();
5075 
5076  if (!isOverElement) {
5077  return false;
5078  }
5079 
5080  return this.floating ?
5081  ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
5082  : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
5083 
5084  },
5085 
5086  _intersectsWithSides: function(item) {
5087 
5088  var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
5089  isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
5090  verticalDirection = this._getDragVerticalDirection(),
5091  horizontalDirection = this._getDragHorizontalDirection();
5092 
5093  if (this.floating && horizontalDirection) {
5094  return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
5095  } else {
5096  return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
5097  }
5098 
5099  },
5100 
5101  _getDragVerticalDirection: function() {
5102  var delta = this.positionAbs.top - this.lastPositionAbs.top;
5103  return delta !== 0 && (delta > 0 ? "down" : "up");
5104  },
5105 
5106  _getDragHorizontalDirection: function() {
5107  var delta = this.positionAbs.left - this.lastPositionAbs.left;
5108  return delta !== 0 && (delta > 0 ? "right" : "left");
5109  },
5110 
5111  refresh: function(event) {
5112  this._refreshItems(event);
5113  this._setHandleClassName();
5114  this.refreshPositions();
5115  return this;
5116  },
5117 
5118  _connectWith: function() {
5119  var options = this.options;
5120  return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
5121  },
5122 
5123  _getItemsAsjQuery: function(connected) {
5124 
5125  var i, j, cur, inst,
5126  items = [],
5127  queries = [],
5128  connectWith = this._connectWith();
5129 
5130  if(connectWith && connected) {
5131  for (i = connectWith.length - 1; i >= 0; i--){
5132  cur = $(connectWith[i]);
5133  for ( j = cur.length - 1; j >= 0; j--){
5134  inst = $.data(cur[j], this.widgetFullName);
5135  if(inst && inst !== this && !inst.options.disabled) {
5136  queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]);
5137  }
5138  }
5139  }
5140  }
5141 
5142  queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]);
5143 
5144  function addItems() {
5145  items.push( this );
5146  }
5147  for (i = queries.length - 1; i >= 0; i--){
5148  queries[i][0].each( addItems );
5149  }
5150 
5151  return $(items);
5152 
5153  },
5154 
5155  _removeCurrentsFromItems: function() {
5156 
5157  var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
5158 
5159  this.items = $.grep(this.items, function (item) {
5160  for (var j=0; j < list.length; j++) {
5161  if(list[j] === item.item[0]) {
5162  return false;
5163  }
5164  }
5165  return true;
5166  });
5167 
5168  },
5169 
5170  _refreshItems: function(event) {
5171 
5172  this.items = [];
5173  this.containers = [this];
5174 
5175  var i, j, cur, inst, targetData, _queries, item, queriesLength,
5176  items = this.items,
5177  queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
5178  connectWith = this._connectWith();
5179 
5180  if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
5181  for (i = connectWith.length - 1; i >= 0; i--){
5182  cur = $(connectWith[i]);
5183  for (j = cur.length - 1; j >= 0; j--){
5184  inst = $.data(cur[j], this.widgetFullName);
5185  if(inst && inst !== this && !inst.options.disabled) {
5186  queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
5187  this.containers.push(inst);
5188  }
5189  }
5190  }
5191  }
5192 
5193  for (i = queries.length - 1; i >= 0; i--) {
5194  targetData = queries[i][1];
5195  _queries = queries[i][0];
5196 
5197  for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
5198  item = $(_queries[j]);
5199 
5200  item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
5201 
5202  items.push({
5203  item: item,
5204  instance: targetData,
5205  width: 0, height: 0,
5206  left: 0, top: 0
5207  });
5208  }
5209  }
5210 
5211  },
5212 
5213  refreshPositions: function(fast) {
5214 
5215  //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
5216  if(this.offsetParent && this.helper) {
5217  this.offset.parent = this._getParentOffset();
5218  }
5219 
5220  var i, item, t, p;
5221 
5222  for (i = this.items.length - 1; i >= 0; i--){
5223  item = this.items[i];
5224 
5225  //We ignore calculating positions of all connected containers when we're not over them
5226  if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
5227  continue;
5228  }
5229 
5230  t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
5231 
5232  if (!fast) {
5233  item.width = t.outerWidth();
5234  item.height = t.outerHeight();
5235  }
5236 
5237  p = t.offset();
5238  item.left = p.left;
5239  item.top = p.top;
5240  }
5241 
5242  if(this.options.custom && this.options.custom.refreshContainers) {
5243  this.options.custom.refreshContainers.call(this);
5244  } else {
5245  for (i = this.containers.length - 1; i >= 0; i--){
5246  p = this.containers[i].element.offset();
5247  this.containers[i].containerCache.left = p.left;
5248  this.containers[i].containerCache.top = p.top;
5249  this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
5250  this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
5251  }
5252  }
5253 
5254  return this;
5255  },
5256 
5257  _createPlaceholder: function(that) {
5258  that = that || this;
5259  var className,
5260  o = that.options;
5261 
5262  if(!o.placeholder || o.placeholder.constructor === String) {
5263  className = o.placeholder;
5264  o.placeholder = {
5265  element: function() {
5266 
5267  var nodeName = that.currentItem[0].nodeName.toLowerCase(),
5268  element = $( "<" + nodeName + ">", that.document[0] )
5269  .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
5270  .removeClass("ui-sortable-helper");
5271 
5272  if ( nodeName === "tr" ) {
5273  that.currentItem.children().each(function() {
5274  $( "<td>&#160;</td>", that.document[0] )
5275  .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
5276  .appendTo( element );
5277  });
5278  } else if ( nodeName === "img" ) {
5279  element.attr( "src", that.currentItem.attr( "src" ) );
5280  }
5281 
5282  if ( !className ) {
5283  element.css( "visibility", "hidden" );
5284  }
5285 
5286  return element;
5287  },
5288  update: function(container, p) {
5289 
5290  // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
5291  // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
5292  if(className && !o.forcePlaceholderSize) {
5293  return;
5294  }
5295 
5296  //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
5297  if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
5298  if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
5299  }
5300  };
5301  }
5302 
5303  //Create the placeholder
5304  that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
5305 
5306  //Append it after the actual current item
5307  that.currentItem.after(that.placeholder);
5308 
5309  //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
5310  o.placeholder.update(that, that.placeholder);
5311 
5312  },
5313 
5314  _contactContainers: function(event) {
5315  var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
5316  innermostContainer = null,
5317  innermostIndex = null;
5318 
5319  // get innermost container that intersects with item
5320  for (i = this.containers.length - 1; i >= 0; i--) {
5321 
5322  // never consider a container that's located within the item itself
5323  if($.contains(this.currentItem[0], this.containers[i].element[0])) {
5324  continue;
5325  }
5326 
5327  if(this._intersectsWith(this.containers[i].containerCache)) {
5328 
5329  // if we've already found a container and it's more "inner" than this, then continue
5330  if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
5331  continue;
5332  }
5333 
5334  innermostContainer = this.containers[i];
5335  innermostIndex = i;
5336 
5337  } else {
5338  // container doesn't intersect. trigger "out" event if necessary
5339  if(this.containers[i].containerCache.over) {
5340  this.containers[i]._trigger("out", event, this._uiHash(this));
5341  this.containers[i].containerCache.over = 0;
5342  }
5343  }
5344 
5345  }
5346 
5347  // if no intersecting containers found, return
5348  if(!innermostContainer) {
5349  return;
5350  }
5351 
5352  // move the item into the container if it's not there already
5353  if(this.containers.length === 1) {
5354  if (!this.containers[innermostIndex].containerCache.over) {
5355  this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
5356  this.containers[innermostIndex].containerCache.over = 1;
5357  }
5358  } else {
5359 
5360  //When entering a new container, we will find the item with the least distance and append our item near it
5361  dist = 10000;
5362  itemWithLeastDistance = null;
5363  floating = innermostContainer.floating || this._isFloating(this.currentItem);
5364  posProperty = floating ? "left" : "top";
5365  sizeProperty = floating ? "width" : "height";
5366  axis = floating ? "clientX" : "clientY";
5367 
5368  for (j = this.items.length - 1; j >= 0; j--) {
5369  if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
5370  continue;
5371  }
5372  if(this.items[j].item[0] === this.currentItem[0]) {
5373  continue;
5374  }
5375 
5376  cur = this.items[j].item.offset()[posProperty];
5377  nearBottom = false;
5378  if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
5379  nearBottom = true;
5380  }
5381 
5382  if ( Math.abs( event[ axis ] - cur ) < dist ) {
5383  dist = Math.abs( event[ axis ] - cur );
5384  itemWithLeastDistance = this.items[ j ];
5385  this.direction = nearBottom ? "up": "down";
5386  }
5387  }
5388 
5389  //Check if dropOnEmpty is enabled
5390  if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
5391  return;
5392  }
5393 
5394  if(this.currentContainer === this.containers[innermostIndex]) {
5395  if ( !this.currentContainer.containerCache.over ) {
5396  this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
5397  this.currentContainer.containerCache.over = 1;
5398  }
5399  return;
5400  }
5401 
5402  itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
5403  this._trigger("change", event, this._uiHash());
5404  this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
5405  this.currentContainer = this.containers[innermostIndex];
5406 
5407  //Update the placeholder
5408  this.options.placeholder.update(this.currentContainer, this.placeholder);
5409 
5410  this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
5411  this.containers[innermostIndex].containerCache.over = 1;
5412  }
5413 
5414 
5415  },
5416 
5417  _createHelper: function(event) {
5418 
5419  var o = this.options,
5420  helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
5421 
5422  //Add the helper to the DOM if that didn't happen already
5423  if(!helper.parents("body").length) {
5424  $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
5425  }
5426 
5427  if(helper[0] === this.currentItem[0]) {
5428  this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
5429  }
5430 
5431  if(!helper[0].style.width || o.forceHelperSize) {
5432  helper.width(this.currentItem.width());
5433  }
5434  if(!helper[0].style.height || o.forceHelperSize) {
5435  helper.height(this.currentItem.height());
5436  }
5437 
5438  return helper;
5439 
5440  },
5441 
5442  _adjustOffsetFromHelper: function(obj) {
5443  if (typeof obj === "string") {
5444  obj = obj.split(" ");
5445  }
5446  if ($.isArray(obj)) {
5447  obj = {left: +obj[0], top: +obj[1] || 0};
5448  }
5449  if ("left" in obj) {
5450  this.offset.click.left = obj.left + this.margins.left;
5451  }
5452  if ("right" in obj) {
5453  this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
5454  }
5455  if ("top" in obj) {
5456  this.offset.click.top = obj.top + this.margins.top;
5457  }
5458  if ("bottom" in obj) {
5459  this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
5460  }
5461  },
5462 
5463  _getParentOffset: function() {
5464 
5465 
5466  //Get the offsetParent and cache its position
5467  this.offsetParent = this.helper.offsetParent();
5468  var po = this.offsetParent.offset();
5469 
5470  // This is a special case where we need to modify a offset calculated on start, since the following happened:
5471  // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
5472  // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
5473  // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
5474  if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
5475  po.left += this.scrollParent.scrollLeft();
5476  po.top += this.scrollParent.scrollTop();
5477  }
5478 
5479  // This needs to be actually done for all browsers, since pageX/pageY includes this information
5480  // with an ugly IE fix
5481  if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
5482  po = { top: 0, left: 0 };
5483  }
5484 
5485  return {
5486  top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
5487  left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
5488  };
5489 
5490  },
5491 
5492  _getRelativeOffset: function() {
5493 
5494  if(this.cssPosition === "relative") {
5495  var p = this.currentItem.position();
5496  return {
5497  top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
5498  left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
5499  };
5500  } else {
5501  return { top: 0, left: 0 };
5502  }
5503 
5504  },
5505 
5506  _cacheMargins: function() {
5507  this.margins = {
5508  left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
5509  top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
5510  };
5511  },
5512 
5513  _cacheHelperProportions: function() {
5514  this.helperProportions = {
5515  width: this.helper.outerWidth(),
5516  height: this.helper.outerHeight()
5517  };
5518  },
5519 
5520  _setContainment: function() {
5521 
5522  var ce, co, over,
5523  o = this.options;
5524  if(o.containment === "parent") {
5525  o.containment = this.helper[0].parentNode;
5526  }
5527  if(o.containment === "document" || o.containment === "window") {
5528  this.containment = [
5529  0 - this.offset.relative.left - this.offset.parent.left,
5530  0 - this.offset.relative.top - this.offset.parent.top,
5531  $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
5532  ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
5533  ];
5534  }
5535 
5536  if(!(/^(document|window|parent)$/).test(o.containment)) {
5537  ce = $(o.containment)[0];
5538  co = $(o.containment).offset();
5539  over = ($(ce).css("overflow") !== "hidden");
5540 
5541  this.containment = [
5542  co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
5543  co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
5544  co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
5545  co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
5546  ];
5547  }
5548 
5549  },
5550 
5551  _convertPositionTo: function(d, pos) {
5552 
5553  if(!pos) {
5554  pos = this.position;
5555  }
5556  var mod = d === "absolute" ? 1 : -1,
5557  scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
5558  scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
5559 
5560  return {
5561  top: (
5562  pos.top + // The absolute mouse position
5563  this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
5564  this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border)
5565  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
5566  ),
5567  left: (
5568  pos.left + // The absolute mouse position
5569  this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
5570  this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border)
5571  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
5572  )
5573  };
5574 
5575  },
5576 
5577  _generatePosition: function(event) {
5578 
5579  var top, left,
5580  o = this.options,
5581  pageX = event.pageX,
5582  pageY = event.pageY,
5583  scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
5584 
5585  // This is another very weird special case that only happens for relative elements:
5586  // 1. If the css position is relative
5587  // 2. and the scroll parent is the document or similar to the offset parent
5588  // we have to refresh the relative offset during the scroll so there are no jumps
5589  if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
5590  this.offset.relative = this._getRelativeOffset();
5591  }
5592 
5593  /*
5594  * - Position constraining -
5595  * Constrain the position to a mix of grid, containment.
5596  */
5597 
5598  if(this.originalPosition) { //If we are not dragging yet, we won't check for options
5599 
5600  if(this.containment) {
5601  if(event.pageX - this.offset.click.left < this.containment[0]) {
5602  pageX = this.containment[0] + this.offset.click.left;
5603  }
5604  if(event.pageY - this.offset.click.top < this.containment[1]) {
5605  pageY = this.containment[1] + this.offset.click.top;
5606  }
5607  if(event.pageX - this.offset.click.left > this.containment[2]) {
5608  pageX = this.containment[2] + this.offset.click.left;
5609  }
5610  if(event.pageY - this.offset.click.top > this.containment[3]) {
5611  pageY = this.containment[3] + this.offset.click.top;
5612  }
5613  }
5614 
5615  if(o.grid) {
5616  top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
5617  pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
5618 
5619  left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
5620  pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
5621  }
5622 
5623  }
5624 
5625  return {
5626  top: (
5627  pageY - // The absolute mouse position
5628  this.offset.click.top - // Click offset (relative to the element)
5629  this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
5630  this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
5631  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
5632  ),
5633  left: (
5634  pageX - // The absolute mouse position
5635  this.offset.click.left - // Click offset (relative to the element)
5636  this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
5637  this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
5638  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
5639  )
5640  };
5641 
5642  },
5643 
5644  _rearrange: function(event, i, a, hardRefresh) {
5645 
5646  a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling));
5647 
5648  //Various things done here to improve the performance:
5649  // 1. we create a setTimeout, that calls refreshPositions
5650  // 2. on the instance, we have a counter variable, that get's higher after every append
5651  // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
5652  // 4. this lets only the last addition to the timeout stack through
5653  this.counter = this.counter ? ++this.counter : 1;
5654  var counter = this.counter;
5655 
5656  this._delay(function() {
5657  if(counter === this.counter) {
5658  this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
5659  }
5660  });
5661 
5662  },
5663 
5664  _clear: function(event, noPropagation) {
5665 
5666  this.reverting = false;
5667  // We delay all events that have to be triggered to after the point where the placeholder has been removed and
5668  // everything else normalized again
5669  var i,
5670  delayedTriggers = [];
5671 
5672  // We first have to update the dom position of the actual currentItem
5673  // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
5674  if(!this._noFinalSort && this.currentItem.parent().length) {
5675  this.placeholder.before(this.currentItem);
5676  }
5677  this._noFinalSort = null;
5678 
5679  if(this.helper[0] === this.currentItem[0]) {
5680  for(i in this._storedCSS) {
5681  if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
5682  this._storedCSS[i] = "";
5683  }
5684  }
5685  this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
5686  } else {
5687  this.currentItem.show();
5688  }
5689 
5690  if(this.fromOutside && !noPropagation) {
5691  delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
5692  }
5693  if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
5694  delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
5695  }
5696 
5697  // Check if the items Container has Changed and trigger appropriate
5698  // events.
5699  if (this !== this.currentContainer) {
5700  if(!noPropagation) {
5701  delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
5702  delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
5703  delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
5704  }
5705  }
5706 
5707 
5708  //Post events to containers
5709  function delayEvent( type, instance, container ) {
5710  return function( event ) {
5711  container._trigger( type, event, instance._uiHash( instance ) );
5712  };
5713  }
5714  for (i = this.containers.length - 1; i >= 0; i--){
5715  if (!noPropagation) {
5716  delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
5717  }
5718  if(this.containers[i].containerCache.over) {
5719  delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
5720  this.containers[i].containerCache.over = 0;
5721  }
5722  }
5723 
5724  //Do what was originally in plugins
5725  if ( this.storedCursor ) {
5726  this.document.find( "body" ).css( "cursor", this.storedCursor );
5727  this.storedStylesheet.remove();
5728  }
5729  if(this._storedOpacity) {
5730  this.helper.css("opacity", this._storedOpacity);
5731  }
5732  if(this._storedZIndex) {
5733  this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
5734  }
5735 
5736  this.dragging = false;
5737 
5738  if(!noPropagation) {
5739  this._trigger("beforeStop", event, this._uiHash());
5740  }
5741 
5742  //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
5743  this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
5744 
5745  if ( !this.cancelHelperRemoval ) {
5746  if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
5747  this.helper.remove();
5748  }
5749  this.helper = null;
5750  }
5751 
5752  if(!noPropagation) {
5753  for (i=0; i < delayedTriggers.length; i++) {
5754  delayedTriggers[i].call(this, event);
5755  } //Trigger all delayed events
5756  this._trigger("stop", event, this._uiHash());
5757  }
5758 
5759  this.fromOutside = false;
5760  return !this.cancelHelperRemoval;
5761 
5762  },
5763 
5764  _trigger: function() {
5765  if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
5766  this.cancel();
5767  }
5768  },
5769 
5770  _uiHash: function(_inst) {
5771  var inst = _inst || this;
5772  return {
5773  helper: inst.helper,
5774  placeholder: inst.placeholder || $([]),
5775  position: inst.position,
5776  originalPosition: inst.originalPosition,
5777  offset: inst.positionAbs,
5778  item: inst.currentItem,
5779  sender: _inst ? _inst.element : null
5780  };
5781  }
5782 
5783 });
5784 
5785 
5786 /*!
5787  * jQuery UI Accordion 1.11.2
5788  * http://jqueryui.com
5789  *
5790  * Copyright 2014 jQuery Foundation and other contributors
5791  * Released under the MIT license.
5792  * http://jquery.org/license
5793  *
5794  * http://api.jqueryui.com/accordion/
5795  */
5796 
5797 
5798 var accordion = $.widget( "ui.accordion", {
5799  version: "1.11.2",
5800  options: {
5801  active: 0,
5802  animate: {},
5803  collapsible: false,
5804  event: "click",
5805  header: "> li > :first-child,> :not(li):even",
5806  heightStyle: "auto",
5807  icons: {
5808  activeHeader: "ui-icon-triangle-1-s",
5809  header: "ui-icon-triangle-1-e"
5810  },
5811 
5812  // callbacks
5813  activate: null,
5814  beforeActivate: null
5815  },
5816 
5817  hideProps: {
5818  borderTopWidth: "hide",
5819  borderBottomWidth: "hide",
5820  paddingTop: "hide",
5821  paddingBottom: "hide",
5822  height: "hide"
5823  },
5824 
5825  showProps: {
5826  borderTopWidth: "show",
5827  borderBottomWidth: "show",
5828  paddingTop: "show",
5829  paddingBottom: "show",
5830  height: "show"
5831  },
5832 
5833  _create: function() {
5834  var options = this.options;
5835  this.prevShow = this.prevHide = $();
5836  this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
5837  // ARIA
5838  .attr( "role", "tablist" );
5839 
5840  // don't allow collapsible: false and active: false / null
5841  if ( !options.collapsible && (options.active === false || options.active == null) ) {
5842  options.active = 0;
5843  }
5844 
5845  this._processPanels();
5846  // handle negative values
5847  if ( options.active < 0 ) {
5848  options.active += this.headers.length;
5849  }
5850  this._refresh();
5851  },
5852 
5853  _getCreateEventData: function() {
5854  return {
5855  header: this.active,
5856  panel: !this.active.length ? $() : this.active.next()
5857  };
5858  },
5859 
5860  _createIcons: function() {
5861  var icons = this.options.icons;
5862  if ( icons ) {
5863  $( "<span>" )
5864  .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
5865  .prependTo( this.headers );
5866  this.active.children( ".ui-accordion-header-icon" )
5867  .removeClass( icons.header )
5868  .addClass( icons.activeHeader );
5869  this.headers.addClass( "ui-accordion-icons" );
5870  }
5871  },
5872 
5873  _destroyIcons: function() {
5874  this.headers
5875  .removeClass( "ui-accordion-icons" )
5876  .children( ".ui-accordion-header-icon" )
5877  .remove();
5878  },
5879 
5880  _destroy: function() {
5881  var contents;
5882 
5883  // clean up main element
5884  this.element
5885  .removeClass( "ui-accordion ui-widget ui-helper-reset" )
5886  .removeAttr( "role" );
5887 
5888  // clean up headers
5889  this.headers
5890  .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
5891  "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
5892  .removeAttr( "role" )
5893  .removeAttr( "aria-expanded" )
5894  .removeAttr( "aria-selected" )
5895  .removeAttr( "aria-controls" )
5896  .removeAttr( "tabIndex" )
5897  .removeUniqueId();
5898 
5899  this._destroyIcons();
5900 
5901  // clean up content panels
5902  contents = this.headers.next()
5903  .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
5904  "ui-accordion-content ui-accordion-content-active ui-state-disabled" )
5905  .css( "display", "" )
5906  .removeAttr( "role" )
5907  .removeAttr( "aria-hidden" )
5908  .removeAttr( "aria-labelledby" )
5909  .removeUniqueId();
5910 
5911  if ( this.options.heightStyle !== "content" ) {
5912  contents.css( "height", "" );
5913  }
5914  },
5915 
5916  _setOption: function( key, value ) {
5917  if ( key === "active" ) {
5918  // _activate() will handle invalid values and update this.options
5919  this._activate( value );
5920  return;
5921  }
5922 
5923  if ( key === "event" ) {
5924  if ( this.options.event ) {
5925  this._off( this.headers, this.options.event );
5926  }
5927  this._setupEvents( value );
5928  }
5929 
5930  this._super( key, value );
5931 
5932  // setting collapsible: false while collapsed; open first panel
5933  if ( key === "collapsible" && !value && this.options.active === false ) {
5934  this._activate( 0 );
5935  }
5936 
5937  if ( key === "icons" ) {
5938  this._destroyIcons();
5939  if ( value ) {
5940  this._createIcons();
5941  }
5942  }
5943 
5944  // #5332 - opacity doesn't cascade to positioned elements in IE
5945  // so we need to add the disabled class to the headers and panels
5946  if ( key === "disabled" ) {
5947  this.element
5948  .toggleClass( "ui-state-disabled", !!value )
5949  .attr( "aria-disabled", value );
5950  this.headers.add( this.headers.next() )
5951  .toggleClass( "ui-state-disabled", !!value );
5952  }
5953  },
5954 
5955  _keydown: function( event ) {
5956  if ( event.altKey || event.ctrlKey ) {
5957  return;
5958  }
5959 
5960  var keyCode = $.ui.keyCode,
5961  length = this.headers.length,
5962  currentIndex = this.headers.index( event.target ),
5963  toFocus = false;
5964 
5965  switch ( event.keyCode ) {
5966  case keyCode.RIGHT:
5967  case keyCode.DOWN:
5968  toFocus = this.headers[ ( currentIndex + 1 ) % length ];
5969  break;
5970  case keyCode.LEFT:
5971  case keyCode.UP:
5972  toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
5973  break;
5974  case keyCode.SPACE:
5975  case keyCode.ENTER:
5976  this._eventHandler( event );
5977  break;
5978  case keyCode.HOME:
5979  toFocus = this.headers[ 0 ];
5980  break;
5981  case keyCode.END:
5982  toFocus = this.headers[ length - 1 ];
5983  break;
5984  }
5985 
5986  if ( toFocus ) {
5987  $( event.target ).attr( "tabIndex", -1 );
5988  $( toFocus ).attr( "tabIndex", 0 );
5989  toFocus.focus();
5990  event.preventDefault();
5991  }
5992  },
5993 
5994  _panelKeyDown: function( event ) {
5995  if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
5996  $( event.currentTarget ).prev().focus();
5997  }
5998  },
5999 
6000  refresh: function() {
6001  var options = this.options;
6002  this._processPanels();
6003 
6004  // was collapsed or no panel
6005  if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
6006  options.active = false;
6007  this.active = $();
6008  // active false only when collapsible is true
6009  } else if ( options.active === false ) {
6010  this._activate( 0 );
6011  // was active, but active panel is gone
6012  } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6013  // all remaining panel are disabled
6014  if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
6015  options.active = false;
6016  this.active = $();
6017  // activate previous panel
6018  } else {
6019  this._activate( Math.max( 0, options.active - 1 ) );
6020  }
6021  // was active, active panel still exists
6022  } else {
6023  // make sure active index is correct
6024  options.active = this.headers.index( this.active );
6025  }
6026 
6027  this._destroyIcons();
6028 
6029  this._refresh();
6030  },
6031 
6032  _processPanels: function() {
6033  var prevHeaders = this.headers,
6034  prevPanels = this.panels;
6035 
6036  this.headers = this.element.find( this.options.header )
6037  .addClass( "ui-accordion-header ui-state-default ui-corner-all" );
6038 
6039  this.panels = this.headers.next()
6040  .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
6041  .filter( ":not(.ui-accordion-content-active)" )
6042  .hide();
6043 
6044  // Avoid memory leaks (#10056)
6045  if ( prevPanels ) {
6046  this._off( prevHeaders.not( this.headers ) );
6047  this._off( prevPanels.not( this.panels ) );
6048  }
6049  },
6050 
6051  _refresh: function() {
6052  var maxHeight,
6053  options = this.options,
6054  heightStyle = options.heightStyle,
6055  parent = this.element.parent();
6056 
6057  this.active = this._findActive( options.active )
6058  .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
6059  .removeClass( "ui-corner-all" );
6060  this.active.next()
6061  .addClass( "ui-accordion-content-active" )
6062  .show();
6063 
6064  this.headers
6065  .attr( "role", "tab" )
6066  .each(function() {
6067  var header = $( this ),
6068  headerId = header.uniqueId().attr( "id" ),
6069  panel = header.next(),
6070  panelId = panel.uniqueId().attr( "id" );
6071  header.attr( "aria-controls", panelId );
6072  panel.attr( "aria-labelledby", headerId );
6073  })
6074  .next()
6075  .attr( "role", "tabpanel" );
6076 
6077  this.headers
6078  .not( this.active )
6079  .attr({
6080  "aria-selected": "false",
6081  "aria-expanded": "false",
6082  tabIndex: -1
6083  })
6084  .next()
6085  .attr({
6086  "aria-hidden": "true"
6087  })
6088  .hide();
6089 
6090  // make sure at least one header is in the tab order
6091  if ( !this.active.length ) {
6092  this.headers.eq( 0 ).attr( "tabIndex", 0 );
6093  } else {
6094  this.active.attr({
6095  "aria-selected": "true",
6096  "aria-expanded": "true",
6097  tabIndex: 0
6098  })
6099  .next()
6100  .attr({
6101  "aria-hidden": "false"
6102  });
6103  }
6104 
6105  this._createIcons();
6106 
6107  this._setupEvents( options.event );
6108 
6109  if ( heightStyle === "fill" ) {
6110  maxHeight = parent.height();
6111  this.element.siblings( ":visible" ).each(function() {
6112  var elem = $( this ),
6113  position = elem.css( "position" );
6114 
6115  if ( position === "absolute" || position === "fixed" ) {
6116  return;
6117  }
6118  maxHeight -= elem.outerHeight( true );
6119  });
6120 
6121  this.headers.each(function() {
6122  maxHeight -= $( this ).outerHeight( true );
6123  });
6124 
6125  this.headers.next()
6126  .each(function() {
6127  $( this ).height( Math.max( 0, maxHeight -
6128  $( this ).innerHeight() + $( this ).height() ) );
6129  })
6130  .css( "overflow", "auto" );
6131  } else if ( heightStyle === "auto" ) {
6132  maxHeight = 0;
6133  this.headers.next()
6134  .each(function() {
6135  maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
6136  })
6137  .height( maxHeight );
6138  }
6139  },
6140 
6141  _activate: function( index ) {
6142  var active = this._findActive( index )[ 0 ];
6143 
6144  // trying to activate the already active panel
6145  if ( active === this.active[ 0 ] ) {
6146  return;
6147  }
6148 
6149  // trying to collapse, simulate a click on the currently active header
6150  active = active || this.active[ 0 ];
6151 
6152  this._eventHandler({
6153  target: active,
6154  currentTarget: active,
6155  preventDefault: $.noop
6156  });
6157  },
6158 
6159  _findActive: function( selector ) {
6160  return typeof selector === "number" ? this.headers.eq( selector ) : $();
6161  },
6162 
6163  _setupEvents: function( event ) {
6164  var events = {
6165  keydown: "_keydown"
6166  };
6167  if ( event ) {
6168  $.each( event.split( " " ), function( index, eventName ) {
6169  events[ eventName ] = "_eventHandler";
6170  });
6171  }
6172 
6173  this._off( this.headers.add( this.headers.next() ) );
6174  this._on( this.headers, events );
6175  this._on( this.headers.next(), { keydown: "_panelKeyDown" });
6176  this._hoverable( this.headers );
6177  this._focusable( this.headers );
6178  },
6179 
6180  _eventHandler: function( event ) {
6181  var options = this.options,
6182  active = this.active,
6183  clicked = $( event.currentTarget ),
6184  clickedIsActive = clicked[ 0 ] === active[ 0 ],
6185  collapsing = clickedIsActive && options.collapsible,
6186  toShow = collapsing ? $() : clicked.next(),
6187  toHide = active.next(),
6188  eventData = {
6189  oldHeader: active,
6190  oldPanel: toHide,
6191  newHeader: collapsing ? $() : clicked,
6192  newPanel: toShow
6193  };
6194 
6195  event.preventDefault();
6196 
6197  if (
6198  // click on active header, but not collapsible
6199  ( clickedIsActive && !options.collapsible ) ||
6200  // allow canceling activation
6201  ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
6202  return;
6203  }
6204 
6205  options.active = collapsing ? false : this.headers.index( clicked );
6206 
6207  // when the call to ._toggle() comes after the class changes
6208  // it causes a very odd bug in IE 8 (see #6720)
6209  this.active = clickedIsActive ? $() : clicked;
6210  this._toggle( eventData );
6211 
6212  // switch classes
6213  // corner classes on the previously active header stay after the animation
6214  active.removeClass( "ui-accordion-header-active ui-state-active" );
6215  if ( options.icons ) {
6216  active.children( ".ui-accordion-header-icon" )
6217  .removeClass( options.icons.activeHeader )
6218  .addClass( options.icons.header );
6219  }
6220 
6221  if ( !clickedIsActive ) {
6222  clicked
6223  .removeClass( "ui-corner-all" )
6224  .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
6225  if ( options.icons ) {
6226  clicked.children( ".ui-accordion-header-icon" )
6227  .removeClass( options.icons.header )
6228  .addClass( options.icons.activeHeader );
6229  }
6230 
6231  clicked
6232  .next()
6233  .addClass( "ui-accordion-content-active" );
6234  }
6235  },
6236 
6237  _toggle: function( data ) {
6238  var toShow = data.newPanel,
6239  toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
6240 
6241  // handle activating a panel during the animation for another activation
6242  this.prevShow.add( this.prevHide ).stop( true, true );
6243  this.prevShow = toShow;
6244  this.prevHide = toHide;
6245 
6246  if ( this.options.animate ) {
6247  this._animate( toShow, toHide, data );
6248  } else {
6249  toHide.hide();
6250  toShow.show();
6251  this._toggleComplete( data );
6252  }
6253 
6254  toHide.attr({
6255  "aria-hidden": "true"
6256  });
6257  toHide.prev().attr( "aria-selected", "false" );
6258  // if we're switching panels, remove the old header from the tab order
6259  // if we're opening from collapsed state, remove the previous header from the tab order
6260  // if we're collapsing, then keep the collapsing header in the tab order
6261  if ( toShow.length && toHide.length ) {
6262  toHide.prev().attr({
6263  "tabIndex": -1,
6264  "aria-expanded": "false"
6265  });
6266  } else if ( toShow.length ) {
6267  this.headers.filter(function() {
6268  return $( this ).attr( "tabIndex" ) === 0;
6269  })
6270  .attr( "tabIndex", -1 );
6271  }
6272 
6273  toShow
6274  .attr( "aria-hidden", "false" )
6275  .prev()
6276  .attr({
6277  "aria-selected": "true",
6278  tabIndex: 0,
6279  "aria-expanded": "true"
6280  });
6281  },
6282 
6283  _animate: function( toShow, toHide, data ) {
6284  var total, easing, duration,
6285  that = this,
6286  adjust = 0,
6287  down = toShow.length &&
6288  ( !toHide.length || ( toShow.index() < toHide.index() ) ),
6289  animate = this.options.animate || {},
6290  options = down && animate.down || animate,
6291  complete = function() {
6292  that._toggleComplete( data );
6293  };
6294 
6295  if ( typeof options === "number" ) {
6296  duration = options;
6297  }
6298  if ( typeof options === "string" ) {
6299  easing = options;
6300  }
6301  // fall back from options to animation in case of partial down settings
6302  easing = easing || options.easing || animate.easing;
6303  duration = duration || options.duration || animate.duration;
6304 
6305  if ( !toHide.length ) {
6306  return toShow.animate( this.showProps, duration, easing, complete );
6307  }
6308  if ( !toShow.length ) {
6309  return toHide.animate( this.hideProps, duration, easing, complete );
6310  }
6311 
6312  total = toShow.show().outerHeight();
6313  toHide.animate( this.hideProps, {
6314  duration: duration,
6315  easing: easing,
6316  step: function( now, fx ) {
6317  fx.now = Math.round( now );
6318  }
6319  });
6320  toShow
6321  .hide()
6322  .animate( this.showProps, {
6323  duration: duration,
6324  easing: easing,
6325  complete: complete,
6326  step: function( now, fx ) {
6327  fx.now = Math.round( now );
6328  if ( fx.prop !== "height" ) {
6329  adjust += fx.now;
6330  } else if ( that.options.heightStyle !== "content" ) {
6331  fx.now = Math.round( total - toHide.outerHeight() - adjust );
6332  adjust = 0;
6333  }
6334  }
6335  });
6336  },
6337 
6338  _toggleComplete: function( data ) {
6339  var toHide = data.oldPanel;
6340 
6341  toHide
6342  .removeClass( "ui-accordion-content-active" )
6343  .prev()
6344  .removeClass( "ui-corner-top" )
6345  .addClass( "ui-corner-all" );
6346 
6347  // Work around for rendering bug in IE (#5421)
6348  if ( toHide.length ) {
6349  toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
6350  }
6351  this._trigger( "activate", null, data );
6352  }
6353 });
6354 
6355 
6356 /*!
6357  * jQuery UI Menu 1.11.2
6358  * http://jqueryui.com
6359  *
6360  * Copyright 2014 jQuery Foundation and other contributors
6361  * Released under the MIT license.
6362  * http://jquery.org/license
6363  *
6364  * http://api.jqueryui.com/menu/
6365  */
6366 
6367 
6368 var menu = $.widget( "ui.menu", {
6369  version: "1.11.2",
6370  defaultElement: "<ul>",
6371  delay: 300,
6372  options: {
6373  icons: {
6374  submenu: "ui-icon-carat-1-e"
6375  },
6376  items: "> *",
6377  menus: "ul",
6378  position: {
6379  my: "left-1 top",
6380  at: "right top"
6381  },
6382  role: "menu",
6383 
6384  // callbacks
6385  blur: null,
6386  focus: null,
6387  select: null
6388  },
6389 
6390  _create: function() {
6391  this.activeMenu = this.element;
6392 
6393  // Flag used to prevent firing of the click handler
6394  // as the event bubbles up through nested menus
6395  this.mouseHandled = false;
6396  this.element
6397  .uniqueId()
6398  .addClass( "ui-menu ui-widget ui-widget-content" )
6399  .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
6400  .attr({
6401  role: this.options.role,
6402  tabIndex: 0
6403  });
6404 
6405  if ( this.options.disabled ) {
6406  this.element
6407  .addClass( "ui-state-disabled" )
6408  .attr( "aria-disabled", "true" );
6409  }
6410 
6411  this._on({
6412  // Prevent focus from sticking to links inside menu after clicking
6413  // them (focus should always stay on UL during navigation).
6414  "mousedown .ui-menu-item": function( event ) {
6415  event.preventDefault();
6416  },
6417  "click .ui-menu-item": function( event ) {
6418  var target = $( event.target );
6419  if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
6420  this.select( event );
6421 
6422  // Only set the mouseHandled flag if the event will bubble, see #9469.
6423  if ( !event.isPropagationStopped() ) {
6424  this.mouseHandled = true;
6425  }
6426 
6427  // Open submenu on click
6428  if ( target.has( ".ui-menu" ).length ) {
6429  this.expand( event );
6430  } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
6431 
6432  // Redirect focus to the menu
6433  this.element.trigger( "focus", [ true ] );
6434 
6435  // If the active item is on the top level, let it stay active.
6436  // Otherwise, blur the active item since it is no longer visible.
6437  if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
6438  clearTimeout( this.timer );
6439  }
6440  }
6441  }
6442  },
6443  "mouseenter .ui-menu-item": function( event ) {
6444  // Ignore mouse events while typeahead is active, see #10458.
6445  // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
6446  // is over an item in the menu
6447  if ( this.previousFilter ) {
6448  return;
6449  }
6450  var target = $( event.currentTarget );
6451  // Remove ui-state-active class from siblings of the newly focused menu item
6452  // to avoid a jump caused by adjacent elements both having a class with a border
6453  target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
6454  this.focus( event, target );
6455  },
6456  mouseleave: "collapseAll",
6457  "mouseleave .ui-menu": "collapseAll",
6458  focus: function( event, keepActiveItem ) {
6459  // If there's already an active item, keep it active
6460  // If not, activate the first item
6461  var item = this.active || this.element.find( this.options.items ).eq( 0 );
6462 
6463  if ( !keepActiveItem ) {
6464  this.focus( event, item );
6465  }
6466  },
6467  blur: function( event ) {
6468  this._delay(function() {
6469  if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
6470  this.collapseAll( event );
6471  }
6472  });
6473  },
6474  keydown: "_keydown"
6475  });
6476 
6477  this.refresh();
6478 
6479  // Clicks outside of a menu collapse any open menus
6480  this._on( this.document, {
6481  click: function( event ) {
6482  if ( this._closeOnDocumentClick( event ) ) {
6483  this.collapseAll( event );
6484  }
6485 
6486  // Reset the mouseHandled flag
6487  this.mouseHandled = false;
6488  }
6489  });
6490  },
6491 
6492  _destroy: function() {
6493  // Destroy (sub)menus
6494  this.element
6495  .removeAttr( "aria-activedescendant" )
6496  .find( ".ui-menu" ).addBack()
6497  .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
6498  .removeAttr( "role" )
6499  .removeAttr( "tabIndex" )
6500  .removeAttr( "aria-labelledby" )
6501  .removeAttr( "aria-expanded" )
6502  .removeAttr( "aria-hidden" )
6503  .removeAttr( "aria-disabled" )
6504  .removeUniqueId()
6505  .show();
6506 
6507  // Destroy menu items
6508  this.element.find( ".ui-menu-item" )
6509  .removeClass( "ui-menu-item" )
6510  .removeAttr( "role" )
6511  .removeAttr( "aria-disabled" )
6512  .removeUniqueId()
6513  .removeClass( "ui-state-hover" )
6514  .removeAttr( "tabIndex" )
6515  .removeAttr( "role" )
6516  .removeAttr( "aria-haspopup" )
6517  .children().each( function() {
6518  var elem = $( this );
6519  if ( elem.data( "ui-menu-submenu-carat" ) ) {
6520  elem.remove();
6521  }
6522  });
6523 
6524  // Destroy menu dividers
6525  this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
6526  },
6527 
6528  _keydown: function( event ) {
6529  var match, prev, character, skip,
6530  preventDefault = true;
6531 
6532  switch ( event.keyCode ) {
6533  case $.ui.keyCode.PAGE_UP:
6534  this.previousPage( event );
6535  break;
6536  case $.ui.keyCode.PAGE_DOWN:
6537  this.nextPage( event );
6538  break;
6539  case $.ui.keyCode.HOME:
6540  this._move( "first", "first", event );
6541  break;
6542  case $.ui.keyCode.END:
6543  this._move( "last", "last", event );
6544  break;
6545  case $.ui.keyCode.UP:
6546  this.previous( event );
6547  break;
6548  case $.ui.keyCode.DOWN:
6549  this.next( event );
6550  break;
6551  case $.ui.keyCode.LEFT:
6552  this.collapse( event );
6553  break;
6554  case $.ui.keyCode.RIGHT:
6555  if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
6556  this.expand( event );
6557  }
6558  break;
6559  case $.ui.keyCode.ENTER:
6560  case $.ui.keyCode.SPACE:
6561  this._activate( event );
6562  break;
6563  case $.ui.keyCode.ESCAPE:
6564  this.collapse( event );
6565  break;
6566  default:
6567  preventDefault = false;
6568  prev = this.previousFilter || "";
6569  character = String.fromCharCode( event.keyCode );
6570  skip = false;
6571 
6572  clearTimeout( this.filterTimer );
6573 
6574  if ( character === prev ) {
6575  skip = true;
6576  } else {
6577  character = prev + character;
6578  }
6579 
6580  match = this._filterMenuItems( character );
6581  match = skip && match.index( this.active.next() ) !== -1 ?
6582  this.active.nextAll( ".ui-menu-item" ) :
6583  match;
6584 
6585  // If no matches on the current filter, reset to the last character pressed
6586  // to move down the menu to the first item that starts with that character
6587  if ( !match.length ) {
6588  character = String.fromCharCode( event.keyCode );
6589  match = this._filterMenuItems( character );
6590  }
6591 
6592  if ( match.length ) {
6593  this.focus( event, match );
6594  this.previousFilter = character;
6595  this.filterTimer = this._delay(function() {
6596  delete this.previousFilter;
6597  }, 1000 );
6598  } else {
6599  delete this.previousFilter;
6600  }
6601  }
6602 
6603  if ( preventDefault ) {
6604  event.preventDefault();
6605  }
6606  },
6607 
6608  _activate: function( event ) {
6609  if ( !this.active.is( ".ui-state-disabled" ) ) {
6610  if ( this.active.is( "[aria-haspopup='true']" ) ) {
6611  this.expand( event );
6612  } else {
6613  this.select( event );
6614  }
6615  }
6616  },
6617 
6618  refresh: function() {
6619  var menus, items,
6620  that = this,
6621  icon = this.options.icons.submenu,
6622  submenus = this.element.find( this.options.menus );
6623 
6624  this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
6625 
6626  // Initialize nested menus
6627  submenus.filter( ":not(.ui-menu)" )
6628  .addClass( "ui-menu ui-widget ui-widget-content ui-front" )
6629  .hide()
6630  .attr({
6631  role: this.options.role,
6632  "aria-hidden": "true",
6633  "aria-expanded": "false"
6634  })
6635  .each(function() {
6636  var menu = $( this ),
6637  item = menu.parent(),
6638  submenuCarat = $( "<span>" )
6639  .addClass( "ui-menu-icon ui-icon " + icon )
6640  .data( "ui-menu-submenu-carat", true );
6641 
6642  item
6643  .attr( "aria-haspopup", "true" )
6644  .prepend( submenuCarat );
6645  menu.attr( "aria-labelledby", item.attr( "id" ) );
6646  });
6647 
6648  menus = submenus.add( this.element );
6649  items = menus.find( this.options.items );
6650 
6651  // Initialize menu-items containing spaces and/or dashes only as dividers
6652  items.not( ".ui-menu-item" ).each(function() {
6653  var item = $( this );
6654  if ( that._isDivider( item ) ) {
6655  item.addClass( "ui-widget-content ui-menu-divider" );
6656  }
6657  });
6658 
6659  // Don't refresh list items that are already adapted
6660  items.not( ".ui-menu-item, .ui-menu-divider" )
6661  .addClass( "ui-menu-item" )
6662  .uniqueId()
6663  .attr({
6664  tabIndex: -1,
6665  role: this._itemRole()
6666  });
6667 
6668  // Add aria-disabled attribute to any disabled menu item
6669  items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
6670 
6671  // If the active item has been removed, blur the menu
6672  if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6673  this.blur();
6674  }
6675  },
6676 
6677  _itemRole: function() {
6678  return {
6679  menu: "menuitem",
6680  listbox: "option"
6681  }[ this.options.role ];
6682  },
6683 
6684  _setOption: function( key, value ) {
6685  if ( key === "icons" ) {
6686  this.element.find( ".ui-menu-icon" )
6687  .removeClass( this.options.icons.submenu )
6688  .addClass( value.submenu );
6689  }
6690  if ( key === "disabled" ) {
6691  this.element
6692  .toggleClass( "ui-state-disabled", !!value )
6693  .attr( "aria-disabled", value );
6694  }
6695  this._super( key, value );
6696  },
6697 
6698  focus: function( event, item ) {
6699  var nested, focused;
6700  this.blur( event, event && event.type === "focus" );
6701 
6702  this._scrollIntoView( item );
6703 
6704  this.active = item.first();
6705  focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
6706  // Only update aria-activedescendant if there's a role
6707  // otherwise we assume focus is managed elsewhere
6708  if ( this.options.role ) {
6709  this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
6710  }
6711 
6712  // Highlight active parent menu item, if any
6713  this.active
6714  .parent()
6715  .closest( ".ui-menu-item" )
6716  .addClass( "ui-state-active" );
6717 
6718  if ( event && event.type === "keydown" ) {
6719  this._close();
6720  } else {
6721  this.timer = this._delay(function() {
6722  this._close();
6723  }, this.delay );
6724  }
6725 
6726  nested = item.children( ".ui-menu" );
6727  if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
6728  this._startOpening(nested);
6729  }
6730  this.activeMenu = item.parent();
6731 
6732  this._trigger( "focus", event, { item: item } );
6733  },
6734 
6735  _scrollIntoView: function( item ) {
6736  var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
6737  if ( this._hasScroll() ) {
6738  borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
6739  paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
6740  offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
6741  scroll = this.activeMenu.scrollTop();
6742  elementHeight = this.activeMenu.height();
6743  itemHeight = item.outerHeight();
6744 
6745  if ( offset < 0 ) {
6746  this.activeMenu.scrollTop( scroll + offset );
6747  } else if ( offset + itemHeight > elementHeight ) {
6748  this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
6749  }
6750  }
6751  },
6752 
6753  blur: function( event, fromFocus ) {
6754  if ( !fromFocus ) {
6755  clearTimeout( this.timer );
6756  }
6757 
6758  if ( !this.active ) {
6759  return;
6760  }
6761 
6762  this.active.removeClass( "ui-state-focus" );
6763  this.active = null;
6764 
6765  this._trigger( "blur", event, { item: this.active } );
6766  },
6767 
6768  _startOpening: function( submenu ) {
6769  clearTimeout( this.timer );
6770 
6771  // Don't open if already open fixes a Firefox bug that caused a .5 pixel
6772  // shift in the submenu position when mousing over the carat icon
6773  if ( submenu.attr( "aria-hidden" ) !== "true" ) {
6774  return;
6775  }
6776 
6777  this.timer = this._delay(function() {
6778  this._close();
6779  this._open( submenu );
6780  }, this.delay );
6781  },
6782 
6783  _open: function( submenu ) {
6784  var position = $.extend({
6785  of: this.active
6786  }, this.options.position );
6787 
6788  clearTimeout( this.timer );
6789  this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
6790  .hide()
6791  .attr( "aria-hidden", "true" );
6792 
6793  submenu
6794  .show()
6795  .removeAttr( "aria-hidden" )
6796  .attr( "aria-expanded", "true" )
6797  .position( position );
6798  },
6799 
6800  collapseAll: function( event, all ) {
6801  clearTimeout( this.timer );
6802  this.timer = this._delay(function() {
6803  // If we were passed an event, look for the submenu that contains the event
6804  var currentMenu = all ? this.element :
6805  $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
6806 
6807  // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
6808  if ( !currentMenu.length ) {
6809  currentMenu = this.element;
6810  }
6811 
6812  this._close( currentMenu );
6813 
6814  this.blur( event );
6815  this.activeMenu = currentMenu;
6816  }, this.delay );
6817  },
6818 
6819  // With no arguments, closes the currently active menu - if nothing is active
6820  // it closes all menus. If passed an argument, it will search for menus BELOW
6821  _close: function( startMenu ) {
6822  if ( !startMenu ) {
6823  startMenu = this.active ? this.active.parent() : this.element;
6824  }
6825 
6826  startMenu
6827  .find( ".ui-menu" )
6828  .hide()
6829  .attr( "aria-hidden", "true" )
6830  .attr( "aria-expanded", "false" )
6831  .end()
6832  .find( ".ui-state-active" ).not( ".ui-state-focus" )
6833  .removeClass( "ui-state-active" );
6834  },
6835 
6836  _closeOnDocumentClick: function( event ) {
6837  return !$( event.target ).closest( ".ui-menu" ).length;
6838  },
6839 
6840  _isDivider: function( item ) {
6841 
6842  // Match hyphen, em dash, en dash
6843  return !/[^\-\u2014\u2013\s]/.test( item.text() );
6844  },
6845 
6846  collapse: function( event ) {
6847  var newItem = this.active &&
6848  this.active.parent().closest( ".ui-menu-item", this.element );
6849  if ( newItem && newItem.length ) {
6850  this._close();
6851  this.focus( event, newItem );
6852  }
6853  },
6854 
6855  expand: function( event ) {
6856  var newItem = this.active &&
6857  this.active
6858  .children( ".ui-menu " )
6859  .find( this.options.items )
6860  .first();
6861 
6862  if ( newItem && newItem.length ) {
6863  this._open( newItem.parent() );
6864 
6865  // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
6866  this._delay(function() {
6867  this.focus( event, newItem );
6868  });
6869  }
6870  },
6871 
6872  next: function( event ) {
6873  this._move( "next", "first", event );
6874  },
6875 
6876  previous: function( event ) {
6877  this._move( "prev", "last", event );
6878  },
6879 
6880  isFirstItem: function() {
6881  return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
6882  },
6883 
6884  isLastItem: function() {
6885  return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
6886  },
6887 
6888  _move: function( direction, filter, event ) {
6889  var next;
6890  if ( this.active ) {
6891  if ( direction === "first" || direction === "last" ) {
6892  next = this.active
6893  [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
6894  .eq( -1 );
6895  } else {
6896  next = this.active
6897  [ direction + "All" ]( ".ui-menu-item" )
6898  .eq( 0 );
6899  }
6900  }
6901  if ( !next || !next.length || !this.active ) {
6902  next = this.activeMenu.find( this.options.items )[ filter ]();
6903  }
6904 
6905  this.focus( event, next );
6906  },
6907 
6908  nextPage: function( event ) {
6909  var item, base, height;
6910 
6911  if ( !this.active ) {
6912  this.next( event );
6913  return;
6914  }
6915  if ( this.isLastItem() ) {
6916  return;
6917  }
6918  if ( this._hasScroll() ) {
6919  base = this.active.offset().top;
6920  height = this.element.height();
6921  this.active.nextAll( ".ui-menu-item" ).each(function() {
6922  item = $( this );
6923  return item.offset().top - base - height < 0;
6924  });
6925 
6926  this.focus( event, item );
6927  } else {
6928  this.focus( event, this.activeMenu.find( this.options.items )
6929  [ !this.active ? "first" : "last" ]() );
6930  }
6931  },
6932 
6933  previousPage: function( event ) {
6934  var item, base, height;
6935  if ( !this.active ) {
6936  this.next( event );
6937  return;
6938  }
6939  if ( this.isFirstItem() ) {
6940  return;
6941  }
6942  if ( this._hasScroll() ) {
6943  base = this.active.offset().top;
6944  height = this.element.height();
6945  this.active.prevAll( ".ui-menu-item" ).each(function() {
6946  item = $( this );
6947  return item.offset().top - base + height > 0;
6948  });
6949 
6950  this.focus( event, item );
6951  } else {
6952  this.focus( event, this.activeMenu.find( this.options.items ).first() );
6953  }
6954  },
6955 
6956  _hasScroll: function() {
6957  return this.element.outerHeight() < this.element.prop( "scrollHeight" );
6958  },
6959 
6960  select: function( event ) {
6961  // TODO: It should never be possible to not have an active item at this
6962  // point, but the tests don't trigger mouseenter before click.
6963  this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
6964  var ui = { item: this.active };
6965  if ( !this.active.has( ".ui-menu" ).length ) {
6966  this.collapseAll( event, true );
6967  }
6968  this._trigger( "select", event, ui );
6969  },
6970 
6971  _filterMenuItems: function(character) {
6972  var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
6973  regex = new RegExp( "^" + escapedCharacter, "i" );
6974 
6975  return this.activeMenu
6976  .find( this.options.items )
6977 
6978  // Only match on items, not dividers or other content (#10571)
6979  .filter( ".ui-menu-item" )
6980  .filter(function() {
6981  return regex.test( $.trim( $( this ).text() ) );
6982  });
6983  }
6984 });
6985 
6986 
6987 /*!
6988  * jQuery UI Autocomplete 1.11.2
6989  * http://jqueryui.com
6990  *
6991  * Copyright 2014 jQuery Foundation and other contributors
6992  * Released under the MIT license.
6993  * http://jquery.org/license
6994  *
6995  * http://api.jqueryui.com/autocomplete/
6996  */
6997 
6998 
6999 $.widget( "ui.autocomplete", {
7000  version: "1.11.2",
7001  defaultElement: "<input>",
7002  options: {
7003  appendTo: null,
7004  autoFocus: false,
7005  delay: 300,
7006  minLength: 1,
7007  position: {
7008  my: "left top",
7009  at: "left bottom",
7010  collision: "none"
7011  },
7012  source: null,
7013 
7014  // callbacks
7015  change: null,
7016  close: null,
7017  focus: null,
7018  open: null,
7019  response: null,
7020  search: null,
7021  select: null
7022  },
7023 
7024  requestIndex: 0,
7025  pending: 0,
7026 
7027  _create: function() {
7028  // Some browsers only repeat keydown events, not keypress events,
7029  // so we use the suppressKeyPress flag to determine if we've already
7030  // handled the keydown event. #7269
7031  // Unfortunately the code for & in keypress is the same as the up arrow,
7032  // so we use the suppressKeyPressRepeat flag to avoid handling keypress
7033  // events when we know the keydown event was used to modify the
7034  // search term. #7799
7035  var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
7036  nodeName = this.element[ 0 ].nodeName.toLowerCase(),
7037  isTextarea = nodeName === "textarea",
7038  isInput = nodeName === "input";
7039 
7040  this.isMultiLine =
7041  // Textareas are always multi-line
7042  isTextarea ? true :
7043  // Inputs are always single-line, even if inside a contentEditable element
7044  // IE also treats inputs as contentEditable
7045  isInput ? false :
7046  // All other element types are determined by whether or not they're contentEditable
7047  this.element.prop( "isContentEditable" );
7048 
7049  this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
7050  this.isNewMenu = true;
7051 
7052  this.element
7053  .addClass( "ui-autocomplete-input" )
7054  .attr( "autocomplete", "off" );
7055 
7056  this._on( this.element, {
7057  keydown: function( event ) {
7058  if ( this.element.prop( "readOnly" ) ) {
7059  suppressKeyPress = true;
7060  suppressInput = true;
7061  suppressKeyPressRepeat = true;
7062  return;
7063  }
7064 
7065  suppressKeyPress = false;
7066  suppressInput = false;
7067  suppressKeyPressRepeat = false;
7068  var keyCode = $.ui.keyCode;
7069  switch ( event.keyCode ) {
7070  case keyCode.PAGE_UP:
7071  suppressKeyPress = true;
7072  this._move( "previousPage", event );
7073  break;
7074  case keyCode.PAGE_DOWN:
7075  suppressKeyPress = true;
7076  this._move( "nextPage", event );
7077  break;
7078  case keyCode.UP:
7079  suppressKeyPress = true;
7080  this._keyEvent( "previous", event );
7081  break;
7082  case keyCode.DOWN:
7083  suppressKeyPress = true;
7084  this._keyEvent( "next", event );
7085  break;
7086  case keyCode.ENTER:
7087  // when menu is open and has focus
7088  if ( this.menu.active ) {
7089  // #6055 - Opera still allows the keypress to occur
7090  // which causes forms to submit
7091  suppressKeyPress = true;
7092  event.preventDefault();
7093  this.menu.select( event );
7094  }
7095  break;
7096  case keyCode.TAB:
7097  if ( this.menu.active ) {
7098  this.menu.select( event );
7099  }
7100  break;
7101  case keyCode.ESCAPE:
7102  if ( this.menu.element.is( ":visible" ) ) {
7103  if ( !this.isMultiLine ) {
7104  this._value( this.term );
7105  }
7106  this.close( event );
7107  // Different browsers have different default behavior for escape
7108  // Single press can mean undo or clear
7109  // Double press in IE means clear the whole form
7110  event.preventDefault();
7111  }
7112  break;
7113  default:
7114  suppressKeyPressRepeat = true;
7115  // search timeout should be triggered before the input value is changed
7116  this._searchTimeout( event );
7117  break;
7118  }
7119  },
7120  keypress: function( event ) {
7121  if ( suppressKeyPress ) {
7122  suppressKeyPress = false;
7123  if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
7124  event.preventDefault();
7125  }
7126  return;
7127  }
7128  if ( suppressKeyPressRepeat ) {
7129  return;
7130  }
7131 
7132  // replicate some key handlers to allow them to repeat in Firefox and Opera
7133  var keyCode = $.ui.keyCode;
7134  switch ( event.keyCode ) {
7135  case keyCode.PAGE_UP:
7136  this._move( "previousPage", event );
7137  break;
7138  case keyCode.PAGE_DOWN:
7139  this._move( "nextPage", event );
7140  break;
7141  case keyCode.UP:
7142  this._keyEvent( "previous", event );
7143  break;
7144  case keyCode.DOWN:
7145  this._keyEvent( "next", event );
7146  break;
7147  }
7148  },
7149  input: function( event ) {
7150  if ( suppressInput ) {
7151  suppressInput = false;
7152  event.preventDefault();
7153  return;
7154  }
7155  this._searchTimeout( event );
7156  },
7157  focus: function() {
7158  this.selectedItem = null;
7159  this.previous = this._value();
7160  },
7161  blur: function( event ) {
7162  if ( this.cancelBlur ) {
7163  delete this.cancelBlur;
7164  return;
7165  }
7166 
7167  clearTimeout( this.searching );
7168  this.close( event );
7169  this._change( event );
7170  }
7171  });
7172 
7173  this._initSource();
7174  this.menu = $( "<ul>" )
7175  .addClass( "ui-autocomplete ui-front" )
7176  .appendTo( this._appendTo() )
7177  .menu({
7178  // disable ARIA support, the live region takes care of that
7179  role: null
7180  })
7181  .hide()
7182  .menu( "instance" );
7183 
7184  this._on( this.menu.element, {
7185  mousedown: function( event ) {
7186  // prevent moving focus out of the text field
7187  event.preventDefault();
7188 
7189  // IE doesn't prevent moving focus even with event.preventDefault()
7190  // so we set a flag to know when we should ignore the blur event
7191  this.cancelBlur = true;
7192  this._delay(function() {
7193  delete this.cancelBlur;
7194  });
7195 
7196  // clicking on the scrollbar causes focus to shift to the body
7197  // but we can't detect a mouseup or a click immediately afterward
7198  // so we have to track the next mousedown and close the menu if
7199  // the user clicks somewhere outside of the autocomplete
7200  var menuElement = this.menu.element[ 0 ];
7201  if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
7202  this._delay(function() {
7203  var that = this;
7204  this.document.one( "mousedown", function( event ) {
7205  if ( event.target !== that.element[ 0 ] &&
7206  event.target !== menuElement &&
7207  !$.contains( menuElement, event.target ) ) {
7208  that.close();
7209  }
7210  });
7211  });
7212  }
7213  },
7214  menufocus: function( event, ui ) {
7215  var label, item;
7216  // support: Firefox
7217  // Prevent accidental activation of menu items in Firefox (#7024 #9118)
7218  if ( this.isNewMenu ) {
7219  this.isNewMenu = false;
7220  if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
7221  this.menu.blur();
7222 
7223  this.document.one( "mousemove", function() {
7224  $( event.target ).trigger( event.originalEvent );
7225  });
7226 
7227  return;
7228  }
7229  }
7230 
7231  item = ui.item.data( "ui-autocomplete-item" );
7232  if ( false !== this._trigger( "focus", event, { item: item } ) ) {
7233  // use value to match what will end up in the input, if it was a key event
7234  if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
7235  this._value( item.value );
7236  }
7237  }
7238 
7239  // Announce the value in the liveRegion
7240  label = ui.item.attr( "aria-label" ) || item.value;
7241  if ( label && $.trim( label ).length ) {
7242  this.liveRegion.children().hide();
7243  $( "<div>" ).text( label ).appendTo( this.liveRegion );
7244  }
7245  },
7246  menuselect: function( event, ui ) {
7247  var item = ui.item.data( "ui-autocomplete-item" ),
7248  previous = this.previous;
7249 
7250  // only trigger when focus was lost (click on menu)
7251  if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
7252  this.element.focus();
7253  this.previous = previous;
7254  // #6109 - IE triggers two focus events and the second
7255  // is asynchronous, so we need to reset the previous
7256  // term synchronously and asynchronously :-(
7257  this._delay(function() {
7258  this.previous = previous;
7259  this.selectedItem = item;
7260  });
7261  }
7262 
7263  if ( false !== this._trigger( "select", event, { item: item } ) ) {
7264  this._value( item.value );
7265  }
7266  // reset the term after the select event
7267  // this allows custom select handling to work properly
7268  this.term = this._value();
7269 
7270  this.close( event );
7271  this.selectedItem = item;
7272  }
7273  });
7274 
7275  this.liveRegion = $( "<span>", {
7276  role: "status",
7277  "aria-live": "assertive",
7278  "aria-relevant": "additions"
7279  })
7280  .addClass( "ui-helper-hidden-accessible" )
7281  .appendTo( this.document[ 0 ].body );
7282 
7283  // turning off autocomplete prevents the browser from remembering the
7284  // value when navigating through history, so we re-enable autocomplete
7285  // if the page is unloaded before the widget is destroyed. #7790
7286  this._on( this.window, {
7287  beforeunload: function() {
7288  this.element.removeAttr( "autocomplete" );
7289  }
7290  });
7291  },
7292 
7293  _destroy: function() {
7294  clearTimeout( this.searching );
7295  this.element
7296  .removeClass( "ui-autocomplete-input" )
7297  .removeAttr( "autocomplete" );
7298  this.menu.element.remove();
7299  this.liveRegion.remove();
7300  },
7301 
7302  _setOption: function( key, value ) {
7303  this._super( key, value );
7304  if ( key === "source" ) {
7305  this._initSource();
7306  }
7307  if ( key === "appendTo" ) {
7308  this.menu.element.appendTo( this._appendTo() );
7309  }
7310  if ( key === "disabled" && value && this.xhr ) {
7311  this.xhr.abort();
7312  }
7313  },
7314 
7315  _appendTo: function() {
7316  var element = this.options.appendTo;
7317 
7318  if ( element ) {
7319  element = element.jquery || element.nodeType ?
7320  $( element ) :
7321  this.document.find( element ).eq( 0 );
7322  }
7323 
7324  if ( !element || !element[ 0 ] ) {
7325  element = this.element.closest( ".ui-front" );
7326  }
7327 
7328  if ( !element.length ) {
7329  element = this.document[ 0 ].body;
7330  }
7331 
7332  return element;
7333  },
7334 
7335  _initSource: function() {
7336  var array, url,
7337  that = this;
7338  if ( $.isArray( this.options.source ) ) {
7339  array = this.options.source;
7340  this.source = function( request, response ) {
7341  response( $.ui.autocomplete.filter( array, request.term ) );
7342  };
7343  } else if ( typeof this.options.source === "string" ) {
7344  url = this.options.source;
7345  this.source = function( request, response ) {
7346  if ( that.xhr ) {
7347  that.xhr.abort();
7348  }
7349  that.xhr = $.ajax({
7350  url: url,
7351  data: request,
7352  dataType: "json",
7353  success: function( data ) {
7354  response( data );
7355  },
7356  error: function() {
7357  response([]);
7358  }
7359  });
7360  };
7361  } else {
7362  this.source = this.options.source;
7363  }
7364  },
7365 
7366  _searchTimeout: function( event ) {
7367  clearTimeout( this.searching );
7368  this.searching = this._delay(function() {
7369 
7370  // Search if the value has changed, or if the user retypes the same value (see #7434)
7371  var equalValues = this.term === this._value(),
7372  menuVisible = this.menu.element.is( ":visible" ),
7373  modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
7374 
7375  if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
7376  this.selectedItem = null;
7377  this.search( null, event );
7378  }
7379  }, this.options.delay );
7380  },
7381 
7382  search: function( value, event ) {
7383  value = value != null ? value : this._value();
7384 
7385  // always save the actual value, not the one passed as an argument
7386  this.term = this._value();
7387 
7388  if ( value.length < this.options.minLength ) {
7389  return this.close( event );
7390  }
7391 
7392  if ( this._trigger( "search", event ) === false ) {
7393  return;
7394  }
7395 
7396  return this._search( value );
7397  },
7398 
7399  _search: function( value ) {
7400  this.pending++;
7401  this.element.addClass( "ui-autocomplete-loading" );
7402  this.cancelSearch = false;
7403 
7404  this.source( { term: value }, this._response() );
7405  },
7406 
7407  _response: function() {
7408  var index = ++this.requestIndex;
7409 
7410  return $.proxy(function( content ) {
7411  if ( index === this.requestIndex ) {
7412  this.__response( content );
7413  }
7414 
7415  this.pending--;
7416  if ( !this.pending ) {
7417  this.element.removeClass( "ui-autocomplete-loading" );
7418  }
7419  }, this );
7420  },
7421 
7422  __response: function( content ) {
7423  if ( content ) {
7424  content = this._normalize( content );
7425  }
7426  this._trigger( "response", null, { content: content } );
7427  if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
7428  this._suggest( content );
7429  this._trigger( "open" );
7430  } else {
7431  // use ._close() instead of .close() so we don't cancel future searches
7432  this._close();
7433  }
7434  },
7435 
7436  close: function( event ) {
7437  this.cancelSearch = true;
7438  this._close( event );
7439  },
7440 
7441  _close: function( event ) {
7442  if ( this.menu.element.is( ":visible" ) ) {
7443  this.menu.element.hide();
7444  this.menu.blur();
7445  this.isNewMenu = true;
7446  this._trigger( "close", event );
7447  }
7448  },
7449 
7450  _change: function( event ) {
7451  if ( this.previous !== this._value() ) {
7452  this._trigger( "change", event, { item: this.selectedItem } );
7453  }
7454  },
7455 
7456  _normalize: function( items ) {
7457  // assume all items have the right format when the first item is complete
7458  if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
7459  return items;
7460  }
7461  return $.map( items, function( item ) {
7462  if ( typeof item === "string" ) {
7463  return {
7464  label: item,
7465  value: item
7466  };
7467  }
7468  return $.extend( {}, item, {
7469  label: item.label || item.value,
7470  value: item.value || item.label
7471  });
7472  });
7473  },
7474 
7475  _suggest: function( items ) {
7476  var ul = this.menu.element.empty();
7477  this._renderMenu( ul, items );
7478  this.isNewMenu = true;
7479  this.menu.refresh();
7480 
7481  // size and position menu
7482  ul.show();
7483  this._resizeMenu();
7484  ul.position( $.extend({
7485  of: this.element
7486  }, this.options.position ) );
7487 
7488  if ( this.options.autoFocus ) {
7489  this.menu.next();
7490  }
7491  },
7492 
7493  _resizeMenu: function() {
7494  var ul = this.menu.element;
7495  ul.outerWidth( Math.max(
7496  // Firefox wraps long text (possibly a rounding bug)
7497  // so we add 1px to avoid the wrapping (#7513)
7498  ul.width( "" ).outerWidth() + 1,
7499  this.element.outerWidth()
7500  ) );
7501  },
7502 
7503  _renderMenu: function( ul, items ) {
7504  var that = this;
7505  $.each( items, function( index, item ) {
7506  that._renderItemData( ul, item );
7507  });
7508  },
7509 
7510  _renderItemData: function( ul, item ) {
7511  return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
7512  },
7513 
7514  _renderItem: function( ul, item ) {
7515  return $( "<li>" ).text( item.label ).appendTo( ul );
7516  },
7517 
7518  _move: function( direction, event ) {
7519  if ( !this.menu.element.is( ":visible" ) ) {
7520  this.search( null, event );
7521  return;
7522  }
7523  if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
7524  this.menu.isLastItem() && /^next/.test( direction ) ) {
7525 
7526  if ( !this.isMultiLine ) {
7527  this._value( this.term );
7528  }
7529 
7530  this.menu.blur();
7531  return;
7532  }
7533  this.menu[ direction ]( event );
7534  },
7535 
7536  widget: function() {
7537  return this.menu.element;
7538  },
7539 
7540  _value: function() {
7541  return this.valueMethod.apply( this.element, arguments );
7542  },
7543 
7544  _keyEvent: function( keyEvent, event ) {
7545  if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
7546  this._move( keyEvent, event );
7547 
7548  // prevents moving cursor to beginning/end of the text field in some browsers
7549  event.preventDefault();
7550  }
7551  }
7552 });
7553 
7554 $.extend( $.ui.autocomplete, {
7555  escapeRegex: function( value ) {
7556  return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
7557  },
7558  filter: function( array, term ) {
7559  var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
7560  return $.grep( array, function( value ) {
7561  return matcher.test( value.label || value.value || value );
7562  });
7563  }
7564 });
7565 
7566 // live region extension, adding a `messages` option
7567 // NOTE: This is an experimental API. We are still investigating
7568 // a full solution for string manipulation and internationalization.
7569 $.widget( "ui.autocomplete", $.ui.autocomplete, {
7570  options: {
7571  messages: {
7572  noResults: "No search results.",
7573  results: function( amount ) {
7574  return amount + ( amount > 1 ? " results are" : " result is" ) +
7575  " available, use up and down arrow keys to navigate.";
7576  }
7577  }
7578  },
7579 
7580  __response: function( content ) {
7581  var message;
7582  this._superApply( arguments );
7583  if ( this.options.disabled || this.cancelSearch ) {
7584  return;
7585  }
7586  if ( content && content.length ) {
7587  message = this.options.messages.results( content.length );
7588  } else {
7589  message = this.options.messages.noResults;
7590  }
7591  this.liveRegion.children().hide();
7592  $( "<div>" ).text( message ).appendTo( this.liveRegion );
7593  }
7594 });
7595 
7596 var autocomplete = $.ui.autocomplete;
7597 
7598 
7599 /*!
7600  * jQuery UI Button 1.11.2
7601  * http://jqueryui.com
7602  *
7603  * Copyright 2014 jQuery Foundation and other contributors
7604  * Released under the MIT license.
7605  * http://jquery.org/license
7606  *
7607  * http://api.jqueryui.com/button/
7608  */
7609 
7610 
7611 var lastActive,
7612  baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
7613  typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
7614  formResetHandler = function() {
7615  var form = $( this );
7616  setTimeout(function() {
7617  form.find( ":ui-button" ).button( "refresh" );
7618  }, 1 );
7619  },
7620  radioGroup = function( radio ) {
7621  var name = radio.name,
7622  form = radio.form,
7623  radios = $( [] );
7624  if ( name ) {
7625  name = name.replace( /'/g, "\\'" );
7626  if ( form ) {
7627  radios = $( form ).find( "[name='" + name + "'][type=radio]" );
7628  } else {
7629  radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
7630  .filter(function() {
7631  return !this.form;
7632  });
7633  }
7634  }
7635  return radios;
7636  };
7637 
7638 $.widget( "ui.button", {
7639  version: "1.11.2",
7640  defaultElement: "<button>",
7641  options: {
7642  disabled: null,
7643  text: true,
7644  label: null,
7645  icons: {
7646  primary: null,
7647  secondary: null
7648  }
7649  },
7650  _create: function() {
7651  this.element.closest( "form" )
7652  .unbind( "reset" + this.eventNamespace )
7653  .bind( "reset" + this.eventNamespace, formResetHandler );
7654 
7655  if ( typeof this.options.disabled !== "boolean" ) {
7656  this.options.disabled = !!this.element.prop( "disabled" );
7657  } else {
7658  this.element.prop( "disabled", this.options.disabled );
7659  }
7660 
7661  this._determineButtonType();
7662  this.hasTitle = !!this.buttonElement.attr( "title" );
7663 
7664  var that = this,
7665  options = this.options,
7666  toggleButton = this.type === "checkbox" || this.type === "radio",
7667  activeClass = !toggleButton ? "ui-state-active" : "";
7668 
7669  if ( options.label === null ) {
7670  options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
7671  }
7672 
7673  this._hoverable( this.buttonElement );
7674 
7675  this.buttonElement
7676  .addClass( baseClasses )
7677  .attr( "role", "button" )
7678  .bind( "mouseenter" + this.eventNamespace, function() {
7679  if ( options.disabled ) {
7680  return;
7681  }
7682  if ( this === lastActive ) {
7683  $( this ).addClass( "ui-state-active" );
7684  }
7685  })
7686  .bind( "mouseleave" + this.eventNamespace, function() {
7687  if ( options.disabled ) {
7688  return;
7689  }
7690  $( this ).removeClass( activeClass );
7691  })
7692  .bind( "click" + this.eventNamespace, function( event ) {
7693  if ( options.disabled ) {
7694  event.preventDefault();
7695  event.stopImmediatePropagation();
7696  }
7697  });
7698 
7699  // Can't use _focusable() because the element that receives focus
7700  // and the element that gets the ui-state-focus class are different
7701  this._on({
7702  focus: function() {
7703  this.buttonElement.addClass( "ui-state-focus" );
7704  },
7705  blur: function() {
7706  this.buttonElement.removeClass( "ui-state-focus" );
7707  }
7708  });
7709 
7710  if ( toggleButton ) {
7711  this.element.bind( "change" + this.eventNamespace, function() {
7712  that.refresh();
7713  });
7714  }
7715 
7716  if ( this.type === "checkbox" ) {
7717  this.buttonElement.bind( "click" + this.eventNamespace, function() {
7718  if ( options.disabled ) {
7719  return false;
7720  }
7721  });
7722  } else if ( this.type === "radio" ) {
7723  this.buttonElement.bind( "click" + this.eventNamespace, function() {
7724  if ( options.disabled ) {
7725  return false;
7726  }
7727  $( this ).addClass( "ui-state-active" );
7728  that.buttonElement.attr( "aria-pressed", "true" );
7729 
7730  var radio = that.element[ 0 ];
7731  radioGroup( radio )
7732  .not( radio )
7733  .map(function() {
7734  return $( this ).button( "widget" )[ 0 ];
7735  })
7736  .removeClass( "ui-state-active" )
7737  .attr( "aria-pressed", "false" );
7738  });
7739  } else {
7740  this.buttonElement
7741  .bind( "mousedown" + this.eventNamespace, function() {
7742  if ( options.disabled ) {
7743  return false;
7744  }
7745  $( this ).addClass( "ui-state-active" );
7746  lastActive = this;
7747  that.document.one( "mouseup", function() {
7748  lastActive = null;
7749  });
7750  })
7751  .bind( "mouseup" + this.eventNamespace, function() {
7752  if ( options.disabled ) {
7753  return false;
7754  }
7755  $( this ).removeClass( "ui-state-active" );
7756  })
7757  .bind( "keydown" + this.eventNamespace, function(event) {
7758  if ( options.disabled ) {
7759  return false;
7760  }
7761  if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
7762  $( this ).addClass( "ui-state-active" );
7763  }
7764  })
7765  // see #8559, we bind to blur here in case the button element loses
7766  // focus between keydown and keyup, it would be left in an "active" state
7767  .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
7768  $( this ).removeClass( "ui-state-active" );
7769  });
7770 
7771  if ( this.buttonElement.is("a") ) {
7772  this.buttonElement.keyup(function(event) {
7773  if ( event.keyCode === $.ui.keyCode.SPACE ) {
7774  // TODO pass through original event correctly (just as 2nd argument doesn't work)
7775  $( this ).click();
7776  }
7777  });
7778  }
7779  }
7780 
7781  this._setOption( "disabled", options.disabled );
7782  this._resetButton();
7783  },
7784 
7785  _determineButtonType: function() {
7786  var ancestor, labelSelector, checked;
7787 
7788  if ( this.element.is("[type=checkbox]") ) {
7789  this.type = "checkbox";
7790  } else if ( this.element.is("[type=radio]") ) {
7791  this.type = "radio";
7792  } else if ( this.element.is("input") ) {
7793  this.type = "input";
7794  } else {
7795  this.type = "button";
7796  }
7797 
7798  if ( this.type === "checkbox" || this.type === "radio" ) {
7799  // we don't search against the document in case the element
7800  // is disconnected from the DOM
7801  ancestor = this.element.parents().last();
7802  labelSelector = "label[for='" + this.element.attr("id") + "']";
7803  this.buttonElement = ancestor.find( labelSelector );
7804  if ( !this.buttonElement.length ) {
7805  ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
7806  this.buttonElement = ancestor.filter( labelSelector );
7807  if ( !this.buttonElement.length ) {
7808  this.buttonElement = ancestor.find( labelSelector );
7809  }
7810  }
7811  this.element.addClass( "ui-helper-hidden-accessible" );
7812 
7813  checked = this.element.is( ":checked" );
7814  if ( checked ) {
7815  this.buttonElement.addClass( "ui-state-active" );
7816  }
7817  this.buttonElement.prop( "aria-pressed", checked );
7818  } else {
7819  this.buttonElement = this.element;
7820  }
7821  },
7822 
7823  widget: function() {
7824  return this.buttonElement;
7825  },
7826 
7827  _destroy: function() {
7828  this.element
7829  .removeClass( "ui-helper-hidden-accessible" );
7830  this.buttonElement
7831  .removeClass( baseClasses + " ui-state-active " + typeClasses )
7832  .removeAttr( "role" )
7833  .removeAttr( "aria-pressed" )
7834  .html( this.buttonElement.find(".ui-button-text").html() );
7835 
7836  if ( !this.hasTitle ) {
7837  this.buttonElement.removeAttr( "title" );
7838  }
7839  },
7840 
7841  _setOption: function( key, value ) {
7842  this._super( key, value );
7843  if ( key === "disabled" ) {
7844  this.widget().toggleClass( "ui-state-disabled", !!value );
7845  this.element.prop( "disabled", !!value );
7846  if ( value ) {
7847  if ( this.type === "checkbox" || this.type === "radio" ) {
7848  this.buttonElement.removeClass( "ui-state-focus" );
7849  } else {
7850  this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
7851  }
7852  }
7853  return;
7854  }
7855  this._resetButton();
7856  },
7857 
7858  refresh: function() {
7859  //See #8237 & #8828
7860  var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
7861 
7862  if ( isDisabled !== this.options.disabled ) {
7863  this._setOption( "disabled", isDisabled );
7864  }
7865  if ( this.type === "radio" ) {
7866  radioGroup( this.element[0] ).each(function() {
7867  if ( $( this ).is( ":checked" ) ) {
7868  $( this ).button( "widget" )
7869  .addClass( "ui-state-active" )
7870  .attr( "aria-pressed", "true" );
7871  } else {
7872  $( this ).button( "widget" )
7873  .removeClass( "ui-state-active" )
7874  .attr( "aria-pressed", "false" );
7875  }
7876  });
7877  } else if ( this.type === "checkbox" ) {
7878  if ( this.element.is( ":checked" ) ) {
7879  this.buttonElement
7880  .addClass( "ui-state-active" )
7881  .attr( "aria-pressed", "true" );
7882  } else {
7883  this.buttonElement
7884  .removeClass( "ui-state-active" )
7885  .attr( "aria-pressed", "false" );
7886  }
7887  }
7888  },
7889 
7890  _resetButton: function() {
7891  if ( this.type === "input" ) {
7892  if ( this.options.label ) {
7893  this.element.val( this.options.label );
7894  }
7895  return;
7896  }
7897  var buttonElement = this.buttonElement.removeClass( typeClasses ),
7898  buttonText = $( "<span></span>", this.document[0] )
7899  .addClass( "ui-button-text" )
7900  .html( this.options.label )
7901  .appendTo( buttonElement.empty() )
7902  .text(),
7903  icons = this.options.icons,
7904  multipleIcons = icons.primary && icons.secondary,
7905  buttonClasses = [];
7906 
7907  if ( icons.primary || icons.secondary ) {
7908  if ( this.options.text ) {
7909  buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
7910  }
7911 
7912  if ( icons.primary ) {
7913  buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
7914  }
7915 
7916  if ( icons.secondary ) {
7917  buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
7918  }
7919 
7920  if ( !this.options.text ) {
7921  buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
7922 
7923  if ( !this.hasTitle ) {
7924  buttonElement.attr( "title", $.trim( buttonText ) );
7925  }
7926  }
7927  } else {
7928  buttonClasses.push( "ui-button-text-only" );
7929  }
7930  buttonElement.addClass( buttonClasses.join( " " ) );
7931  }
7932 });
7933 
7934 $.widget( "ui.buttonset", {
7935  version: "1.11.2",
7936  options: {
7937  items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
7938  },
7939 
7940  _create: function() {
7941  this.element.addClass( "ui-buttonset" );
7942  },
7943 
7944  _init: function() {
7945  this.refresh();
7946  },
7947 
7948  _setOption: function( key, value ) {
7949  if ( key === "disabled" ) {
7950  this.buttons.button( "option", key, value );
7951  }
7952 
7953  this._super( key, value );
7954  },
7955 
7956  refresh: function() {
7957  var rtl = this.element.css( "direction" ) === "rtl",
7958  allButtons = this.element.find( this.options.items ),
7959  existingButtons = allButtons.filter( ":ui-button" );
7960 
7961  // Initialize new buttons
7962  allButtons.not( ":ui-button" ).button();
7963 
7964  // Refresh existing buttons
7965  existingButtons.button( "refresh" );
7966 
7967  this.buttons = allButtons
7968  .map(function() {
7969  return $( this ).button( "widget" )[ 0 ];
7970  })
7971  .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
7972  .filter( ":first" )
7973  .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
7974  .end()
7975  .filter( ":last" )
7976  .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
7977  .end()
7978  .end();
7979  },
7980 
7981  _destroy: function() {
7982  this.element.removeClass( "ui-buttonset" );
7983  this.buttons
7984  .map(function() {
7985  return $( this ).button( "widget" )[ 0 ];
7986  })
7987  .removeClass( "ui-corner-left ui-corner-right" )
7988  .end()
7989  .button( "destroy" );
7990  }
7991 });
7992 
7993 var button = $.ui.button;
7994 
7995 
7996 /*!
7997  * jQuery UI Datepicker 1.11.2
7998  * http://jqueryui.com
7999  *
8000  * Copyright 2014 jQuery Foundation and other contributors
8001  * Released under the MIT license.
8002  * http://jquery.org/license
8003  *
8004  * http://api.jqueryui.com/datepicker/
8005  */
8006 
8007 
8008 $.extend($.ui, { datepicker: { version: "1.11.2" } });
8009 
8010 var datepicker_instActive;
8011 
8012 function datepicker_getZindex( elem ) {
8013  var position, value;
8014  while ( elem.length && elem[ 0 ] !== document ) {
8015  // Ignore z-index if position is set to a value where z-index is ignored by the browser
8016  // This makes behavior of this function consistent across browsers
8017  // WebKit always returns auto if the element is positioned
8018  position = elem.css( "position" );
8019  if ( position === "absolute" || position === "relative" || position === "fixed" ) {
8020  // IE returns 0 when zIndex is not specified
8021  // other browsers return a string
8022  // we ignore the case of nested elements with an explicit value of 0
8023  // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
8024  value = parseInt( elem.css( "zIndex" ), 10 );
8025  if ( !isNaN( value ) && value !== 0 ) {
8026  return value;
8027  }
8028  }
8029  elem = elem.parent();
8030  }
8031 
8032  return 0;
8033 }
8034 /* Date picker manager.
8035  Use the singleton instance of this class, $.datepicker, to interact with the date picker.
8036  Settings for (groups of) date pickers are maintained in an instance object,
8037  allowing multiple different settings on the same page. */
8038 
8039 function Datepicker() {
8040  this._curInst = null; // The current instance in use
8041  this._keyEvent = false; // If the last event was a key event
8042  this._disabledInputs = []; // List of date picker inputs that have been disabled
8043  this._datepickerShowing = false; // True if the popup picker is showing , false if not
8044  this._inDialog = false; // True if showing within a "dialog", false if not
8045  this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
8046  this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
8047  this._appendClass = "ui-datepicker-append"; // The name of the append marker class
8048  this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
8049  this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
8050  this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
8051  this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
8052  this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
8053  this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
8054  this.regional = []; // Available regional settings, indexed by language code
8055  this.regional[""] = { // Default regional settings
8056  closeText: "Done", // Display text for close link
8057  prevText: "Prev", // Display text for previous month link
8058  nextText: "Next", // Display text for next month link
8059  currentText: "Today", // Display text for current month link
8060  monthNames: ["January","February","March","April","May","June",
8061  "July","August","September","October","November","December"], // Names of months for drop-down and formatting
8062  monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
8063  dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
8064  dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
8065  dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
8066  weekHeader: "Wk", // Column header for week of the year
8067  dateFormat: "mm/dd/yy", // See format options on parseDate
8068  firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
8069  isRTL: false, // True if right-to-left language, false if left-to-right
8070  showMonthAfterYear: false, // True if the year select precedes month, false for month then year
8071  yearSuffix: "" // Additional text to append to the year in the month headers
8072  };
8073  this._defaults = { // Global defaults for all the date picker instances
8074  showOn: "focus", // "focus" for popup on focus,
8075  // "button" for trigger button, or "both" for either
8076  showAnim: "fadeIn", // Name of jQuery animation for popup
8077  showOptions: {}, // Options for enhanced animations
8078  defaultDate: null, // Used when field is blank: actual date,
8079  // +/-number for offset from today, null for today
8080  appendText: "", // Display text following the input box, e.g. showing the format
8081  buttonText: "...", // Text for trigger button
8082  buttonImage: "", // URL for trigger button image
8083  buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
8084  hideIfNoPrevNext: false, // True to hide next/previous month links
8085  // if not applicable, false to just disable them
8086  navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
8087  gotoCurrent: false, // True if today link goes back to current selection instead
8088  changeMonth: false, // True if month can be selected directly, false if only prev/next
8089  changeYear: false, // True if year can be selected directly, false if only prev/next
8090  yearRange: "c-10:c+10", // Range of years to display in drop-down,
8091  // either relative to today's year (-nn:+nn), relative to currently displayed year
8092  // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
8093  showOtherMonths: false, // True to show dates in other months, false to leave blank
8094  selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
8095  showWeek: false, // True to show week of the year, false to not show it
8096  calculateWeek: this.iso8601Week, // How to calculate the week of the year,
8097  // takes a Date and returns the number of the week for it
8098  shortYearCutoff: "+10", // Short year values < this are in the current century,
8099  // > this are in the previous century,
8100  // string value starting with "+" for current year + value
8101  minDate: null, // The earliest selectable date, or null for no limit
8102  maxDate: null, // The latest selectable date, or null for no limit
8103  duration: "fast", // Duration of display/closure
8104  beforeShowDay: null, // Function that takes a date and returns an array with
8105  // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
8106  // [2] = cell title (optional), e.g. $.datepicker.noWeekends
8107  beforeShow: null, // Function that takes an input field and
8108  // returns a set of custom settings for the date picker
8109  onSelect: null, // Define a callback function when a date is selected
8110  onChangeMonthYear: null, // Define a callback function when the month or year is changed
8111  onClose: null, // Define a callback function when the datepicker is closed
8112  numberOfMonths: 1, // Number of months to show at a time
8113  showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
8114  stepMonths: 1, // Number of months to step back/forward
8115  stepBigMonths: 12, // Number of months to step back/forward for the big links
8116  altField: "", // Selector for an alternate field to store selected dates into
8117  altFormat: "", // The date format to use for the alternate field
8118  constrainInput: true, // The input is constrained by the current date format
8119  showButtonPanel: false, // True to show button panel, false to not show it
8120  autoSize: false, // True to size the input for the date format, false to leave as is
8121  disabled: false // The initial disabled state
8122  };
8123  $.extend(this._defaults, this.regional[""]);
8124  this.regional.en = $.extend( true, {}, this.regional[ "" ]);
8125  this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
8126  this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
8127 }
8128 
8129 $.extend(Datepicker.prototype, {
8130  /* Class name added to elements to indicate already configured with a date picker. */
8131  markerClassName: "hasDatepicker",
8132 
8133  //Keep track of the maximum number of rows displayed (see #7043)
8134  maxRows: 4,
8135 
8136  // TODO rename to "widget" when switching to widget factory
8137  _widgetDatepicker: function() {
8138  return this.dpDiv;
8139  },
8140 
8141  /* Override the default settings for all instances of the date picker.
8142  * @param settings object - the new settings to use as defaults (anonymous object)
8143  * @return the manager object
8144  */
8145  setDefaults: function(settings) {
8146  datepicker_extendRemove(this._defaults, settings || {});
8147  return this;
8148  },
8149 
8150  /* Attach the date picker to a jQuery selection.
8151  * @param target element - the target input field or division or span
8152  * @param settings object - the new settings to use for this date picker instance (anonymous)
8153  */
8154  _attachDatepicker: function(target, settings) {
8155  var nodeName, inline, inst;
8156  nodeName = target.nodeName.toLowerCase();
8157  inline = (nodeName === "div" || nodeName === "span");
8158  if (!target.id) {
8159  this.uuid += 1;
8160  target.id = "dp" + this.uuid;
8161  }
8162  inst = this._newInst($(target), inline);
8163  inst.settings = $.extend({}, settings || {});
8164  if (nodeName === "input") {
8165  this._connectDatepicker(target, inst);
8166  } else if (inline) {
8167  this._inlineDatepicker(target, inst);
8168  }
8169  },
8170 
8171  /* Create a new instance object. */
8172  _newInst: function(target, inline) {
8173  var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
8174  return {id: id, input: target, // associated target
8175  selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
8176  drawMonth: 0, drawYear: 0, // month being drawn
8177  inline: inline, // is datepicker inline or not
8178  dpDiv: (!inline ? this.dpDiv : // presentation div
8179  datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
8180  },
8181 
8182  /* Attach the date picker to an input field. */
8183  _connectDatepicker: function(target, inst) {
8184  var input = $(target);
8185  inst.append = $([]);
8186  inst.trigger = $([]);
8187  if (input.hasClass(this.markerClassName)) {
8188  return;
8189  }
8190  this._attachments(input, inst);
8191  input.addClass(this.markerClassName).keydown(this._doKeyDown).
8192  keypress(this._doKeyPress).keyup(this._doKeyUp);
8193  this._autoSize(inst);
8194  $.data(target, "datepicker", inst);
8195  //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
8196  if( inst.settings.disabled ) {
8197  this._disableDatepicker( target );
8198  }
8199  },
8200 
8201  /* Make attachments based on settings. */
8202  _attachments: function(input, inst) {
8203  var showOn, buttonText, buttonImage,
8204  appendText = this._get(inst, "appendText"),
8205  isRTL = this._get(inst, "isRTL");
8206 
8207  if (inst.append) {
8208  inst.append.remove();
8209  }
8210  if (appendText) {
8211  inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
8212  input[isRTL ? "before" : "after"](inst.append);
8213  }
8214 
8215  input.unbind("focus", this._showDatepicker);
8216 
8217  if (inst.trigger) {
8218  inst.trigger.remove();
8219  }
8220 
8221  showOn = this._get(inst, "showOn");
8222  if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
8223  input.focus(this._showDatepicker);
8224  }
8225  if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
8226  buttonText = this._get(inst, "buttonText");
8227  buttonImage = this._get(inst, "buttonImage");
8228  inst.trigger = $(this._get(inst, "buttonImageOnly") ?
8229  $("<img/>").addClass(this._triggerClass).
8230  attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
8231  $("<button type='button'></button>").addClass(this._triggerClass).
8232  html(!buttonImage ? buttonText : $("<img/>").attr(
8233  { src:buttonImage, alt:buttonText, title:buttonText })));
8234  input[isRTL ? "before" : "after"](inst.trigger);
8235  inst.trigger.click(function() {
8236  if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
8237  $.datepicker._hideDatepicker();
8238  } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
8239  $.datepicker._hideDatepicker();
8240  $.datepicker._showDatepicker(input[0]);
8241  } else {
8242  $.datepicker._showDatepicker(input[0]);
8243  }
8244  return false;
8245  });
8246  }
8247  },
8248 
8249  /* Apply the maximum length for the date format. */
8250  _autoSize: function(inst) {
8251  if (this._get(inst, "autoSize") && !inst.inline) {
8252  var findMax, max, maxI, i,
8253  date = new Date(2009, 12 - 1, 20), // Ensure double digits
8254  dateFormat = this._get(inst, "dateFormat");
8255 
8256  if (dateFormat.match(/[DM]/)) {
8257  findMax = function(names) {
8258  max = 0;
8259  maxI = 0;
8260  for (i = 0; i < names.length; i++) {
8261  if (names[i].length > max) {
8262  max = names[i].length;
8263  maxI = i;
8264  }
8265  }
8266  return maxI;
8267  };
8268  date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
8269  "monthNames" : "monthNamesShort"))));
8270  date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
8271  "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
8272  }
8273  inst.input.attr("size", this._formatDate(inst, date).length);
8274  }
8275  },
8276 
8277  /* Attach an inline date picker to a div. */
8278  _inlineDatepicker: function(target, inst) {
8279  var divSpan = $(target);
8280  if (divSpan.hasClass(this.markerClassName)) {
8281  return;
8282  }
8283  divSpan.addClass(this.markerClassName).append(inst.dpDiv);
8284  $.data(target, "datepicker", inst);
8285  this._setDate(inst, this._getDefaultDate(inst), true);
8286  this._updateDatepicker(inst);
8287  this._updateAlternate(inst);
8288  //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
8289  if( inst.settings.disabled ) {
8290  this._disableDatepicker( target );
8291  }
8292  // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
8293  // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
8294  inst.dpDiv.css( "display", "block" );
8295  },
8296 
8297  /* Pop-up the date picker in a "dialog" box.
8298  * @param input element - ignored
8299  * @param date string or Date - the initial date to display
8300  * @param onSelect function - the function to call when a date is selected
8301  * @param settings object - update the dialog date picker instance's settings (anonymous object)
8302  * @param pos int[2] - coordinates for the dialog's position within the screen or
8303  * event - with x/y coordinates or
8304  * leave empty for default (screen centre)
8305  * @return the manager object
8306  */
8307  _dialogDatepicker: function(input, date, onSelect, settings, pos) {
8308  var id, browserWidth, browserHeight, scrollX, scrollY,
8309  inst = this._dialogInst; // internal instance
8310 
8311  if (!inst) {
8312  this.uuid += 1;
8313  id = "dp" + this.uuid;
8314  this._dialogInput = $("<input type='text' id='" + id +
8315  "' style='position: absolute; top: -100px; width: 0px;'/>");
8316  this._dialogInput.keydown(this._doKeyDown);
8317  $("body").append(this._dialogInput);
8318  inst = this._dialogInst = this._newInst(this._dialogInput, false);
8319  inst.settings = {};
8320  $.data(this._dialogInput[0], "datepicker", inst);
8321  }
8322  datepicker_extendRemove(inst.settings, settings || {});
8323  date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
8324  this._dialogInput.val(date);
8325 
8326  this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
8327  if (!this._pos) {
8328  browserWidth = document.documentElement.clientWidth;
8329  browserHeight = document.documentElement.clientHeight;
8330  scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
8331  scrollY = document.documentElement.scrollTop || document.body.scrollTop;
8332  this._pos = // should use actual width/height below
8333  [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
8334  }
8335 
8336  // move input on screen for focus, but hidden behind dialog
8337  this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
8338  inst.settings.onSelect = onSelect;
8339  this._inDialog = true;
8340  this.dpDiv.addClass(this._dialogClass);
8341  this._showDatepicker(this._dialogInput[0]);
8342  if ($.blockUI) {
8343  $.blockUI(this.dpDiv);
8344  }
8345  $.data(this._dialogInput[0], "datepicker", inst);
8346  return this;
8347  },
8348 
8349  /* Detach a datepicker from its control.
8350  * @param target element - the target input field or division or span
8351  */
8352  _destroyDatepicker: function(target) {
8353  var nodeName,
8354  $target = $(target),
8355  inst = $.data(target, "datepicker");
8356 
8357  if (!$target.hasClass(this.markerClassName)) {
8358  return;
8359  }
8360 
8361  nodeName = target.nodeName.toLowerCase();
8362  $.removeData(target, "datepicker");
8363  if (nodeName === "input") {
8364  inst.append.remove();
8365  inst.trigger.remove();
8366  $target.removeClass(this.markerClassName).
8367  unbind("focus", this._showDatepicker).
8368  unbind("keydown", this._doKeyDown).
8369  unbind("keypress", this._doKeyPress).
8370  unbind("keyup", this._doKeyUp);
8371  } else if (nodeName === "div" || nodeName === "span") {
8372  $target.removeClass(this.markerClassName).empty();
8373  }
8374  },
8375 
8376  /* Enable the date picker to a jQuery selection.
8377  * @param target element - the target input field or division or span
8378  */
8379  _enableDatepicker: function(target) {
8380  var nodeName, inline,
8381  $target = $(target),
8382  inst = $.data(target, "datepicker");
8383 
8384  if (!$target.hasClass(this.markerClassName)) {
8385  return;
8386  }
8387 
8388  nodeName = target.nodeName.toLowerCase();
8389  if (nodeName === "input") {
8390  target.disabled = false;
8391  inst.trigger.filter("button").
8392  each(function() { this.disabled = false; }).end().
8393  filter("img").css({opacity: "1.0", cursor: ""});
8394  } else if (nodeName === "div" || nodeName === "span") {
8395  inline = $target.children("." + this._inlineClass);
8396  inline.children().removeClass("ui-state-disabled");
8397  inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8398  prop("disabled", false);
8399  }
8400  this._disabledInputs = $.map(this._disabledInputs,
8401  function(value) { return (value === target ? null : value); }); // delete entry
8402  },
8403 
8404  /* Disable the date picker to a jQuery selection.
8405  * @param target element - the target input field or division or span
8406  */
8407  _disableDatepicker: function(target) {
8408  var nodeName, inline,
8409  $target = $(target),
8410  inst = $.data(target, "datepicker");
8411 
8412  if (!$target.hasClass(this.markerClassName)) {
8413  return;
8414  }
8415 
8416  nodeName = target.nodeName.toLowerCase();
8417  if (nodeName === "input") {
8418  target.disabled = true;
8419  inst.trigger.filter("button").
8420  each(function() { this.disabled = true; }).end().
8421  filter("img").css({opacity: "0.5", cursor: "default"});
8422  } else if (nodeName === "div" || nodeName === "span") {
8423  inline = $target.children("." + this._inlineClass);
8424  inline.children().addClass("ui-state-disabled");
8425  inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8426  prop("disabled", true);
8427  }
8428  this._disabledInputs = $.map(this._disabledInputs,
8429  function(value) { return (value === target ? null : value); }); // delete entry
8430  this._disabledInputs[this._disabledInputs.length] = target;
8431  },
8432 
8433  /* Is the first field in a jQuery collection disabled as a datepicker?
8434  * @param target element - the target input field or division or span
8435  * @return boolean - true if disabled, false if enabled
8436  */
8437  _isDisabledDatepicker: function(target) {
8438  if (!target) {
8439  return false;
8440  }
8441  for (var i = 0; i < this._disabledInputs.length; i++) {
8442  if (this._disabledInputs[i] === target) {
8443  return true;
8444  }
8445  }
8446  return false;
8447  },
8448 
8449  /* Retrieve the instance data for the target control.
8450  * @param target element - the target input field or division or span
8451  * @return object - the associated instance data
8452  * @throws error if a jQuery problem getting data
8453  */
8454  _getInst: function(target) {
8455  try {
8456  return $.data(target, "datepicker");
8457  }
8458  catch (err) {
8459  throw "Missing instance data for this datepicker";
8460  }
8461  },
8462 
8463  /* Update or retrieve the settings for a date picker attached to an input field or division.
8464  * @param target element - the target input field or division or span
8465  * @param name object - the new settings to update or
8466  * string - the name of the setting to change or retrieve,
8467  * when retrieving also "all" for all instance settings or
8468  * "defaults" for all global defaults
8469  * @param value any - the new value for the setting
8470  * (omit if above is an object or to retrieve a value)
8471  */
8472  _optionDatepicker: function(target, name, value) {
8473  var settings, date, minDate, maxDate,
8474  inst = this._getInst(target);
8475 
8476  if (arguments.length === 2 && typeof name === "string") {
8477  return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
8478  (inst ? (name === "all" ? $.extend({}, inst.settings) :
8479  this._get(inst, name)) : null));
8480  }
8481 
8482  settings = name || {};
8483  if (typeof name === "string") {
8484  settings = {};
8485  settings[name] = value;
8486  }
8487 
8488  if (inst) {
8489  if (this._curInst === inst) {
8490  this._hideDatepicker();
8491  }
8492 
8493  date = this._getDateDatepicker(target, true);
8494  minDate = this._getMinMaxDate(inst, "min");
8495  maxDate = this._getMinMaxDate(inst, "max");
8496  datepicker_extendRemove(inst.settings, settings);
8497  // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
8498  if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
8499  inst.settings.minDate = this._formatDate(inst, minDate);
8500  }
8501  if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
8502  inst.settings.maxDate = this._formatDate(inst, maxDate);
8503  }
8504  if ( "disabled" in settings ) {
8505  if ( settings.disabled ) {
8506  this._disableDatepicker(target);
8507  } else {
8508  this._enableDatepicker(target);
8509  }
8510  }
8511  this._attachments($(target), inst);
8512  this._autoSize(inst);
8513  this._setDate(inst, date);
8514  this._updateAlternate(inst);
8515  this._updateDatepicker(inst);
8516  }
8517  },
8518 
8519  // change method deprecated
8520  _changeDatepicker: function(target, name, value) {
8521  this._optionDatepicker(target, name, value);
8522  },
8523 
8524  /* Redraw the date picker attached to an input field or division.
8525  * @param target element - the target input field or division or span
8526  */
8527  _refreshDatepicker: function(target) {
8528  var inst = this._getInst(target);
8529  if (inst) {
8530  this._updateDatepicker(inst);
8531  }
8532  },
8533 
8534  /* Set the dates for a jQuery selection.
8535  * @param target element - the target input field or division or span
8536  * @param date Date - the new date
8537  */
8538  _setDateDatepicker: function(target, date) {
8539  var inst = this._getInst(target);
8540  if (inst) {
8541  this._setDate(inst, date);
8542  this._updateDatepicker(inst);
8543  this._updateAlternate(inst);
8544  }
8545  },
8546 
8547  /* Get the date(s) for the first entry in a jQuery selection.
8548  * @param target element - the target input field or division or span
8549  * @param noDefault boolean - true if no default date is to be used
8550  * @return Date - the current date
8551  */
8552  _getDateDatepicker: function(target, noDefault) {
8553  var inst = this._getInst(target);
8554  if (inst && !inst.inline) {
8555  this._setDateFromField(inst, noDefault);
8556  }
8557  return (inst ? this._getDate(inst) : null);
8558  },
8559 
8560  /* Handle keystrokes. */
8561  _doKeyDown: function(event) {
8562  var onSelect, dateStr, sel,
8563  inst = $.datepicker._getInst(event.target),
8564  handled = true,
8565  isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
8566 
8567  inst._keyEvent = true;
8568  if ($.datepicker._datepickerShowing) {
8569  switch (event.keyCode) {
8570  case 9: $.datepicker._hideDatepicker();
8571  handled = false;
8572  break; // hide on tab out
8573  case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
8574  $.datepicker._currentClass + ")", inst.dpDiv);
8575  if (sel[0]) {
8576  $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
8577  }
8578 
8579  onSelect = $.datepicker._get(inst, "onSelect");
8580  if (onSelect) {
8581  dateStr = $.datepicker._formatDate(inst);
8582 
8583  // trigger custom callback
8584  onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
8585  } else {
8586  $.datepicker._hideDatepicker();
8587  }
8588 
8589  return false; // don't submit the form
8590  case 27: $.datepicker._hideDatepicker();
8591  break; // hide on escape
8592  case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8593  -$.datepicker._get(inst, "stepBigMonths") :
8594  -$.datepicker._get(inst, "stepMonths")), "M");
8595  break; // previous month/year on page up/+ ctrl
8596  case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8597  +$.datepicker._get(inst, "stepBigMonths") :
8598  +$.datepicker._get(inst, "stepMonths")), "M");
8599  break; // next month/year on page down/+ ctrl
8600  case 35: if (event.ctrlKey || event.metaKey) {
8601  $.datepicker._clearDate(event.target);
8602  }
8603  handled = event.ctrlKey || event.metaKey;
8604  break; // clear on ctrl or command +end
8605  case 36: if (event.ctrlKey || event.metaKey) {
8606  $.datepicker._gotoToday(event.target);
8607  }
8608  handled = event.ctrlKey || event.metaKey;
8609  break; // current on ctrl or command +home
8610  case 37: if (event.ctrlKey || event.metaKey) {
8611  $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
8612  }
8613  handled = event.ctrlKey || event.metaKey;
8614  // -1 day on ctrl or command +left
8615  if (event.originalEvent.altKey) {
8616  $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8617  -$.datepicker._get(inst, "stepBigMonths") :
8618  -$.datepicker._get(inst, "stepMonths")), "M");
8619  }
8620  // next month/year on alt +left on Mac
8621  break;
8622  case 38: if (event.ctrlKey || event.metaKey) {
8623  $.datepicker._adjustDate(event.target, -7, "D");
8624  }
8625  handled = event.ctrlKey || event.metaKey;
8626  break; // -1 week on ctrl or command +up
8627  case 39: if (event.ctrlKey || event.metaKey) {
8628  $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
8629  }
8630  handled = event.ctrlKey || event.metaKey;
8631  // +1 day on ctrl or command +right
8632  if (event.originalEvent.altKey) {
8633  $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8634  +$.datepicker._get(inst, "stepBigMonths") :
8635  +$.datepicker._get(inst, "stepMonths")), "M");
8636  }
8637  // next month/year on alt +right
8638  break;
8639  case 40: if (event.ctrlKey || event.metaKey) {
8640  $.datepicker._adjustDate(event.target, +7, "D");
8641  }
8642  handled = event.ctrlKey || event.metaKey;
8643  break; // +1 week on ctrl or command +down
8644  default: handled = false;
8645  }
8646  } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
8647  $.datepicker._showDatepicker(this);
8648  } else {
8649  handled = false;
8650  }
8651 
8652  if (handled) {
8653  event.preventDefault();
8654  event.stopPropagation();
8655  }
8656  },
8657 
8658  /* Filter entered characters - based on date format. */
8659  _doKeyPress: function(event) {
8660  var chars, chr,
8661  inst = $.datepicker._getInst(event.target);
8662 
8663  if ($.datepicker._get(inst, "constrainInput")) {
8664  chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
8665  chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
8666  return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
8667  }
8668  },
8669 
8670  /* Synchronise manual entry and field/alternate field. */
8671  _doKeyUp: function(event) {
8672  var date,
8673  inst = $.datepicker._getInst(event.target);
8674 
8675  if (inst.input.val() !== inst.lastVal) {
8676  try {
8677  date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
8678  (inst.input ? inst.input.val() : null),
8679  $.datepicker._getFormatConfig(inst));
8680 
8681  if (date) { // only if valid
8682  $.datepicker._setDateFromField(inst);
8683  $.datepicker._updateAlternate(inst);
8684  $.datepicker._updateDatepicker(inst);
8685  }
8686  }
8687  catch (err) {
8688  }
8689  }
8690  return true;
8691  },
8692 
8693  /* Pop-up the date picker for a given input field.
8694  * If false returned from beforeShow event handler do not show.
8695  * @param input element - the input field attached to the date picker or
8696  * event - if triggered by focus
8697  */
8698  _showDatepicker: function(input) {
8699  input = input.target || input;
8700  if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
8701  input = $("input", input.parentNode)[0];
8702  }
8703 
8704  if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
8705  return;
8706  }
8707 
8708  var inst, beforeShow, beforeShowSettings, isFixed,
8709  offset, showAnim, duration;
8710 
8711  inst = $.datepicker._getInst(input);
8712  if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
8713  $.datepicker._curInst.dpDiv.stop(true, true);
8714  if ( inst && $.datepicker._datepickerShowing ) {
8715  $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
8716  }
8717  }
8718 
8719  beforeShow = $.datepicker._get(inst, "beforeShow");
8720  beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
8721  if(beforeShowSettings === false){
8722  return;
8723  }
8724  datepicker_extendRemove(inst.settings, beforeShowSettings);
8725 
8726  inst.lastVal = null;
8727  $.datepicker._lastInput = input;
8728  $.datepicker._setDateFromField(inst);
8729 
8730  if ($.datepicker._inDialog) { // hide cursor
8731  input.value = "";
8732  }
8733  if (!$.datepicker._pos) { // position below input
8734  $.datepicker._pos = $.datepicker._findPos(input);
8735  $.datepicker._pos[1] += input.offsetHeight; // add the height
8736  }
8737 
8738  isFixed = false;
8739  $(input).parents().each(function() {
8740  isFixed |= $(this).css("position") === "fixed";
8741  return !isFixed;
8742  });
8743 
8744  offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
8745  $.datepicker._pos = null;
8746  //to avoid flashes on Firefox
8747  inst.dpDiv.empty();
8748  // determine sizing offscreen
8749  inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
8750  $.datepicker._updateDatepicker(inst);
8751  // fix width for dynamic number of date pickers
8752  // and adjust position before showing
8753  offset = $.datepicker._checkOffset(inst, offset, isFixed);
8754  inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
8755  "static" : (isFixed ? "fixed" : "absolute")), display: "none",
8756  left: offset.left + "px", top: offset.top + "px"});
8757 
8758  if (!inst.inline) {
8759  showAnim = $.datepicker._get(inst, "showAnim");
8760  duration = $.datepicker._get(inst, "duration");
8761  inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
8762  $.datepicker._datepickerShowing = true;
8763 
8764  if ( $.effects && $.effects.effect[ showAnim ] ) {
8765  inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
8766  } else {
8767  inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
8768  }
8769 
8770  if ( $.datepicker._shouldFocusInput( inst ) ) {
8771  inst.input.focus();
8772  }
8773 
8774  $.datepicker._curInst = inst;
8775  }
8776  },
8777 
8778  /* Generate the date picker content. */
8779  _updateDatepicker: function(inst) {
8780  this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
8781  datepicker_instActive = inst; // for delegate hover events
8782  inst.dpDiv.empty().append(this._generateHTML(inst));
8783  this._attachHandlers(inst);
8784 
8785  var origyearshtml,
8786  numMonths = this._getNumberOfMonths(inst),
8787  cols = numMonths[1],
8788  width = 17,
8789  activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
8790 
8791  if ( activeCell.length > 0 ) {
8792  datepicker_handleMouseover.apply( activeCell.get( 0 ) );
8793  }
8794 
8795  inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
8796  if (cols > 1) {
8797  inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
8798  }
8799  inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
8800  "Class"]("ui-datepicker-multi");
8801  inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
8802  "Class"]("ui-datepicker-rtl");
8803 
8804  if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
8805  inst.input.focus();
8806  }
8807 
8808  // deffered render of the years select (to avoid flashes on Firefox)
8809  if( inst.yearshtml ){
8810  origyearshtml = inst.yearshtml;
8811  setTimeout(function(){
8812  //assure that inst.yearshtml didn't change.
8813  if( origyearshtml === inst.yearshtml && inst.yearshtml ){
8814  inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
8815  }
8816  origyearshtml = inst.yearshtml = null;
8817  }, 0);
8818  }
8819  },
8820 
8821  // #6694 - don't focus the input if it's already focused
8822  // this breaks the change event in IE
8823  // Support: IE and jQuery <1.9
8824  _shouldFocusInput: function( inst ) {
8825  return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
8826  },
8827 
8828  /* Check positioning to remain on screen. */
8829  _checkOffset: function(inst, offset, isFixed) {
8830  var dpWidth = inst.dpDiv.outerWidth(),
8831  dpHeight = inst.dpDiv.outerHeight(),
8832  inputWidth = inst.input ? inst.input.outerWidth() : 0,
8833  inputHeight = inst.input ? inst.input.outerHeight() : 0,
8834  viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
8835  viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
8836 
8837  offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
8838  offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
8839  offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
8840 
8841  // now check if datepicker is showing outside window viewport - move to a better place if so.
8842  offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
8843  Math.abs(offset.left + dpWidth - viewWidth) : 0);
8844  offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
8845  Math.abs(dpHeight + inputHeight) : 0);
8846 
8847  return offset;
8848  },
8849 
8850  /* Find an object's position on the screen. */
8851  _findPos: function(obj) {
8852  var position,
8853  inst = this._getInst(obj),
8854  isRTL = this._get(inst, "isRTL");
8855 
8856  while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
8857  obj = obj[isRTL ? "previousSibling" : "nextSibling"];
8858  }
8859 
8860  position = $(obj).offset();
8861  return [position.left, position.top];
8862  },
8863 
8864  /* Hide the date picker from view.
8865  * @param input element - the input field attached to the date picker
8866  */
8867  _hideDatepicker: function(input) {
8868  var showAnim, duration, postProcess, onClose,
8869  inst = this._curInst;
8870 
8871  if (!inst || (input && inst !== $.data(input, "datepicker"))) {
8872  return;
8873  }
8874 
8875  if (this._datepickerShowing) {
8876  showAnim = this._get(inst, "showAnim");
8877  duration = this._get(inst, "duration");
8878  postProcess = function() {
8879  $.datepicker._tidyDialog(inst);
8880  };
8881 
8882  // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8883  if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8884  inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
8885  } else {
8886  inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
8887  (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
8888  }
8889 
8890  if (!showAnim) {
8891  postProcess();
8892  }
8893  this._datepickerShowing = false;
8894 
8895  onClose = this._get(inst, "onClose");
8896  if (onClose) {
8897  onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
8898  }
8899 
8900  this._lastInput = null;
8901  if (this._inDialog) {
8902  this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
8903  if ($.blockUI) {
8904  $.unblockUI();
8905  $("body").append(this.dpDiv);
8906  }
8907  }
8908  this._inDialog = false;
8909  }
8910  },
8911 
8912  /* Tidy up after a dialog display. */
8913  _tidyDialog: function(inst) {
8914  inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
8915  },
8916 
8917  /* Close date picker if clicked elsewhere. */
8918  _checkExternalClick: function(event) {
8919  if (!$.datepicker._curInst) {
8920  return;
8921  }
8922 
8923  var $target = $(event.target),
8924  inst = $.datepicker._getInst($target[0]);
8925 
8926  if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
8927  $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
8928  !$target.hasClass($.datepicker.markerClassName) &&
8929  !$target.closest("." + $.datepicker._triggerClass).length &&
8930  $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
8931  ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
8932  $.datepicker._hideDatepicker();
8933  }
8934  },
8935 
8936  /* Adjust one of the date sub-fields. */
8937  _adjustDate: function(id, offset, period) {
8938  var target = $(id),
8939  inst = this._getInst(target[0]);
8940 
8941  if (this._isDisabledDatepicker(target[0])) {
8942  return;
8943  }
8944  this._adjustInstDate(inst, offset +
8945  (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
8946  period);
8947  this._updateDatepicker(inst);
8948  },
8949 
8950  /* Action for current link. */
8951  _gotoToday: function(id) {
8952  var date,
8953  target = $(id),
8954  inst = this._getInst(target[0]);
8955 
8956  if (this._get(inst, "gotoCurrent") && inst.currentDay) {
8957  inst.selectedDay = inst.currentDay;
8958  inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8959  inst.drawYear = inst.selectedYear = inst.currentYear;
8960  } else {
8961  date = new Date();
8962  inst.selectedDay = date.getDate();
8963  inst.drawMonth = inst.selectedMonth = date.getMonth();
8964  inst.drawYear = inst.selectedYear = date.getFullYear();
8965  }
8966  this._notifyChange(inst);
8967  this._adjustDate(target);
8968  },
8969 
8970  /* Action for selecting a new month/year. */
8971  _selectMonthYear: function(id, select, period) {
8972  var target = $(id),
8973  inst = this._getInst(target[0]);
8974 
8975  inst["selected" + (period === "M" ? "Month" : "Year")] =
8976  inst["draw" + (period === "M" ? "Month" : "Year")] =
8977  parseInt(select.options[select.selectedIndex].value,10);
8978 
8979  this._notifyChange(inst);
8980  this._adjustDate(target);
8981  },
8982 
8983  /* Action for selecting a day. */
8984  _selectDay: function(id, month, year, td) {
8985  var inst,
8986  target = $(id);
8987 
8988  if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
8989  return;
8990  }
8991 
8992  inst = this._getInst(target[0]);
8993  inst.selectedDay = inst.currentDay = $("a", td).html();
8994  inst.selectedMonth = inst.currentMonth = month;
8995  inst.selectedYear = inst.currentYear = year;
8996  this._selectDate(id, this._formatDate(inst,
8997  inst.currentDay, inst.currentMonth, inst.currentYear));
8998  },
8999 
9000  /* Erase the input field and hide the date picker. */
9001  _clearDate: function(id) {
9002  var target = $(id);
9003  this._selectDate(target, "");
9004  },
9005 
9006  /* Update the input field with the selected date. */
9007  _selectDate: function(id, dateStr) {
9008  var onSelect,
9009  target = $(id),
9010  inst = this._getInst(target[0]);
9011 
9012  dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
9013  if (inst.input) {
9014  inst.input.val(dateStr);
9015  }
9016  this._updateAlternate(inst);
9017 
9018  onSelect = this._get(inst, "onSelect");
9019  if (onSelect) {
9020  onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
9021  } else if (inst.input) {
9022  inst.input.trigger("change"); // fire the change event
9023  }
9024 
9025  if (inst.inline){
9026  this._updateDatepicker(inst);
9027  } else {
9028  this._hideDatepicker();
9029  this._lastInput = inst.input[0];
9030  if (typeof(inst.input[0]) !== "object") {
9031  inst.input.focus(); // restore focus
9032  }
9033  this._lastInput = null;
9034  }
9035  },
9036 
9037  /* Update any alternate field to synchronise with the main field. */
9038  _updateAlternate: function(inst) {
9039  var altFormat, date, dateStr,
9040  altField = this._get(inst, "altField");
9041 
9042  if (altField) { // update alternate field too
9043  altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
9044  date = this._getDate(inst);
9045  dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
9046  $(altField).each(function() { $(this).val(dateStr); });
9047  }
9048  },
9049 
9050  /* Set as beforeShowDay function to prevent selection of weekends.
9051  * @param date Date - the date to customise
9052  * @return [boolean, string] - is this date selectable?, what is its CSS class?
9053  */
9054  noWeekends: function(date) {
9055  var day = date.getDay();
9056  return [(day > 0 && day < 6), ""];
9057  },
9058 
9059  /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
9060  * @param date Date - the date to get the week for
9061  * @return number - the number of the week within the year that contains this date
9062  */
9063  iso8601Week: function(date) {
9064  var time,
9065  checkDate = new Date(date.getTime());
9066 
9067  // Find Thursday of this week starting on Monday
9068  checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
9069 
9070  time = checkDate.getTime();
9071  checkDate.setMonth(0); // Compare with Jan 1
9072  checkDate.setDate(1);
9073  return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
9074  },
9075 
9076  /* Parse a string value into a date object.
9077  * See formatDate below for the possible formats.
9078  *
9079  * @param format string - the expected format of the date
9080  * @param value string - the date in the above format
9081  * @param settings Object - attributes include:
9082  * shortYearCutoff number - the cutoff year for determining the century (optional)
9083  * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
9084  * dayNames string[7] - names of the days from Sunday (optional)
9085  * monthNamesShort string[12] - abbreviated names of the months (optional)
9086  * monthNames string[12] - names of the months (optional)
9087  * @return Date - the extracted date value or null if value is blank
9088  */
9089  parseDate: function (format, value, settings) {
9090  if (format == null || value == null) {
9091  throw "Invalid arguments";
9092  }
9093 
9094  value = (typeof value === "object" ? value.toString() : value + "");
9095  if (value === "") {
9096  return null;
9097  }
9098 
9099  var iFormat, dim, extra,
9100  iValue = 0,
9101  shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
9102  shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
9103  new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
9104  dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
9105  dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
9106  monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
9107  monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
9108  year = -1,
9109  month = -1,
9110  day = -1,
9111  doy = -1,
9112  literal = false,
9113  date,
9114  // Check whether a format character is doubled
9115  lookAhead = function(match) {
9116  var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
9117  if (matches) {
9118  iFormat++;
9119  }
9120  return matches;
9121  },
9122  // Extract a number from the string value
9123  getNumber = function(match) {
9124  var isDoubled = lookAhead(match),
9125  size = (match === "@" ? 14 : (match === "!" ? 20 :
9126  (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
9127  minSize = (match === "y" ? size : 1),
9128  digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
9129  num = value.substring(iValue).match(digits);
9130  if (!num) {
9131  throw "Missing number at position " + iValue;
9132  }
9133  iValue += num[0].length;
9134  return parseInt(num[0], 10);
9135  },
9136  // Extract a name from the string value and convert to an index
9137  getName = function(match, shortNames, longNames) {
9138  var index = -1,
9139  names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
9140  return [ [k, v] ];
9141  }).sort(function (a, b) {
9142  return -(a[1].length - b[1].length);
9143  });
9144 
9145  $.each(names, function (i, pair) {
9146  var name = pair[1];
9147  if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
9148  index = pair[0];
9149  iValue += name.length;
9150  return false;
9151  }
9152  });
9153  if (index !== -1) {
9154  return index + 1;
9155  } else {
9156  throw "Unknown name at position " + iValue;
9157  }
9158  },
9159  // Confirm that a literal character matches the string value
9160  checkLiteral = function() {
9161  if (value.charAt(iValue) !== format.charAt(iFormat)) {
9162  throw "Unexpected literal at position " + iValue;
9163  }
9164  iValue++;
9165  };
9166 
9167  for (iFormat = 0; iFormat < format.length; iFormat++) {
9168  if (literal) {
9169  if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
9170  literal = false;
9171  } else {
9172  checkLiteral();
9173  }
9174  } else {
9175  switch (format.charAt(iFormat)) {
9176  case "d":
9177  day = getNumber("d");
9178  break;
9179  case "D":
9180  getName("D", dayNamesShort, dayNames);
9181  break;
9182  case "o":
9183  doy = getNumber("o");
9184  break;
9185  case "m":
9186  month = getNumber("m");
9187  break;
9188  case "M":
9189  month = getName("M", monthNamesShort, monthNames);
9190  break;
9191  case "y":
9192  year = getNumber("y");
9193  break;
9194  case "@":
9195  date = new Date(getNumber("@"));
9196  year = date.getFullYear();
9197  month = date.getMonth() + 1;
9198  day = date.getDate();
9199  break;
9200  case "!":
9201  date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
9202  year = date.getFullYear();
9203  month = date.getMonth() + 1;
9204  day = date.getDate();
9205  break;
9206  case "'":
9207  if (lookAhead("'")){
9208  checkLiteral();
9209  } else {
9210  literal = true;
9211  }
9212  break;
9213  default:
9214  checkLiteral();
9215  }
9216  }
9217  }
9218 
9219  if (iValue < value.length){
9220  extra = value.substr(iValue);
9221  if (!/^\s+/.test(extra)) {
9222  throw "Extra/unparsed characters found in date: " + extra;
9223  }
9224  }
9225 
9226  if (year === -1) {
9227  year = new Date().getFullYear();
9228  } else if (year < 100) {
9229  year += new Date().getFullYear() - new Date().getFullYear() % 100 +
9230  (year <= shortYearCutoff ? 0 : -100);
9231  }
9232 
9233  if (doy > -1) {
9234  month = 1;
9235  day = doy;
9236  do {
9237  dim = this._getDaysInMonth(year, month - 1);
9238  if (day <= dim) {
9239  break;
9240  }
9241  month++;
9242  day -= dim;
9243  } while (true);
9244  }
9245 
9246  date = this._daylightSavingAdjust(new Date(year, month - 1, day));
9247  if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
9248  throw "Invalid date"; // E.g. 31/02/00
9249  }
9250  return date;
9251  },
9252 
9253  /* Standard date formats. */
9254  ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
9255  COOKIE: "D, dd M yy",
9256  ISO_8601: "yy-mm-dd",
9257  RFC_822: "D, d M y",
9258  RFC_850: "DD, dd-M-y",
9259  RFC_1036: "D, d M y",
9260  RFC_1123: "D, d M yy",
9261  RFC_2822: "D, d M yy",
9262  RSS: "D, d M y", // RFC 822
9263  TICKS: "!",
9264  TIMESTAMP: "@",
9265  W3C: "yy-mm-dd", // ISO 8601
9266 
9267  _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
9268  Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
9269 
9270  /* Format a date object into a string value.
9271  * The format can be combinations of the following:
9272  * d - day of month (no leading zero)
9273  * dd - day of month (two digit)
9274  * o - day of year (no leading zeros)
9275  * oo - day of year (three digit)
9276  * D - day name short
9277  * DD - day name long
9278  * m - month of year (no leading zero)
9279  * mm - month of year (two digit)
9280  * M - month name short
9281  * MM - month name long
9282  * y - year (two digit)
9283  * yy - year (four digit)
9284  * @ - Unix timestamp (ms since 01/01/1970)
9285  * ! - Windows ticks (100ns since 01/01/0001)
9286  * "..." - literal text
9287  * '' - single quote
9288  *
9289  * @param format string - the desired format of the date
9290  * @param date Date - the date value to format
9291  * @param settings Object - attributes include:
9292  * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
9293  * dayNames string[7] - names of the days from Sunday (optional)
9294  * monthNamesShort string[12] - abbreviated names of the months (optional)
9295  * monthNames string[12] - names of the months (optional)
9296  * @return string - the date in the above format
9297  */
9298  formatDate: function (format, date, settings) {
9299  if (!date) {
9300  return "";
9301  }
9302 
9303  var iFormat,
9304  dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
9305  dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
9306  monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
9307  monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
9308  // Check whether a format character is doubled
9309  lookAhead = function(match) {
9310  var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
9311  if (matches) {
9312  iFormat++;
9313  }
9314  return matches;
9315  },
9316  // Format a number, with leading zero if necessary
9317  formatNumber = function(match, value, len) {
9318  var num = "" + value;
9319  if (lookAhead(match)) {
9320  while (num.length < len) {
9321  num = "0" + num;
9322  }
9323  }
9324  return num;
9325  },
9326  // Format a name, short or long as requested
9327  formatName = function(match, value, shortNames, longNames) {
9328  return (lookAhead(match) ? longNames[value] : shortNames[value]);
9329  },
9330  output = "",
9331  literal = false;
9332 
9333  if (date) {
9334  for (iFormat = 0; iFormat < format.length; iFormat++) {
9335  if (literal) {
9336  if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
9337  literal = false;
9338  } else {
9339  output += format.charAt(iFormat);
9340  }
9341  } else {
9342  switch (format.charAt(iFormat)) {
9343  case "d":
9344  output += formatNumber("d", date.getDate(), 2);
9345  break;
9346  case "D":
9347  output += formatName("D", date.getDay(), dayNamesShort, dayNames);
9348  break;
9349  case "o":
9350  output += formatNumber("o",
9351  Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
9352  break;
9353  case "m":
9354  output += formatNumber("m", date.getMonth() + 1, 2);
9355  break;
9356  case "M":
9357  output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
9358  break;
9359  case "y":
9360  output += (lookAhead("y") ? date.getFullYear() :
9361  (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
9362  break;
9363  case "@":
9364  output += date.getTime();
9365  break;
9366  case "!":
9367  output += date.getTime() * 10000 + this._ticksTo1970;
9368  break;
9369  case "'":
9370  if (lookAhead("'")) {
9371  output += "'";
9372  } else {
9373  literal = true;
9374  }
9375  break;
9376  default:
9377  output += format.charAt(iFormat);
9378  }
9379  }
9380  }
9381  }
9382  return output;
9383  },
9384 
9385  /* Extract all possible characters from the date format. */
9386  _possibleChars: function (format) {
9387  var iFormat,
9388  chars = "",
9389  literal = false,
9390  // Check whether a format character is doubled
9391  lookAhead = function(match) {
9392  var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
9393  if (matches) {
9394  iFormat++;
9395  }
9396  return matches;
9397  };
9398 
9399  for (iFormat = 0; iFormat < format.length; iFormat++) {
9400  if (literal) {
9401  if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
9402  literal = false;
9403  } else {
9404  chars += format.charAt(iFormat);
9405  }
9406  } else {
9407  switch (format.charAt(iFormat)) {
9408  case "d": case "m": case "y": case "@":
9409  chars += "0123456789";
9410  break;
9411  case "D": case "M":
9412  return null; // Accept anything
9413  case "'":
9414  if (lookAhead("'")) {
9415  chars += "'";
9416  } else {
9417  literal = true;
9418  }
9419  break;
9420  default:
9421  chars += format.charAt(iFormat);
9422  }
9423  }
9424  }
9425  return chars;
9426  },
9427 
9428  /* Get a setting value, defaulting if necessary. */
9429  _get: function(inst, name) {
9430  return inst.settings[name] !== undefined ?
9431  inst.settings[name] : this._defaults[name];
9432  },
9433 
9434  /* Parse existing date and initialise date picker. */
9435  _setDateFromField: function(inst, noDefault) {
9436  if (inst.input.val() === inst.lastVal) {
9437  return;
9438  }
9439 
9440  var dateFormat = this._get(inst, "dateFormat"),
9441  dates = inst.lastVal = inst.input ? inst.input.val() : null,
9442  defaultDate = this._getDefaultDate(inst),
9443  date = defaultDate,
9444  settings = this._getFormatConfig(inst);
9445 
9446  try {
9447  date = this.parseDate(dateFormat, dates, settings) || defaultDate;
9448  } catch (event) {
9449  dates = (noDefault ? "" : dates);
9450  }
9451  inst.selectedDay = date.getDate();
9452  inst.drawMonth = inst.selectedMonth = date.getMonth();
9453  inst.drawYear = inst.selectedYear = date.getFullYear();
9454  inst.currentDay = (dates ? date.getDate() : 0);
9455  inst.currentMonth = (dates ? date.getMonth() : 0);
9456  inst.currentYear = (dates ? date.getFullYear() : 0);
9457  this._adjustInstDate(inst);
9458  },
9459 
9460  /* Retrieve the default date shown on opening. */
9461  _getDefaultDate: function(inst) {
9462  return this._restrictMinMax(inst,
9463  this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
9464  },
9465 
9466  /* A date may be specified as an exact value or a relative one. */
9467  _determineDate: function(inst, date, defaultDate) {
9468  var offsetNumeric = function(offset) {
9469  var date = new Date();
9470  date.setDate(date.getDate() + offset);
9471  return date;
9472  },
9473  offsetString = function(offset) {
9474  try {
9475  return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
9476  offset, $.datepicker._getFormatConfig(inst));
9477  }
9478  catch (e) {
9479  // Ignore
9480  }
9481 
9482  var date = (offset.toLowerCase().match(/^c/) ?
9483  $.datepicker._getDate(inst) : null) || new Date(),
9484  year = date.getFullYear(),
9485  month = date.getMonth(),
9486  day = date.getDate(),
9487  pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
9488  matches = pattern.exec(offset);
9489 
9490  while (matches) {
9491  switch (matches[2] || "d") {
9492  case "d" : case "D" :
9493  day += parseInt(matches[1],10); break;
9494  case "w" : case "W" :
9495  day += parseInt(matches[1],10) * 7; break;
9496  case "m" : case "M" :
9497  month += parseInt(matches[1],10);
9498  day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9499  break;
9500  case "y": case "Y" :
9501  year += parseInt(matches[1],10);
9502  day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9503  break;
9504  }
9505  matches = pattern.exec(offset);
9506  }
9507  return new Date(year, month, day);
9508  },
9509  newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
9510  (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
9511 
9512  newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
9513  if (newDate) {
9514  newDate.setHours(0);
9515  newDate.setMinutes(0);
9516  newDate.setSeconds(0);
9517  newDate.setMilliseconds(0);
9518  }
9519  return this._daylightSavingAdjust(newDate);
9520  },
9521 
9522  /* Handle switch to/from daylight saving.
9523  * Hours may be non-zero on daylight saving cut-over:
9524  * > 12 when midnight changeover, but then cannot generate
9525  * midnight datetime, so jump to 1AM, otherwise reset.
9526  * @param date (Date) the date to check
9527  * @return (Date) the corrected date
9528  */
9529  _daylightSavingAdjust: function(date) {
9530  if (!date) {
9531  return null;
9532  }
9533  date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
9534  return date;
9535  },
9536 
9537  /* Set the date(s) directly. */
9538  _setDate: function(inst, date, noChange) {
9539  var clear = !date,
9540  origMonth = inst.selectedMonth,
9541  origYear = inst.selectedYear,
9542  newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
9543 
9544  inst.selectedDay = inst.currentDay = newDate.getDate();
9545  inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
9546  inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
9547  if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
9548  this._notifyChange(inst);
9549  }
9550  this._adjustInstDate(inst);
9551  if (inst.input) {
9552  inst.input.val(clear ? "" : this._formatDate(inst));
9553  }
9554  },
9555 
9556  /* Retrieve the date(s) directly. */
9557  _getDate: function(inst) {
9558  var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
9559  this._daylightSavingAdjust(new Date(
9560  inst.currentYear, inst.currentMonth, inst.currentDay)));
9561  return startDate;
9562  },
9563 
9564  /* Attach the onxxx handlers. These are declared statically so
9565  * they work with static code transformers like Caja.
9566  */
9567  _attachHandlers: function(inst) {
9568  var stepMonths = this._get(inst, "stepMonths"),
9569  id = "#" + inst.id.replace( /\\\\/g, "\\" );
9570  inst.dpDiv.find("[data-handler]").map(function () {
9571  var handler = {
9572  prev: function () {
9573  $.datepicker._adjustDate(id, -stepMonths, "M");
9574  },
9575  next: function () {
9576  $.datepicker._adjustDate(id, +stepMonths, "M");
9577  },
9578  hide: function () {
9579  $.datepicker._hideDatepicker();
9580  },
9581  today: function () {
9582  $.datepicker._gotoToday(id);
9583  },
9584  selectDay: function () {
9585  $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
9586  return false;
9587  },
9588  selectMonth: function () {
9589  $.datepicker._selectMonthYear(id, this, "M");
9590  return false;
9591  },
9592  selectYear: function () {
9593  $.datepicker._selectMonthYear(id, this, "Y");
9594  return false;
9595  }
9596  };
9597  $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
9598  });
9599  },
9600 
9601  /* Generate the HTML for the current state of the date picker. */
9602  _generateHTML: function(inst) {
9603  var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
9604  controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
9605  monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
9606  selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
9607  cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
9608  printDate, dRow, tbody, daySettings, otherMonth, unselectable,
9609  tempDate = new Date(),
9610  today = this._daylightSavingAdjust(
9611  new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
9612  isRTL = this._get(inst, "isRTL"),
9613  showButtonPanel = this._get(inst, "showButtonPanel"),
9614  hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
9615  navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
9616  numMonths = this._getNumberOfMonths(inst),
9617  showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
9618  stepMonths = this._get(inst, "stepMonths"),
9619  isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
9620  currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
9621  new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
9622  minDate = this._getMinMaxDate(inst, "min"),
9623  maxDate = this._getMinMaxDate(inst, "max"),
9624  drawMonth = inst.drawMonth - showCurrentAtPos,
9625  drawYear = inst.drawYear;
9626 
9627  if (drawMonth < 0) {
9628  drawMonth += 12;
9629  drawYear--;
9630  }
9631  if (maxDate) {
9632  maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
9633  maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
9634  maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
9635  while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
9636  drawMonth--;
9637  if (drawMonth < 0) {
9638  drawMonth = 11;
9639  drawYear--;
9640  }
9641  }
9642  }
9643  inst.drawMonth = drawMonth;
9644  inst.drawYear = drawYear;
9645 
9646  prevText = this._get(inst, "prevText");
9647  prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
9648  this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
9649  this._getFormatConfig(inst)));
9650 
9651  prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
9652  "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
9653  " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
9654  (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>"));
9655 
9656  nextText = this._get(inst, "nextText");
9657  nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
9658  this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
9659  this._getFormatConfig(inst)));
9660 
9661  next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
9662  "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
9663  " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
9664  (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>"));
9665 
9666  currentText = this._get(inst, "currentText");
9667  gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
9668  currentText = (!navigationAsDateFormat ? currentText :
9669  this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
9670 
9671  controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
9672  this._get(inst, "closeText") + "</button>" : "");
9673 
9674  buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
9675  (this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
9676  ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
9677 
9678  firstDay = parseInt(this._get(inst, "firstDay"),10);
9679  firstDay = (isNaN(firstDay) ? 0 : firstDay);
9680 
9681  showWeek = this._get(inst, "showWeek");
9682  dayNames = this._get(inst, "dayNames");
9683  dayNamesMin = this._get(inst, "dayNamesMin");
9684  monthNames = this._get(inst, "monthNames");
9685  monthNamesShort = this._get(inst, "monthNamesShort");
9686  beforeShowDay = this._get(inst, "beforeShowDay");
9687  showOtherMonths = this._get(inst, "showOtherMonths");
9688  selectOtherMonths = this._get(inst, "selectOtherMonths");
9689  defaultDate = this._getDefaultDate(inst);
9690  html = "";
9691  dow;
9692  for (row = 0; row < numMonths[0]; row++) {
9693  group = "";
9694  this.maxRows = 4;
9695  for (col = 0; col < numMonths[1]; col++) {
9696  selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
9697  cornerClass = " ui-corner-all";
9698  calender = "";
9699  if (isMultiMonth) {
9700  calender += "<div class='ui-datepicker-group";
9701  if (numMonths[1] > 1) {
9702  switch (col) {
9703  case 0: calender += " ui-datepicker-group-first";
9704  cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
9705  case numMonths[1]-1: calender += " ui-datepicker-group-last";
9706  cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
9707  default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
9708  }
9709  }
9710  calender += "'>";
9711  }
9712  calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
9713  (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
9714  (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
9715  this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
9716  row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
9717  "</div><table class='ui-datepicker-calendar'><thead>" +
9718  "<tr>";
9719  thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
9720  for (dow = 0; dow < 7; dow++) { // days of the week
9721  day = (dow + firstDay) % 7;
9722  thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
9723  "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
9724  }
9725  calender += thead + "</tr></thead><tbody>";
9726  daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
9727  if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
9728  inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
9729  }
9730  leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
9731  curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
9732  numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
9733  this.maxRows = numRows;
9734  printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
9735  for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
9736  calender += "<tr>";
9737  tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
9738  this._get(inst, "calculateWeek")(printDate) + "</td>");
9739  for (dow = 0; dow < 7; dow++) { // create date picker days
9740  daySettings = (beforeShowDay ?
9741  beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
9742  otherMonth = (printDate.getMonth() !== drawMonth);
9743  unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
9744  (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
9745  tbody += "<td class='" +
9746  ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
9747  (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
9748  ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
9749  (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
9750  // or defaultDate is current printedDate and defaultDate is selectedDate
9751  " " + this._dayOverClass : "") + // highlight selected day
9752  (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days
9753  (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
9754  (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
9755  (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
9756  ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
9757  (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
9758  (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
9759  (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
9760  (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
9761  (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
9762  (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
9763  "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
9764  printDate.setDate(printDate.getDate() + 1);
9765  printDate = this._daylightSavingAdjust(printDate);
9766  }
9767  calender += tbody + "</tr>";
9768  }
9769  drawMonth++;
9770  if (drawMonth > 11) {
9771  drawMonth = 0;
9772  drawYear++;
9773  }
9774  calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
9775  ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
9776  group += calender;
9777  }
9778  html += group;
9779  }
9780  html += buttonPanel;
9781  inst._keyEvent = false;
9782  return html;
9783  },
9784 
9785  /* Generate the month and year header. */
9786  _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
9787  secondary, monthNames, monthNamesShort) {
9788 
9789  var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
9790  changeMonth = this._get(inst, "changeMonth"),
9791  changeYear = this._get(inst, "changeYear"),
9792  showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
9793  html = "<div class='ui-datepicker-title'>",
9794  monthHtml = "";
9795 
9796  // month selection
9797  if (secondary || !changeMonth) {
9798  monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
9799  } else {
9800  inMinYear = (minDate && minDate.getFullYear() === drawYear);
9801  inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
9802  monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
9803  for ( month = 0; month < 12; month++) {
9804  if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
9805  monthHtml += "<option value='" + month + "'" +
9806  (month === drawMonth ? " selected='selected'" : "") +
9807  ">" + monthNamesShort[month] + "</option>";
9808  }
9809  }
9810  monthHtml += "</select>";
9811  }
9812 
9813  if (!showMonthAfterYear) {
9814  html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
9815  }
9816 
9817  // year selection
9818  if ( !inst.yearshtml ) {
9819  inst.yearshtml = "";
9820  if (secondary || !changeYear) {
9821  html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9822  } else {
9823  // determine range of years to display
9824  years = this._get(inst, "yearRange").split(":");
9825  thisYear = new Date().getFullYear();
9826  determineYear = function(value) {
9827  var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
9828  (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
9829  parseInt(value, 10)));
9830  return (isNaN(year) ? thisYear : year);
9831  };
9832  year = determineYear(years[0]);
9833  endYear = Math.max(year, determineYear(years[1] || ""));
9834  year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
9835  endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
9836  inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
9837  for (; year <= endYear; year++) {
9838  inst.yearshtml += "<option value='" + year + "'" +
9839  (year === drawYear ? " selected='selected'" : "") +
9840  ">" + year + "</option>";
9841  }
9842  inst.yearshtml += "</select>";
9843 
9844  html += inst.yearshtml;
9845  inst.yearshtml = null;
9846  }
9847  }
9848 
9849  html += this._get(inst, "yearSuffix");
9850  if (showMonthAfterYear) {
9851  html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
9852  }
9853  html += "</div>"; // Close datepicker_header
9854  return html;
9855  },
9856 
9857  /* Adjust one of the date sub-fields. */
9858  _adjustInstDate: function(inst, offset, period) {
9859  var year = inst.drawYear + (period === "Y" ? offset : 0),
9860  month = inst.drawMonth + (period === "M" ? offset : 0),
9861  day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
9862  date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
9863 
9864  inst.selectedDay = date.getDate();
9865  inst.drawMonth = inst.selectedMonth = date.getMonth();
9866  inst.drawYear = inst.selectedYear = date.getFullYear();
9867  if (period === "M" || period === "Y") {
9868  this._notifyChange(inst);
9869  }
9870  },
9871 
9872  /* Ensure a date is within any min/max bounds. */
9873  _restrictMinMax: function(inst, date) {
9874  var minDate = this._getMinMaxDate(inst, "min"),
9875  maxDate = this._getMinMaxDate(inst, "max"),
9876  newDate = (minDate && date < minDate ? minDate : date);
9877  return (maxDate && newDate > maxDate ? maxDate : newDate);
9878  },
9879 
9880  /* Notify change of month/year. */
9881  _notifyChange: function(inst) {
9882  var onChange = this._get(inst, "onChangeMonthYear");
9883  if (onChange) {
9884  onChange.apply((inst.input ? inst.input[0] : null),
9885  [inst.selectedYear, inst.selectedMonth + 1, inst]);
9886  }
9887  },
9888 
9889  /* Determine the number of months to show. */
9890  _getNumberOfMonths: function(inst) {
9891  var numMonths = this._get(inst, "numberOfMonths");
9892  return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
9893  },
9894 
9895  /* Determine the current maximum date - ensure no time components are set. */
9896  _getMinMaxDate: function(inst, minMax) {
9897  return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
9898  },
9899 
9900  /* Find the number of days in a given month. */
9901  _getDaysInMonth: function(year, month) {
9902  return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
9903  },
9904 
9905  /* Find the day of the week of the first of a month. */
9906  _getFirstDayOfMonth: function(year, month) {
9907  return new Date(year, month, 1).getDay();
9908  },
9909 
9910  /* Determines if we should allow a "next/prev" month display change. */
9911  _canAdjustMonth: function(inst, offset, curYear, curMonth) {
9912  var numMonths = this._getNumberOfMonths(inst),
9913  date = this._daylightSavingAdjust(new Date(curYear,
9914  curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
9915 
9916  if (offset < 0) {
9917  date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
9918  }
9919  return this._isInRange(inst, date);
9920  },
9921 
9922  /* Is the given date in the accepted range? */
9923  _isInRange: function(inst, date) {
9924  var yearSplit, currentYear,
9925  minDate = this._getMinMaxDate(inst, "min"),
9926  maxDate = this._getMinMaxDate(inst, "max"),
9927  minYear = null,
9928  maxYear = null,
9929  years = this._get(inst, "yearRange");
9930  if (years){
9931  yearSplit = years.split(":");
9932  currentYear = new Date().getFullYear();
9933  minYear = parseInt(yearSplit[0], 10);
9934  maxYear = parseInt(yearSplit[1], 10);
9935  if ( yearSplit[0].match(/[+\-].*/) ) {
9936  minYear += currentYear;
9937  }
9938  if ( yearSplit[1].match(/[+\-].*/) ) {
9939  maxYear += currentYear;
9940  }
9941  }
9942 
9943  return ((!minDate || date.getTime() >= minDate.getTime()) &&
9944  (!maxDate || date.getTime() <= maxDate.getTime()) &&
9945  (!minYear || date.getFullYear() >= minYear) &&
9946  (!maxYear || date.getFullYear() <= maxYear));
9947  },
9948 
9949  /* Provide the configuration settings for formatting/parsing. */
9950  _getFormatConfig: function(inst) {
9951  var shortYearCutoff = this._get(inst, "shortYearCutoff");
9952  shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
9953  new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9954  return {shortYearCutoff: shortYearCutoff,
9955  dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
9956  monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
9957  },
9958 
9959  /* Format the given date for display. */
9960  _formatDate: function(inst, day, month, year) {
9961  if (!day) {
9962  inst.currentDay = inst.selectedDay;
9963  inst.currentMonth = inst.selectedMonth;
9964  inst.currentYear = inst.selectedYear;
9965  }
9966  var date = (day ? (typeof day === "object" ? day :
9967  this._daylightSavingAdjust(new Date(year, month, day))) :
9968  this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9969  return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
9970  }
9971 });
9972 
9973 /*
9974  * Bind hover events for datepicker elements.
9975  * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9976  * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9977  */
9978 function datepicker_bindHover(dpDiv) {
9979  var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9980  return dpDiv.delegate(selector, "mouseout", function() {
9981  $(this).removeClass("ui-state-hover");
9982  if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9983  $(this).removeClass("ui-datepicker-prev-hover");
9984  }
9985  if (this.className.indexOf("ui-datepicker-next") !== -1) {
9986  $(this).removeClass("ui-datepicker-next-hover");
9987  }
9988  })
9989  .delegate( selector, "mouseover", datepicker_handleMouseover );
9990 }
9991 
9992 function datepicker_handleMouseover() {
9993  if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
9994  $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
9995  $(this).addClass("ui-state-hover");
9996  if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9997  $(this).addClass("ui-datepicker-prev-hover");
9998  }
9999  if (this.className.indexOf("ui-datepicker-next") !== -1) {
10000  $(this).addClass("ui-datepicker-next-hover");
10001  }
10002  }
10003 }
10004 
10005 /* jQuery extend now ignores nulls! */
10006 function datepicker_extendRemove(target, props) {
10007  $.extend(target, props);
10008  for (var name in props) {
10009  if (props[name] == null) {
10010  target[name] = props[name];
10011  }
10012  }
10013  return target;
10014 }
10015 
10016 /* Invoke the datepicker functionality.
10017  @param options string - a command, optionally followed by additional parameters or
10018  Object - settings for attaching new datepicker functionality
10019  @return jQuery object */
10020 $.fn.datepicker = function(options){
10021 
10022  /* Verify an empty collection wasn't passed - Fixes #6976 */
10023  if ( !this.length ) {
10024  return this;
10025  }
10026 
10027  /* Initialise the date picker. */
10028  if (!$.datepicker.initialized) {
10029  $(document).mousedown($.datepicker._checkExternalClick);
10030  $.datepicker.initialized = true;
10031  }
10032 
10033  /* Append datepicker main container to body if not exist. */
10034  if ($("#"+$.datepicker._mainDivId).length === 0) {
10035  $("body").append($.datepicker.dpDiv);
10036  }
10037 
10038  var otherArgs = Array.prototype.slice.call(arguments, 1);
10039  if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
10040  return $.datepicker["_" + options + "Datepicker"].
10041  apply($.datepicker, [this[0]].concat(otherArgs));
10042  }
10043  if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
10044  return $.datepicker["_" + options + "Datepicker"].
10045  apply($.datepicker, [this[0]].concat(otherArgs));
10046  }
10047  return this.each(function() {
10048  typeof options === "string" ?
10049  $.datepicker["_" + options + "Datepicker"].
10050  apply($.datepicker, [this].concat(otherArgs)) :
10051  $.datepicker._attachDatepicker(this, options);
10052  });
10053 };
10054 
10055 $.datepicker = new Datepicker(); // singleton instance
10056 $.datepicker.initialized = false;
10057 $.datepicker.uuid = new Date().getTime();
10058 $.datepicker.version = "1.11.2";
10059 
10060 var datepicker = $.datepicker;
10061 
10062 
10063 /*!
10064  * jQuery UI Dialog 1.11.2
10065  * http://jqueryui.com
10066  *
10067  * Copyright 2014 jQuery Foundation and other contributors
10068  * Released under the MIT license.
10069  * http://jquery.org/license
10070  *
10071  * http://api.jqueryui.com/dialog/
10072  */
10073 
10074 
10075 var dialog = $.widget( "ui.dialog", {
10076  version: "1.11.2",
10077  options: {
10078  appendTo: "body",
10079  autoOpen: true,
10080  buttons: [],
10081  closeOnEscape: true,
10082  closeText: "Close",
10083  dialogClass: "",
10084  draggable: true,
10085  hide: null,
10086  height: "auto",
10087  maxHeight: null,
10088  maxWidth: null,
10089  minHeight: 150,
10090  minWidth: 150,
10091  modal: false,
10092  position: {
10093  my: "center",
10094  at: "center",
10095  of: window,
10096  collision: "fit",
10097  // Ensure the titlebar is always visible
10098  using: function( pos ) {
10099  var topOffset = $( this ).css( pos ).offset().top;
10100  if ( topOffset < 0 ) {
10101  $( this ).css( "top", pos.top - topOffset );
10102  }
10103  }
10104  },
10105  resizable: true,
10106  show: null,
10107  title: null,
10108  width: 300,
10109 
10110  // callbacks
10111  beforeClose: null,
10112  close: null,
10113  drag: null,
10114  dragStart: null,
10115  dragStop: null,
10116  focus: null,
10117  open: null,
10118  resize: null,
10119  resizeStart: null,
10120  resizeStop: null
10121  },
10122 
10123  sizeRelatedOptions: {
10124  buttons: true,
10125  height: true,
10126  maxHeight: true,
10127  maxWidth: true,
10128  minHeight: true,
10129  minWidth: true,
10130  width: true
10131  },
10132 
10133  resizableRelatedOptions: {
10134  maxHeight: true,
10135  maxWidth: true,
10136  minHeight: true,
10137  minWidth: true
10138  },
10139 
10140  _create: function() {
10141  this.originalCss = {
10142  display: this.element[ 0 ].style.display,
10143  width: this.element[ 0 ].style.width,
10144  minHeight: this.element[ 0 ].style.minHeight,
10145  maxHeight: this.element[ 0 ].style.maxHeight,
10146  height: this.element[ 0 ].style.height
10147  };
10148  this.originalPosition = {
10149  parent: this.element.parent(),
10150  index: this.element.parent().children().index( this.element )
10151  };
10152  this.originalTitle = this.element.attr( "title" );
10153  this.options.title = this.options.title || this.originalTitle;
10154 
10155  this._createWrapper();
10156 
10157  this.element
10158  .show()
10159  .removeAttr( "title" )
10160  .addClass( "ui-dialog-content ui-widget-content" )
10161  .appendTo( this.uiDialog );
10162 
10163  this._createTitlebar();
10164  this._createButtonPane();
10165 
10166  if ( this.options.draggable && $.fn.draggable ) {
10167  this._makeDraggable();
10168  }
10169  if ( this.options.resizable && $.fn.resizable ) {
10170  this._makeResizable();
10171  }
10172 
10173  this._isOpen = false;
10174 
10175  this._trackFocus();
10176  },
10177 
10178  _init: function() {
10179  if ( this.options.autoOpen ) {
10180  this.open();
10181  }
10182  },
10183 
10184  _appendTo: function() {
10185  var element = this.options.appendTo;
10186  if ( element && (element.jquery || element.nodeType) ) {
10187  return $( element );
10188  }
10189  return this.document.find( element || "body" ).eq( 0 );
10190  },
10191 
10192  _destroy: function() {
10193  var next,
10194  originalPosition = this.originalPosition;
10195 
10196  this._destroyOverlay();
10197 
10198  this.element
10199  .removeUniqueId()
10200  .removeClass( "ui-dialog-content ui-widget-content" )
10201  .css( this.originalCss )
10202  // Without detaching first, the following becomes really slow
10203  .detach();
10204 
10205  this.uiDialog.stop( true, true ).remove();
10206 
10207  if ( this.originalTitle ) {
10208  this.element.attr( "title", this.originalTitle );
10209  }
10210 
10211  next = originalPosition.parent.children().eq( originalPosition.index );
10212  // Don't try to place the dialog next to itself (#8613)
10213  if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
10214  next.before( this.element );
10215  } else {
10216  originalPosition.parent.append( this.element );
10217  }
10218  },
10219 
10220  widget: function() {
10221  return this.uiDialog;
10222  },
10223 
10224  disable: $.noop,
10225  enable: $.noop,
10226 
10227  close: function( event ) {
10228  var activeElement,
10229  that = this;
10230 
10231  if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
10232  return;
10233  }
10234 
10235  this._isOpen = false;
10236  this._focusedElement = null;
10237  this._destroyOverlay();
10238  this._untrackInstance();
10239 
10240  if ( !this.opener.filter( ":focusable" ).focus().length ) {
10241 
10242  // support: IE9
10243  // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
10244  try {
10245  activeElement = this.document[ 0 ].activeElement;
10246 
10247  // Support: IE9, IE10
10248  // If the <body> is blurred, IE will switch windows, see #4520
10249  if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
10250 
10251  // Hiding a focused element doesn't trigger blur in WebKit
10252  // so in case we have nothing to focus on, explicitly blur the active element
10253  // https://bugs.webkit.org/show_bug.cgi?id=47182
10254  $( activeElement ).blur();
10255  }
10256  } catch ( error ) {}
10257  }
10258 
10259  this._hide( this.uiDialog, this.options.hide, function() {
10260  that._trigger( "close", event );
10261  });
10262  },
10263 
10264  isOpen: function() {
10265  return this._isOpen;
10266  },
10267 
10268  moveToTop: function() {
10269  this._moveToTop();
10270  },
10271 
10272  _moveToTop: function( event, silent ) {
10273  var moved = false,
10274  zIndicies = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
10275  return +$( this ).css( "z-index" );
10276  }).get(),
10277  zIndexMax = Math.max.apply( null, zIndicies );
10278 
10279  if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
10280  this.uiDialog.css( "z-index", zIndexMax + 1 );
10281  moved = true;
10282  }
10283 
10284  if ( moved && !silent ) {
10285  this._trigger( "focus", event );
10286  }
10287  return moved;
10288  },
10289 
10290  open: function() {
10291  var that = this;
10292  if ( this._isOpen ) {
10293  if ( this._moveToTop() ) {
10294  this._focusTabbable();
10295  }
10296  return;
10297  }
10298 
10299  this._isOpen = true;
10300  this.opener = $( this.document[ 0 ].activeElement );
10301 
10302  this._size();
10303  this._position();
10304  this._createOverlay();
10305  this._moveToTop( null, true );
10306 
10307  // Ensure the overlay is moved to the top with the dialog, but only when
10308  // opening. The overlay shouldn't move after the dialog is open so that
10309  // modeless dialogs opened after the modal dialog stack properly.
10310  if ( this.overlay ) {
10311  this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
10312  }
10313 
10314  this._show( this.uiDialog, this.options.show, function() {
10315  that._focusTabbable();
10316  that._trigger( "focus" );
10317  });
10318 
10319  // Track the dialog immediately upon openening in case a focus event
10320  // somehow occurs outside of the dialog before an element inside the
10321  // dialog is focused (#10152)
10322  this._makeFocusTarget();
10323 
10324  this._trigger( "open" );
10325  },
10326 
10327  _focusTabbable: function() {
10328  // Set focus to the first match:
10329  // 1. An element that was focused previously
10330  // 2. First element inside the dialog matching [autofocus]
10331  // 3. Tabbable element inside the content element
10332  // 4. Tabbable element inside the buttonpane
10333  // 5. The close button
10334  // 6. The dialog itself
10335  var hasFocus = this._focusedElement;
10336  if ( !hasFocus ) {
10337  hasFocus = this.element.find( "[autofocus]" );
10338  }
10339  if ( !hasFocus.length ) {
10340  hasFocus = this.element.find( ":tabbable" );
10341  }
10342  if ( !hasFocus.length ) {
10343  hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
10344  }
10345  if ( !hasFocus.length ) {
10346  hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
10347  }
10348  if ( !hasFocus.length ) {
10349  hasFocus = this.uiDialog;
10350  }
10351  hasFocus.eq( 0 ).focus();
10352  },
10353 
10354  _keepFocus: function( event ) {
10355  function checkFocus() {
10356  var activeElement = this.document[0].activeElement,
10357  isActive = this.uiDialog[0] === activeElement ||
10358  $.contains( this.uiDialog[0], activeElement );
10359  if ( !isActive ) {
10360  this._focusTabbable();
10361  }
10362  }
10363  event.preventDefault();
10364  checkFocus.call( this );
10365  // support: IE
10366  // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
10367  // so we check again later
10368  this._delay( checkFocus );
10369  },
10370 
10371  _createWrapper: function() {
10372  this.uiDialog = $("<div>")
10373  .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
10374  this.options.dialogClass )
10375  .hide()
10376  .attr({
10377  // Setting tabIndex makes the div focusable
10378  tabIndex: -1,
10379  role: "dialog"
10380  })
10381  .appendTo( this._appendTo() );
10382 
10383  this._on( this.uiDialog, {
10384  keydown: function( event ) {
10385  if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
10386  event.keyCode === $.ui.keyCode.ESCAPE ) {
10387  event.preventDefault();
10388  this.close( event );
10389  return;
10390  }
10391 
10392  // prevent tabbing out of dialogs
10393  if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
10394  return;
10395  }
10396  var tabbables = this.uiDialog.find( ":tabbable" ),
10397  first = tabbables.filter( ":first" ),
10398  last = tabbables.filter( ":last" );
10399 
10400  if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
10401  this._delay(function() {
10402  first.focus();
10403  });
10404  event.preventDefault();
10405  } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
10406  this._delay(function() {
10407  last.focus();
10408  });
10409  event.preventDefault();
10410  }
10411  },
10412  mousedown: function( event ) {
10413  if ( this._moveToTop( event ) ) {
10414  this._focusTabbable();
10415  }
10416  }
10417  });
10418 
10419  // We assume that any existing aria-describedby attribute means
10420  // that the dialog content is marked up properly
10421  // otherwise we brute force the content as the description
10422  if ( !this.element.find( "[aria-describedby]" ).length ) {
10423  this.uiDialog.attr({
10424  "aria-describedby": this.element.uniqueId().attr( "id" )
10425  });
10426  }
10427  },
10428 
10429  _createTitlebar: function() {
10430  var uiDialogTitle;
10431 
10432  this.uiDialogTitlebar = $( "<div>" )
10433  .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
10434  .prependTo( this.uiDialog );
10435  this._on( this.uiDialogTitlebar, {
10436  mousedown: function( event ) {
10437  // Don't prevent click on close button (#8838)
10438  // Focusing a dialog that is partially scrolled out of view
10439  // causes the browser to scroll it into view, preventing the click event
10440  if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
10441  // Dialog isn't getting focus when dragging (#8063)
10442  this.uiDialog.focus();
10443  }
10444  }
10445  });
10446 
10447  // support: IE
10448  // Use type="button" to prevent enter keypresses in textboxes from closing the
10449  // dialog in IE (#9312)
10450  this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
10451  .button({
10452  label: this.options.closeText,
10453  icons: {
10454  primary: "ui-icon-closethick"
10455  },
10456  text: false
10457  })
10458  .addClass( "ui-dialog-titlebar-close" )
10459  .appendTo( this.uiDialogTitlebar );
10460  this._on( this.uiDialogTitlebarClose, {
10461  click: function( event ) {
10462  event.preventDefault();
10463  this.close( event );
10464  }
10465  });
10466 
10467  uiDialogTitle = $( "<span>" )
10468  .uniqueId()
10469  .addClass( "ui-dialog-title" )
10470  .prependTo( this.uiDialogTitlebar );
10471  this._title( uiDialogTitle );
10472 
10473  this.uiDialog.attr({
10474  "aria-labelledby": uiDialogTitle.attr( "id" )
10475  });
10476  },
10477 
10478  _title: function( title ) {
10479  if ( !this.options.title ) {
10480  title.html( "&#160;" );
10481  }
10482  title.text( this.options.title );
10483  },
10484 
10485  _createButtonPane: function() {
10486  this.uiDialogButtonPane = $( "<div>" )
10487  .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
10488 
10489  this.uiButtonSet = $( "<div>" )
10490  .addClass( "ui-dialog-buttonset" )
10491  .appendTo( this.uiDialogButtonPane );
10492 
10493  this._createButtons();
10494  },
10495 
10496  _createButtons: function() {
10497  var that = this,
10498  buttons = this.options.buttons;
10499 
10500  // if we already have a button pane, remove it
10501  this.uiDialogButtonPane.remove();
10502  this.uiButtonSet.empty();
10503 
10504  if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
10505  this.uiDialog.removeClass( "ui-dialog-buttons" );
10506  return;
10507  }
10508 
10509  $.each( buttons, function( name, props ) {
10510  var click, buttonOptions;
10511  props = $.isFunction( props ) ?
10512  { click: props, text: name } :
10513  props;
10514  // Default to a non-submitting button
10515  props = $.extend( { type: "button" }, props );
10516  // Change the context for the click callback to be the main element
10517  click = props.click;
10518  props.click = function() {
10519  click.apply( that.element[ 0 ], arguments );
10520  };
10521  buttonOptions = {
10522  icons: props.icons,
10523  text: props.showText
10524  };
10525  delete props.icons;
10526  delete props.showText;
10527  $( "<button></button>", props )
10528  .button( buttonOptions )
10529  .appendTo( that.uiButtonSet );
10530  });
10531  this.uiDialog.addClass( "ui-dialog-buttons" );
10532  this.uiDialogButtonPane.appendTo( this.uiDialog );
10533  },
10534 
10535  _makeDraggable: function() {
10536  var that = this,
10537  options = this.options;
10538 
10539  function filteredUi( ui ) {
10540  return {
10541  position: ui.position,
10542  offset: ui.offset
10543  };
10544  }
10545 
10546  this.uiDialog.draggable({
10547  cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
10548  handle: ".ui-dialog-titlebar",
10549  containment: "document",
10550  start: function( event, ui ) {
10551  $( this ).addClass( "ui-dialog-dragging" );
10552  that._blockFrames();
10553  that._trigger( "dragStart", event, filteredUi( ui ) );
10554  },
10555  drag: function( event, ui ) {
10556  that._trigger( "drag", event, filteredUi( ui ) );
10557  },
10558  stop: function( event, ui ) {
10559  var left = ui.offset.left - that.document.scrollLeft(),
10560  top = ui.offset.top - that.document.scrollTop();
10561 
10562  options.position = {
10563  my: "left top",
10564  at: "left" + (left >= 0 ? "+" : "") + left + " " +
10565  "top" + (top >= 0 ? "+" : "") + top,
10566  of: that.window
10567  };
10568  $( this ).removeClass( "ui-dialog-dragging" );
10569  that._unblockFrames();
10570  that._trigger( "dragStop", event, filteredUi( ui ) );
10571  }
10572  });
10573  },
10574 
10575  _makeResizable: function() {
10576  var that = this,
10577  options = this.options,
10578  handles = options.resizable,
10579  // .ui-resizable has position: relative defined in the stylesheet
10580  // but dialogs have to use absolute or fixed positioning
10581  position = this.uiDialog.css("position"),
10582  resizeHandles = typeof handles === "string" ?
10583  handles :
10584  "n,e,s,w,se,sw,ne,nw";
10585 
10586  function filteredUi( ui ) {
10587  return {
10588  originalPosition: ui.originalPosition,
10589  originalSize: ui.originalSize,
10590  position: ui.position,
10591  size: ui.size
10592  };
10593  }
10594 
10595  this.uiDialog.resizable({
10596  cancel: ".ui-dialog-content",
10597  containment: "document",
10598  alsoResize: this.element,
10599  maxWidth: options.maxWidth,
10600  maxHeight: options.maxHeight,
10601  minWidth: options.minWidth,
10602  minHeight: this._minHeight(),
10603  handles: resizeHandles,
10604  start: function( event, ui ) {
10605  $( this ).addClass( "ui-dialog-resizing" );
10606  that._blockFrames();
10607  that._trigger( "resizeStart", event, filteredUi( ui ) );
10608  },
10609  resize: function( event, ui ) {
10610  that._trigger( "resize", event, filteredUi( ui ) );
10611  },
10612  stop: function( event, ui ) {
10613  var offset = that.uiDialog.offset(),
10614  left = offset.left - that.document.scrollLeft(),
10615  top = offset.top - that.document.scrollTop();
10616 
10617  options.height = that.uiDialog.height();
10618  options.width = that.uiDialog.width();
10619  options.position = {
10620  my: "left top",
10621  at: "left" + (left >= 0 ? "+" : "") + left + " " +
10622  "top" + (top >= 0 ? "+" : "") + top,
10623  of: that.window
10624  };
10625  $( this ).removeClass( "ui-dialog-resizing" );
10626  that._unblockFrames();
10627  that._trigger( "resizeStop", event, filteredUi( ui ) );
10628  }
10629  })
10630  .css( "position", position );
10631  },
10632 
10633  _trackFocus: function() {
10634  this._on( this.widget(), {
10635  focusin: function( event ) {
10636  this._makeFocusTarget();
10637  this._focusedElement = $( event.target );
10638  }
10639  });
10640  },
10641 
10642  _makeFocusTarget: function() {
10643  this._untrackInstance();
10644  this._trackingInstances().unshift( this );
10645  },
10646 
10647  _untrackInstance: function() {
10648  var instances = this._trackingInstances(),
10649  exists = $.inArray( this, instances );
10650  if ( exists !== -1 ) {
10651  instances.splice( exists, 1 );
10652  }
10653  },
10654 
10655  _trackingInstances: function() {
10656  var instances = this.document.data( "ui-dialog-instances" );
10657  if ( !instances ) {
10658  instances = [];
10659  this.document.data( "ui-dialog-instances", instances );
10660  }
10661  return instances;
10662  },
10663 
10664  _minHeight: function() {
10665  var options = this.options;
10666 
10667  return options.height === "auto" ?
10668  options.minHeight :
10669  Math.min( options.minHeight, options.height );
10670  },
10671 
10672  _position: function() {
10673  // Need to show the dialog to get the actual offset in the position plugin
10674  var isVisible = this.uiDialog.is( ":visible" );
10675  if ( !isVisible ) {
10676  this.uiDialog.show();
10677  }
10678  this.uiDialog.position( this.options.position );
10679  if ( !isVisible ) {
10680  this.uiDialog.hide();
10681  }
10682  },
10683 
10684  _setOptions: function( options ) {
10685  var that = this,
10686  resize = false,
10687  resizableOptions = {};
10688 
10689  $.each( options, function( key, value ) {
10690  that._setOption( key, value );
10691 
10692  if ( key in that.sizeRelatedOptions ) {
10693  resize = true;
10694  }
10695  if ( key in that.resizableRelatedOptions ) {
10696  resizableOptions[ key ] = value;
10697  }
10698  });
10699 
10700  if ( resize ) {
10701  this._size();
10702  this._position();
10703  }
10704  if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
10705  this.uiDialog.resizable( "option", resizableOptions );
10706  }
10707  },
10708 
10709  _setOption: function( key, value ) {
10710  var isDraggable, isResizable,
10711  uiDialog = this.uiDialog;
10712 
10713  if ( key === "dialogClass" ) {
10714  uiDialog
10715  .removeClass( this.options.dialogClass )
10716  .addClass( value );
10717  }
10718 
10719  if ( key === "disabled" ) {
10720  return;
10721  }
10722 
10723  this._super( key, value );
10724 
10725  if ( key === "appendTo" ) {
10726  this.uiDialog.appendTo( this._appendTo() );
10727  }
10728 
10729  if ( key === "buttons" ) {
10730  this._createButtons();
10731  }
10732 
10733  if ( key === "closeText" ) {
10734  this.uiDialogTitlebarClose.button({
10735  // Ensure that we always pass a string
10736  label: "" + value
10737  });
10738  }
10739 
10740  if ( key === "draggable" ) {
10741  isDraggable = uiDialog.is( ":data(ui-draggable)" );
10742  if ( isDraggable && !value ) {
10743  uiDialog.draggable( "destroy" );
10744  }
10745 
10746  if ( !isDraggable && value ) {
10747  this._makeDraggable();
10748  }
10749  }
10750 
10751  if ( key === "position" ) {
10752  this._position();
10753  }
10754 
10755  if ( key === "resizable" ) {
10756  // currently resizable, becoming non-resizable
10757  isResizable = uiDialog.is( ":data(ui-resizable)" );
10758  if ( isResizable && !value ) {
10759  uiDialog.resizable( "destroy" );
10760  }
10761 
10762  // currently resizable, changing handles
10763  if ( isResizable && typeof value === "string" ) {
10764  uiDialog.resizable( "option", "handles", value );
10765  }
10766 
10767  // currently non-resizable, becoming resizable
10768  if ( !isResizable && value !== false ) {
10769  this._makeResizable();
10770  }
10771  }
10772 
10773  if ( key === "title" ) {
10774  this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
10775  }
10776  },
10777 
10778  _size: function() {
10779  // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
10780  // divs will both have width and height set, so we need to reset them
10781  var nonContentHeight, minContentHeight, maxContentHeight,
10782  options = this.options;
10783 
10784  // Reset content sizing
10785  this.element.show().css({
10786  width: "auto",
10787  minHeight: 0,
10788  maxHeight: "none",
10789  height: 0
10790  });
10791 
10792  if ( options.minWidth > options.width ) {
10793  options.width = options.minWidth;
10794  }
10795 
10796  // reset wrapper sizing
10797  // determine the height of all the non-content elements
10798  nonContentHeight = this.uiDialog.css({
10799  height: "auto",
10800  width: options.width
10801  })
10802  .outerHeight();
10803  minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
10804  maxContentHeight = typeof options.maxHeight === "number" ?
10805  Math.max( 0, options.maxHeight - nonContentHeight ) :
10806  "none";
10807 
10808  if ( options.height === "auto" ) {
10809  this.element.css({
10810  minHeight: minContentHeight,
10811  maxHeight: maxContentHeight,
10812  height: "auto"
10813  });
10814  } else {
10815  this.element.height( Math.max( 0, options.height - nonContentHeight ) );
10816  }
10817 
10818  if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
10819  this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
10820  }
10821  },
10822 
10823  _blockFrames: function() {
10824  this.iframeBlocks = this.document.find( "iframe" ).map(function() {
10825  var iframe = $( this );
10826 
10827  return $( "<div>" )
10828  .css({
10829  position: "absolute",
10830  width: iframe.outerWidth(),
10831  height: iframe.outerHeight()
10832  })
10833  .appendTo( iframe.parent() )
10834  .offset( iframe.offset() )[0];
10835  });
10836  },
10837 
10838  _unblockFrames: function() {
10839  if ( this.iframeBlocks ) {
10840  this.iframeBlocks.remove();
10841  delete this.iframeBlocks;
10842  }
10843  },
10844 
10845  _allowInteraction: function( event ) {
10846  if ( $( event.target ).closest( ".ui-dialog" ).length ) {
10847  return true;
10848  }
10849 
10850  // TODO: Remove hack when datepicker implements
10851  // the .ui-front logic (#8989)
10852  return !!$( event.target ).closest( ".ui-datepicker" ).length;
10853  },
10854 
10855  _createOverlay: function() {
10856  if ( !this.options.modal ) {
10857  return;
10858  }
10859 
10860  // We use a delay in case the overlay is created from an
10861  // event that we're going to be cancelling (#2804)
10862  var isOpening = true;
10863  this._delay(function() {
10864  isOpening = false;
10865  });
10866 
10867  if ( !this.document.data( "ui-dialog-overlays" ) ) {
10868 
10869  // Prevent use of anchors and inputs
10870  // Using _on() for an event handler shared across many instances is
10871  // safe because the dialogs stack and must be closed in reverse order
10872  this._on( this.document, {
10873  focusin: function( event ) {
10874  if ( isOpening ) {
10875  return;
10876  }
10877 
10878  if ( !this._allowInteraction( event ) ) {
10879  event.preventDefault();
10880  this._trackingInstances()[ 0 ]._focusTabbable();
10881  }
10882  }
10883  });
10884  }
10885 
10886  this.overlay = $( "<div>" )
10887  .addClass( "ui-widget-overlay ui-front" )
10888  .appendTo( this._appendTo() );
10889  this._on( this.overlay, {
10890  mousedown: "_keepFocus"
10891  });
10892  this.document.data( "ui-dialog-overlays",
10893  (this.document.data( "ui-dialog-overlays" ) || 0) + 1 );
10894  },
10895 
10896  _destroyOverlay: function() {
10897  if ( !this.options.modal ) {
10898  return;
10899  }
10900 
10901  if ( this.overlay ) {
10902  var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
10903 
10904  if ( !overlays ) {
10905  this.document
10906  .unbind( "focusin" )
10907  .removeData( "ui-dialog-overlays" );
10908  } else {
10909  this.document.data( "ui-dialog-overlays", overlays );
10910  }
10911 
10912  this.overlay.remove();
10913  this.overlay = null;
10914  }
10915  }
10916 });
10917 
10918 
10919 /*!
10920  * jQuery UI Progressbar 1.11.2
10921  * http://jqueryui.com
10922  *
10923  * Copyright 2014 jQuery Foundation and other contributors
10924  * Released under the MIT license.
10925  * http://jquery.org/license
10926  *
10927  * http://api.jqueryui.com/progressbar/
10928  */
10929 
10930 
10931 var progressbar = $.widget( "ui.progressbar", {
10932  version: "1.11.2",
10933  options: {
10934  max: 100,
10935  value: 0,
10936 
10937  change: null,
10938  complete: null
10939  },
10940 
10941  min: 0,
10942 
10943  _create: function() {
10944  // Constrain initial value
10945  this.oldValue = this.options.value = this._constrainedValue();
10946 
10947  this.element
10948  .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10949  .attr({
10950  // Only set static values, aria-valuenow and aria-valuemax are
10951  // set inside _refreshValue()
10952  role: "progressbar",
10953  "aria-valuemin": this.min
10954  });
10955 
10956  this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
10957  .appendTo( this.element );
10958 
10959  this._refreshValue();
10960  },
10961 
10962  _destroy: function() {
10963  this.element
10964  .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10965  .removeAttr( "role" )
10966  .removeAttr( "aria-valuemin" )
10967  .removeAttr( "aria-valuemax" )
10968  .removeAttr( "aria-valuenow" );
10969 
10970  this.valueDiv.remove();
10971  },
10972 
10973  value: function( newValue ) {
10974  if ( newValue === undefined ) {
10975  return this.options.value;
10976  }
10977 
10978  this.options.value = this._constrainedValue( newValue );
10979  this._refreshValue();
10980  },
10981 
10982  _constrainedValue: function( newValue ) {
10983  if ( newValue === undefined ) {
10984  newValue = this.options.value;
10985  }
10986 
10987  this.indeterminate = newValue === false;
10988 
10989  // sanitize value
10990  if ( typeof newValue !== "number" ) {
10991  newValue = 0;
10992  }
10993 
10994  return this.indeterminate ? false :
10995  Math.min( this.options.max, Math.max( this.min, newValue ) );
10996  },
10997 
10998  _setOptions: function( options ) {
10999  // Ensure "value" option is set after other values (like max)
11000  var value = options.value;
11001  delete options.value;
11002 
11003  this._super( options );
11004 
11005  this.options.value = this._constrainedValue( value );
11006  this._refreshValue();
11007  },
11008 
11009  _setOption: function( key, value ) {
11010  if ( key === "max" ) {
11011  // Don't allow a max less than min
11012  value = Math.max( this.min, value );
11013  }
11014  if ( key === "disabled" ) {
11015  this.element
11016  .toggleClass( "ui-state-disabled", !!value )
11017  .attr( "aria-disabled", value );
11018  }
11019  this._super( key, value );
11020  },
11021 
11022  _percentage: function() {
11023  return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
11024  },
11025 
11026  _refreshValue: function() {
11027  var value = this.options.value,
11028  percentage = this._percentage();
11029 
11030  this.valueDiv
11031  .toggle( this.indeterminate || value > this.min )
11032  .toggleClass( "ui-corner-right", value === this.options.max )
11033  .width( percentage.toFixed(0) + "%" );
11034 
11035  this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
11036 
11037  if ( this.indeterminate ) {
11038  this.element.removeAttr( "aria-valuenow" );
11039  if ( !this.overlayDiv ) {
11040  this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
11041  }
11042  } else {
11043  this.element.attr({
11044  "aria-valuemax": this.options.max,
11045  "aria-valuenow": value
11046  });
11047  if ( this.overlayDiv ) {
11048  this.overlayDiv.remove();
11049  this.overlayDiv = null;
11050  }
11051  }
11052 
11053  if ( this.oldValue !== value ) {
11054  this.oldValue = value;
11055  this._trigger( "change" );
11056  }
11057  if ( value === this.options.max ) {
11058  this._trigger( "complete" );
11059  }
11060  }
11061 });
11062 
11063 
11064 /*!
11065  * jQuery UI Selectmenu 1.11.2
11066  * http://jqueryui.com
11067  *
11068  * Copyright 2014 jQuery Foundation and other contributors
11069  * Released under the MIT license.
11070  * http://jquery.org/license
11071  *
11072  * http://api.jqueryui.com/selectmenu
11073  */
11074 
11075 
11076 var selectmenu = $.widget( "ui.selectmenu", {
11077  version: "1.11.2",
11078  defaultElement: "<select>",
11079  options: {
11080  appendTo: null,
11081  disabled: null,
11082  icons: {
11083  button: "ui-icon-triangle-1-s"
11084  },
11085  position: {
11086  my: "left top",
11087  at: "left bottom",
11088  collision: "none"
11089  },
11090  width: null,
11091 
11092  // callbacks
11093  change: null,
11094  close: null,
11095  focus: null,
11096  open: null,
11097  select: null
11098  },
11099 
11100  _create: function() {
11101  var selectmenuId = this.element.uniqueId().attr( "id" );
11102  this.ids = {
11103  element: selectmenuId,
11104  button: selectmenuId + "-button",
11105  menu: selectmenuId + "-menu"
11106  };
11107 
11108  this._drawButton();
11109  this._drawMenu();
11110 
11111  if ( this.options.disabled ) {
11112  this.disable();
11113  }
11114  },
11115 
11116  _drawButton: function() {
11117  var that = this,
11118  tabindex = this.element.attr( "tabindex" );
11119 
11120  // Associate existing label with the new button
11121  this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button );
11122  this._on( this.label, {
11123  click: function( event ) {
11124  this.button.focus();
11125  event.preventDefault();
11126  }
11127  });
11128 
11129  // Hide original select element
11130  this.element.hide();
11131 
11132  // Create button
11133  this.button = $( "<span>", {
11134  "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
11135  tabindex: tabindex || this.options.disabled ? -1 : 0,
11136  id: this.ids.button,
11137  role: "combobox",
11138  "aria-expanded": "false",
11139  "aria-autocomplete": "list",
11140  "aria-owns": this.ids.menu,
11141  "aria-haspopup": "true"
11142  })
11143  .insertAfter( this.element );
11144 
11145  $( "<span>", {
11146  "class": "ui-icon " + this.options.icons.button
11147  })
11148  .prependTo( this.button );
11149 
11150  this.buttonText = $( "<span>", {
11151  "class": "ui-selectmenu-text"
11152  })
11153  .appendTo( this.button );
11154 
11155  this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
11156  this._resizeButton();
11157 
11158  this._on( this.button, this._buttonEvents );
11159  this.button.one( "focusin", function() {
11160 
11161  // Delay rendering the menu items until the button receives focus.
11162  // The menu may have already been rendered via a programmatic open.
11163  if ( !that.menuItems ) {
11164  that._refreshMenu();
11165  }
11166  });
11167  this._hoverable( this.button );
11168  this._focusable( this.button );
11169  },
11170 
11171  _drawMenu: function() {
11172  var that = this;
11173 
11174  // Create menu
11175  this.menu = $( "<ul>", {
11176  "aria-hidden": "true",
11177  "aria-labelledby": this.ids.button,
11178  id: this.ids.menu
11179  });
11180 
11181  // Wrap menu
11182  this.menuWrap = $( "<div>", {
11183  "class": "ui-selectmenu-menu ui-front"
11184  })
11185  .append( this.menu )
11186  .appendTo( this._appendTo() );
11187 
11188  // Initialize menu widget
11189  this.menuInstance = this.menu
11190  .menu({
11191  role: "listbox",
11192  select: function( event, ui ) {
11193  event.preventDefault();
11194 
11195  // support: IE8
11196  // If the item was selected via a click, the text selection
11197  // will be destroyed in IE
11198  that._setSelection();
11199 
11200  that._select( ui.item.data( "ui-selectmenu-item" ), event );
11201  },
11202  focus: function( event, ui ) {
11203  var item = ui.item.data( "ui-selectmenu-item" );
11204 
11205  // Prevent inital focus from firing and check if its a newly focused item
11206  if ( that.focusIndex != null && item.index !== that.focusIndex ) {
11207  that._trigger( "focus", event, { item: item } );
11208  if ( !that.isOpen ) {
11209  that._select( item, event );
11210  }
11211  }
11212  that.focusIndex = item.index;
11213 
11214  that.button.attr( "aria-activedescendant",
11215  that.menuItems.eq( item.index ).attr( "id" ) );
11216  }
11217  })
11218  .menu( "instance" );
11219 
11220  // Adjust menu styles to dropdown
11221  this.menu
11222  .addClass( "ui-corner-bottom" )
11223  .removeClass( "ui-corner-all" );
11224 
11225  // Don't close the menu on mouseleave
11226  this.menuInstance._off( this.menu, "mouseleave" );
11227 
11228  // Cancel the menu's collapseAll on document click
11229  this.menuInstance._closeOnDocumentClick = function() {
11230  return false;
11231  };
11232 
11233  // Selects often contain empty items, but never contain dividers
11234  this.menuInstance._isDivider = function() {
11235  return false;
11236  };
11237  },
11238 
11239  refresh: function() {
11240  this._refreshMenu();
11241  this._setText( this.buttonText, this._getSelectedItem().text() );
11242  if ( !this.options.width ) {
11243  this._resizeButton();
11244  }
11245  },
11246 
11247  _refreshMenu: function() {
11248  this.menu.empty();
11249 
11250  var item,
11251  options = this.element.find( "option" );
11252 
11253  if ( !options.length ) {
11254  return;
11255  }
11256 
11257  this._parseOptions( options );
11258  this._renderMenu( this.menu, this.items );
11259 
11260  this.menuInstance.refresh();
11261  this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );
11262 
11263  item = this._getSelectedItem();
11264 
11265  // Update the menu to have the correct item focused
11266  this.menuInstance.focus( null, item );
11267  this._setAria( item.data( "ui-selectmenu-item" ) );
11268 
11269  // Set disabled state
11270  this._setOption( "disabled", this.element.prop( "disabled" ) );
11271  },
11272 
11273  open: function( event ) {
11274  if ( this.options.disabled ) {
11275  return;
11276  }
11277 
11278  // If this is the first time the menu is being opened, render the items
11279  if ( !this.menuItems ) {
11280  this._refreshMenu();
11281  } else {
11282 
11283  // Menu clears focus on close, reset focus to selected item
11284  this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
11285  this.menuInstance.focus( null, this._getSelectedItem() );
11286  }
11287 
11288  this.isOpen = true;
11289  this._toggleAttr();
11290  this._resizeMenu();
11291  this._position();
11292 
11293  this._on( this.document, this._documentClick );
11294 
11295  this._trigger( "open", event );
11296  },
11297 
11298  _position: function() {
11299  this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
11300  },
11301 
11302  close: function( event ) {
11303  if ( !this.isOpen ) {
11304  return;
11305  }
11306 
11307  this.isOpen = false;
11308  this._toggleAttr();
11309 
11310  this.range = null;
11311  this._off( this.document );
11312 
11313  this._trigger( "close", event );
11314  },
11315 
11316  widget: function() {
11317  return this.button;
11318  },
11319 
11320  menuWidget: function() {
11321  return this.menu;
11322  },
11323 
11324  _renderMenu: function( ul, items ) {
11325  var that = this,
11326  currentOptgroup = "";
11327 
11328  $.each( items, function( index, item ) {
11329  if ( item.optgroup !== currentOptgroup ) {
11330  $( "<li>", {
11331  "class": "ui-selectmenu-optgroup ui-menu-divider" +
11332  ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
11333  " ui-state-disabled" :
11334  "" ),
11335  text: item.optgroup
11336  })
11337  .appendTo( ul );
11338 
11339  currentOptgroup = item.optgroup;
11340  }
11341 
11342  that._renderItemData( ul, item );
11343  });
11344  },
11345 
11346  _renderItemData: function( ul, item ) {
11347  return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
11348  },
11349 
11350  _renderItem: function( ul, item ) {
11351  var li = $( "<li>" );
11352 
11353  if ( item.disabled ) {
11354  li.addClass( "ui-state-disabled" );
11355  }
11356  this._setText( li, item.label );
11357 
11358  return li.appendTo( ul );
11359  },
11360 
11361  _setText: function( element, value ) {
11362  if ( value ) {
11363  element.text( value );
11364  } else {
11365  element.html( "&#160;" );
11366  }
11367  },
11368 
11369  _move: function( direction, event ) {
11370  var item, next,
11371  filter = ".ui-menu-item";
11372 
11373  if ( this.isOpen ) {
11374  item = this.menuItems.eq( this.focusIndex );
11375  } else {
11376  item = this.menuItems.eq( this.element[ 0 ].selectedIndex );
11377  filter += ":not(.ui-state-disabled)";
11378  }
11379 
11380  if ( direction === "first" || direction === "last" ) {
11381  next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
11382  } else {
11383  next = item[ direction + "All" ]( filter ).eq( 0 );
11384  }
11385 
11386  if ( next.length ) {
11387  this.menuInstance.focus( event, next );
11388  }
11389  },
11390 
11391  _getSelectedItem: function() {
11392  return this.menuItems.eq( this.element[ 0 ].selectedIndex );
11393  },
11394 
11395  _toggle: function( event ) {
11396  this[ this.isOpen ? "close" : "open" ]( event );
11397  },
11398 
11399  _setSelection: function() {
11400  var selection;
11401 
11402  if ( !this.range ) {
11403  return;
11404  }
11405 
11406  if ( window.getSelection ) {
11407  selection = window.getSelection();
11408  selection.removeAllRanges();
11409  selection.addRange( this.range );
11410 
11411  // support: IE8
11412  } else {
11413  this.range.select();
11414  }
11415 
11416  // support: IE
11417  // Setting the text selection kills the button focus in IE, but
11418  // restoring the focus doesn't kill the selection.
11419  this.button.focus();
11420  },
11421 
11422  _documentClick: {
11423  mousedown: function( event ) {
11424  if ( !this.isOpen ) {
11425  return;
11426  }
11427 
11428  if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) {
11429  this.close( event );
11430  }
11431  }
11432  },
11433 
11434  _buttonEvents: {
11435 
11436  // Prevent text selection from being reset when interacting with the selectmenu (#10144)
11437  mousedown: function() {
11438  var selection;
11439 
11440  if ( window.getSelection ) {
11441  selection = window.getSelection();
11442  if ( selection.rangeCount ) {
11443  this.range = selection.getRangeAt( 0 );
11444  }
11445 
11446  // support: IE8
11447  } else {
11448  this.range = document.selection.createRange();
11449  }
11450  },
11451 
11452  click: function( event ) {
11453  this._setSelection();
11454  this._toggle( event );
11455  },
11456 
11457  keydown: function( event ) {
11458  var preventDefault = true;
11459  switch ( event.keyCode ) {
11460  case $.ui.keyCode.TAB:
11461  case $.ui.keyCode.ESCAPE:
11462  this.close( event );
11463  preventDefault = false;
11464  break;
11465  case $.ui.keyCode.ENTER:
11466  if ( this.isOpen ) {
11467  this._selectFocusedItem( event );
11468  }
11469  break;
11470  case $.ui.keyCode.UP:
11471  if ( event.altKey ) {
11472  this._toggle( event );
11473  } else {
11474  this._move( "prev", event );
11475  }
11476  break;
11477  case $.ui.keyCode.DOWN:
11478  if ( event.altKey ) {
11479  this._toggle( event );
11480  } else {
11481  this._move( "next", event );
11482  }
11483  break;
11484  case $.ui.keyCode.SPACE:
11485  if ( this.isOpen ) {
11486  this._selectFocusedItem( event );
11487  } else {
11488  this._toggle( event );
11489  }
11490  break;
11491  case $.ui.keyCode.LEFT:
11492  this._move( "prev", event );
11493  break;
11494  case $.ui.keyCode.RIGHT:
11495  this._move( "next", event );
11496  break;
11497  case $.ui.keyCode.HOME:
11498  case $.ui.keyCode.PAGE_UP:
11499  this._move( "first", event );
11500  break;
11501  case $.ui.keyCode.END:
11502  case $.ui.keyCode.PAGE_DOWN:
11503  this._move( "last", event );
11504  break;
11505  default:
11506  this.menu.trigger( event );
11507  preventDefault = false;
11508  }
11509 
11510  if ( preventDefault ) {
11511  event.preventDefault();
11512  }
11513  }
11514  },
11515 
11516  _selectFocusedItem: function( event ) {
11517  var item = this.menuItems.eq( this.focusIndex );
11518  if ( !item.hasClass( "ui-state-disabled" ) ) {
11519  this._select( item.data( "ui-selectmenu-item" ), event );
11520  }
11521  },
11522 
11523  _select: function( item, event ) {
11524  var oldIndex = this.element[ 0 ].selectedIndex;
11525 
11526  // Change native select element
11527  this.element[ 0 ].selectedIndex = item.index;
11528  this._setText( this.buttonText, item.label );
11529  this._setAria( item );
11530  this._trigger( "select", event, { item: item } );
11531 
11532  if ( item.index !== oldIndex ) {
11533  this._trigger( "change", event, { item: item } );
11534  }
11535 
11536  this.close( event );
11537  },
11538 
11539  _setAria: function( item ) {
11540  var id = this.menuItems.eq( item.index ).attr( "id" );
11541 
11542  this.button.attr({
11543  "aria-labelledby": id,
11544  "aria-activedescendant": id
11545  });
11546  this.menu.attr( "aria-activedescendant", id );
11547  },
11548 
11549  _setOption: function( key, value ) {
11550  if ( key === "icons" ) {
11551  this.button.find( "span.ui-icon" )
11552  .removeClass( this.options.icons.button )
11553  .addClass( value.button );
11554  }
11555 
11556  this._super( key, value );
11557 
11558  if ( key === "appendTo" ) {
11559  this.menuWrap.appendTo( this._appendTo() );
11560  }
11561 
11562  if ( key === "disabled" ) {
11563  this.menuInstance.option( "disabled", value );
11564  this.button
11565  .toggleClass( "ui-state-disabled", value )
11566  .attr( "aria-disabled", value );
11567 
11568  this.element.prop( "disabled", value );
11569  if ( value ) {
11570  this.button.attr( "tabindex", -1 );
11571  this.close();
11572  } else {
11573  this.button.attr( "tabindex", 0 );
11574  }
11575  }
11576 
11577  if ( key === "width" ) {
11578  this._resizeButton();
11579  }
11580  },
11581 
11582  _appendTo: function() {
11583  var element = this.options.appendTo;
11584 
11585  if ( element ) {
11586  element = element.jquery || element.nodeType ?
11587  $( element ) :
11588  this.document.find( element ).eq( 0 );
11589  }
11590 
11591  if ( !element || !element[ 0 ] ) {
11592  element = this.element.closest( ".ui-front" );
11593  }
11594 
11595  if ( !element.length ) {
11596  element = this.document[ 0 ].body;
11597  }
11598 
11599  return element;
11600  },
11601 
11602  _toggleAttr: function() {
11603  this.button
11604  .toggleClass( "ui-corner-top", this.isOpen )
11605  .toggleClass( "ui-corner-all", !this.isOpen )
11606  .attr( "aria-expanded", this.isOpen );
11607  this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
11608  this.menu.attr( "aria-hidden", !this.isOpen );
11609  },
11610 
11611  _resizeButton: function() {
11612  var width = this.options.width;
11613 
11614  if ( !width ) {
11615  width = this.element.show().outerWidth();
11616  this.element.hide();
11617  }
11618 
11619  this.button.outerWidth( width );
11620  },
11621 
11622  _resizeMenu: function() {
11623  this.menu.outerWidth( Math.max(
11624  this.button.outerWidth(),
11625 
11626  // support: IE10
11627  // IE10 wraps long text (possibly a rounding bug)
11628  // so we add 1px to avoid the wrapping
11629  this.menu.width( "" ).outerWidth() + 1
11630  ) );
11631  },
11632 
11633  _getCreateOptions: function() {
11634  return { disabled: this.element.prop( "disabled" ) };
11635  },
11636 
11637  _parseOptions: function( options ) {
11638  var data = [];
11639  options.each(function( index, item ) {
11640  var option = $( item ),
11641  optgroup = option.parent( "optgroup" );
11642  data.push({
11643  element: option,
11644  index: index,
11645  value: option.attr( "value" ),
11646  label: option.text(),
11647  optgroup: optgroup.attr( "label" ) || "",
11648  disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
11649  });
11650  });
11651  this.items = data;
11652  },
11653 
11654  _destroy: function() {
11655  this.menuWrap.remove();
11656  this.button.remove();
11657  this.element.show();
11658  this.element.removeUniqueId();
11659  this.label.attr( "for", this.ids.element );
11660  }
11661 });
11662 
11663 
11664 /*!
11665  * jQuery UI Slider 1.11.2
11666  * http://jqueryui.com
11667  *
11668  * Copyright 2014 jQuery Foundation and other contributors
11669  * Released under the MIT license.
11670  * http://jquery.org/license
11671  *
11672  * http://api.jqueryui.com/slider/
11673  */
11674 
11675 
11676 var slider = $.widget( "ui.slider", $.ui.mouse, {
11677  version: "1.11.2",
11678  widgetEventPrefix: "slide",
11679 
11680  options: {
11681  animate: false,
11682  distance: 0,
11683  max: 100,
11684  min: 0,
11685  orientation: "horizontal",
11686  range: false,
11687  step: 1,
11688  value: 0,
11689  values: null,
11690 
11691  // callbacks
11692  change: null,
11693  slide: null,
11694  start: null,
11695  stop: null
11696  },
11697 
11698  // number of pages in a slider
11699  // (how many times can you page up/down to go through the whole range)
11700  numPages: 5,
11701 
11702  _create: function() {
11703  this._keySliding = false;
11704  this._mouseSliding = false;
11705  this._animateOff = true;
11706  this._handleIndex = null;
11707  this._detectOrientation();
11708  this._mouseInit();
11709  this._calculateNewMax();
11710 
11711  this.element
11712  .addClass( "ui-slider" +
11713  " ui-slider-" + this.orientation +
11714  " ui-widget" +
11715  " ui-widget-content" +
11716  " ui-corner-all");
11717 
11718  this._refresh();
11719  this._setOption( "disabled", this.options.disabled );
11720 
11721  this._animateOff = false;
11722  },
11723 
11724  _refresh: function() {
11725  this._createRange();
11726  this._createHandles();
11727  this._setupEvents();
11728  this._refreshValue();
11729  },
11730 
11731  _createHandles: function() {
11732  var i, handleCount,
11733  options = this.options,
11734  existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
11735  handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",
11736  handles = [];
11737 
11738  handleCount = ( options.values && options.values.length ) || 1;
11739 
11740  if ( existingHandles.length > handleCount ) {
11741  existingHandles.slice( handleCount ).remove();
11742  existingHandles = existingHandles.slice( 0, handleCount );
11743  }
11744 
11745  for ( i = existingHandles.length; i < handleCount; i++ ) {
11746  handles.push( handle );
11747  }
11748 
11749  this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
11750 
11751  this.handle = this.handles.eq( 0 );
11752 
11753  this.handles.each(function( i ) {
11754  $( this ).data( "ui-slider-handle-index", i );
11755  });
11756  },
11757 
11758  _createRange: function() {
11759  var options = this.options,
11760  classes = "";
11761 
11762  if ( options.range ) {
11763  if ( options.range === true ) {
11764  if ( !options.values ) {
11765  options.values = [ this._valueMin(), this._valueMin() ];
11766  } else if ( options.values.length && options.values.length !== 2 ) {
11767  options.values = [ options.values[0], options.values[0] ];
11768  } else if ( $.isArray( options.values ) ) {
11769  options.values = options.values.slice(0);
11770  }
11771  }
11772 
11773  if ( !this.range || !this.range.length ) {
11774  this.range = $( "<div></div>" )
11775  .appendTo( this.element );
11776 
11777  classes = "ui-slider-range" +
11778  // note: this isn't the most fittingly semantic framework class for this element,
11779  // but worked best visually with a variety of themes
11780  " ui-widget-header ui-corner-all";
11781  } else {
11782  this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
11783  // Handle range switching from true to min/max
11784  .css({
11785  "left": "",
11786  "bottom": ""
11787  });
11788  }
11789 
11790  this.range.addClass( classes +
11791  ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
11792  } else {
11793  if ( this.range ) {
11794  this.range.remove();
11795  }
11796  this.range = null;
11797  }
11798  },
11799 
11800  _setupEvents: function() {
11801  this._off( this.handles );
11802  this._on( this.handles, this._handleEvents );
11803  this._hoverable( this.handles );
11804  this._focusable( this.handles );
11805  },
11806 
11807  _destroy: function() {
11808  this.handles.remove();
11809  if ( this.range ) {
11810  this.range.remove();
11811  }
11812 
11813  this.element
11814  .removeClass( "ui-slider" +
11815  " ui-slider-horizontal" +
11816  " ui-slider-vertical" +
11817  " ui-widget" +
11818  " ui-widget-content" +
11819  " ui-corner-all" );
11820 
11821  this._mouseDestroy();
11822  },
11823 
11824  _mouseCapture: function( event ) {
11825  var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
11826  that = this,
11827  o = this.options;
11828 
11829  if ( o.disabled ) {
11830  return false;
11831  }
11832 
11833  this.elementSize = {
11834  width: this.element.outerWidth(),
11835  height: this.element.outerHeight()
11836  };
11837  this.elementOffset = this.element.offset();
11838 
11839  position = { x: event.pageX, y: event.pageY };
11840  normValue = this._normValueFromMouse( position );
11841  distance = this._valueMax() - this._valueMin() + 1;
11842  this.handles.each(function( i ) {
11843  var thisDistance = Math.abs( normValue - that.values(i) );
11844  if (( distance > thisDistance ) ||
11845  ( distance === thisDistance &&
11846  (i === that._lastChangedValue || that.values(i) === o.min ))) {
11847  distance = thisDistance;
11848  closestHandle = $( this );
11849  index = i;
11850  }
11851  });
11852 
11853  allowed = this._start( event, index );
11854  if ( allowed === false ) {
11855  return false;
11856  }
11857  this._mouseSliding = true;
11858 
11859  this._handleIndex = index;
11860 
11861  closestHandle
11862  .addClass( "ui-state-active" )
11863  .focus();
11864 
11865  offset = closestHandle.offset();
11866  mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
11867  this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
11868  left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
11869  top: event.pageY - offset.top -
11870  ( closestHandle.height() / 2 ) -
11871  ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
11872  ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
11873  ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
11874  };
11875 
11876  if ( !this.handles.hasClass( "ui-state-hover" ) ) {
11877  this._slide( event, index, normValue );
11878  }
11879  this._animateOff = true;
11880  return true;
11881  },
11882 
11883  _mouseStart: function() {
11884  return true;
11885  },
11886 
11887  _mouseDrag: function( event ) {
11888  var position = { x: event.pageX, y: event.pageY },
11889  normValue = this._normValueFromMouse( position );
11890 
11891  this._slide( event, this._handleIndex, normValue );
11892 
11893  return false;
11894  },
11895 
11896  _mouseStop: function( event ) {
11897  this.handles.removeClass( "ui-state-active" );
11898  this._mouseSliding = false;
11899 
11900  this._stop( event, this._handleIndex );
11901  this._change( event, this._handleIndex );
11902 
11903  this._handleIndex = null;
11904  this._clickOffset = null;
11905  this._animateOff = false;
11906 
11907  return false;
11908  },
11909 
11910  _detectOrientation: function() {
11911  this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
11912  },
11913 
11914  _normValueFromMouse: function( position ) {
11915  var pixelTotal,
11916  pixelMouse,
11917  percentMouse,
11918  valueTotal,
11919  valueMouse;
11920 
11921  if ( this.orientation === "horizontal" ) {
11922  pixelTotal = this.elementSize.width;
11923  pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
11924  } else {
11925  pixelTotal = this.elementSize.height;
11926  pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
11927  }
11928 
11929  percentMouse = ( pixelMouse / pixelTotal );
11930  if ( percentMouse > 1 ) {
11931  percentMouse = 1;
11932  }
11933  if ( percentMouse < 0 ) {
11934  percentMouse = 0;
11935  }
11936  if ( this.orientation === "vertical" ) {
11937  percentMouse = 1 - percentMouse;
11938  }
11939 
11940  valueTotal = this._valueMax() - this._valueMin();
11941  valueMouse = this._valueMin() + percentMouse * valueTotal;
11942 
11943  return this._trimAlignValue( valueMouse );
11944  },
11945 
11946  _start: function( event, index ) {
11947  var uiHash = {
11948  handle: this.handles[ index ],
11949  value: this.value()
11950  };
11951  if ( this.options.values && this.options.values.length ) {
11952  uiHash.value = this.values( index );
11953  uiHash.values = this.values();
11954  }
11955  return this._trigger( "start", event, uiHash );
11956  },
11957 
11958  _slide: function( event, index, newVal ) {
11959  var otherVal,
11960  newValues,
11961  allowed;
11962 
11963  if ( this.options.values && this.options.values.length ) {
11964  otherVal = this.values( index ? 0 : 1 );
11965 
11966  if ( ( this.options.values.length === 2 && this.options.range === true ) &&
11967  ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
11968  ) {
11969  newVal = otherVal;
11970  }
11971 
11972  if ( newVal !== this.values( index ) ) {
11973  newValues = this.values();
11974  newValues[ index ] = newVal;
11975  // A slide can be canceled by returning false from the slide callback
11976  allowed = this._trigger( "slide", event, {
11977  handle: this.handles[ index ],
11978  value: newVal,
11979  values: newValues
11980  } );
11981  otherVal = this.values( index ? 0 : 1 );
11982  if ( allowed !== false ) {
11983  this.values( index, newVal );
11984  }
11985  }
11986  } else {
11987  if ( newVal !== this.value() ) {
11988  // A slide can be canceled by returning false from the slide callback
11989  allowed = this._trigger( "slide", event, {
11990  handle: this.handles[ index ],
11991  value: newVal
11992  } );
11993  if ( allowed !== false ) {
11994  this.value( newVal );
11995  }
11996  }
11997  }
11998  },
11999 
12000  _stop: function( event, index ) {
12001  var uiHash = {
12002  handle: this.handles[ index ],
12003  value: this.value()
12004  };
12005  if ( this.options.values && this.options.values.length ) {
12006  uiHash.value = this.values( index );
12007  uiHash.values = this.values();
12008  }
12009 
12010  this._trigger( "stop", event, uiHash );
12011  },
12012 
12013  _change: function( event, index ) {
12014  if ( !this._keySliding && !this._mouseSliding ) {
12015  var uiHash = {
12016  handle: this.handles[ index ],
12017  value: this.value()
12018  };
12019  if ( this.options.values && this.options.values.length ) {
12020  uiHash.value = this.values( index );
12021  uiHash.values = this.values();
12022  }
12023 
12024  //store the last changed value index for reference when handles overlap
12025  this._lastChangedValue = index;
12026 
12027  this._trigger( "change", event, uiHash );
12028  }
12029  },
12030 
12031  value: function( newValue ) {
12032  if ( arguments.length ) {
12033  this.options.value = this._trimAlignValue( newValue );
12034  this._refreshValue();
12035  this._change( null, 0 );
12036  return;
12037  }
12038 
12039  return this._value();
12040  },
12041 
12042  values: function( index, newValue ) {
12043  var vals,
12044  newValues,
12045  i;
12046 
12047  if ( arguments.length > 1 ) {
12048  this.options.values[ index ] = this._trimAlignValue( newValue );
12049  this._refreshValue();
12050  this._change( null, index );
12051  return;
12052  }
12053 
12054  if ( arguments.length ) {
12055  if ( $.isArray( arguments[ 0 ] ) ) {
12056  vals = this.options.values;
12057  newValues = arguments[ 0 ];
12058  for ( i = 0; i < vals.length; i += 1 ) {
12059  vals[ i ] = this._trimAlignValue( newValues[ i ] );
12060  this._change( null, i );
12061  }
12062  this._refreshValue();
12063  } else {
12064  if ( this.options.values && this.options.values.length ) {
12065  return this._values( index );
12066  } else {
12067  return this.value();
12068  }
12069  }
12070  } else {
12071  return this._values();
12072  }
12073  },
12074 
12075  _setOption: function( key, value ) {
12076  var i,
12077  valsLength = 0;
12078 
12079  if ( key === "range" && this.options.range === true ) {
12080  if ( value === "min" ) {
12081  this.options.value = this._values( 0 );
12082  this.options.values = null;
12083  } else if ( value === "max" ) {
12084  this.options.value = this._values( this.options.values.length - 1 );
12085  this.options.values = null;
12086  }
12087  }
12088 
12089  if ( $.isArray( this.options.values ) ) {
12090  valsLength = this.options.values.length;
12091  }
12092 
12093  if ( key === "disabled" ) {
12094  this.element.toggleClass( "ui-state-disabled", !!value );
12095  }
12096 
12097  this._super( key, value );
12098 
12099  switch ( key ) {
12100  case "orientation":
12101  this._detectOrientation();
12102  this.element
12103  .removeClass( "ui-slider-horizontal ui-slider-vertical" )
12104  .addClass( "ui-slider-" + this.orientation );
12105  this._refreshValue();
12106 
12107  // Reset positioning from previous orientation
12108  this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
12109  break;
12110  case "value":
12111  this._animateOff = true;
12112  this._refreshValue();
12113  this._change( null, 0 );
12114  this._animateOff = false;
12115  break;
12116  case "values":
12117  this._animateOff = true;
12118  this._refreshValue();
12119  for ( i = 0; i < valsLength; i += 1 ) {
12120  this._change( null, i );
12121  }
12122  this._animateOff = false;
12123  break;
12124  case "step":
12125  case "min":
12126  case "max":
12127  this._animateOff = true;
12128  this._calculateNewMax();
12129  this._refreshValue();
12130  this._animateOff = false;
12131  break;
12132  case "range":
12133  this._animateOff = true;
12134  this._refresh();
12135  this._animateOff = false;
12136  break;
12137  }
12138  },
12139 
12140  //internal value getter
12141  // _value() returns value trimmed by min and max, aligned by step
12142  _value: function() {
12143  var val = this.options.value;
12144  val = this._trimAlignValue( val );
12145 
12146  return val;
12147  },
12148 
12149  //internal values getter
12150  // _values() returns array of values trimmed by min and max, aligned by step
12151  // _values( index ) returns single value trimmed by min and max, aligned by step
12152  _values: function( index ) {
12153  var val,
12154  vals,
12155  i;
12156 
12157  if ( arguments.length ) {
12158  val = this.options.values[ index ];
12159  val = this._trimAlignValue( val );
12160 
12161  return val;
12162  } else if ( this.options.values && this.options.values.length ) {
12163  // .slice() creates a copy of the array
12164  // this copy gets trimmed by min and max and then returned
12165  vals = this.options.values.slice();
12166  for ( i = 0; i < vals.length; i += 1) {
12167  vals[ i ] = this._trimAlignValue( vals[ i ] );
12168  }
12169 
12170  return vals;
12171  } else {
12172  return [];
12173  }
12174  },
12175 
12176  // returns the step-aligned value that val is closest to, between (inclusive) min and max
12177  _trimAlignValue: function( val ) {
12178  if ( val <= this._valueMin() ) {
12179  return this._valueMin();
12180  }
12181  if ( val >= this._valueMax() ) {
12182  return this._valueMax();
12183  }
12184  var step = ( this.options.step > 0 ) ? this.options.step : 1,
12185  valModStep = (val - this._valueMin()) % step,
12186  alignValue = val - valModStep;
12187 
12188  if ( Math.abs(valModStep) * 2 >= step ) {
12189  alignValue += ( valModStep > 0 ) ? step : ( -step );
12190  }
12191 
12192  // Since JavaScript has problems with large floats, round
12193  // the final value to 5 digits after the decimal point (see #4124)
12194  return parseFloat( alignValue.toFixed(5) );
12195  },
12196 
12197  _calculateNewMax: function() {
12198  var remainder = ( this.options.max - this._valueMin() ) % this.options.step;
12199  this.max = this.options.max - remainder;
12200  },
12201 
12202  _valueMin: function() {
12203  return this.options.min;
12204  },
12205 
12206  _valueMax: function() {
12207  return this.max;
12208  },
12209 
12210  _refreshValue: function() {
12211  var lastValPercent, valPercent, value, valueMin, valueMax,
12212  oRange = this.options.range,
12213  o = this.options,
12214  that = this,
12215  animate = ( !this._animateOff ) ? o.animate : false,
12216  _set = {};
12217 
12218  if ( this.options.values && this.options.values.length ) {
12219  this.handles.each(function( i ) {
12220  valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
12221  _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
12222  $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
12223  if ( that.options.range === true ) {
12224  if ( that.orientation === "horizontal" ) {
12225  if ( i === 0 ) {
12226  that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
12227  }
12228  if ( i === 1 ) {
12229  that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
12230  }
12231  } else {
12232  if ( i === 0 ) {
12233  that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
12234  }
12235  if ( i === 1 ) {
12236  that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
12237  }
12238  }
12239  }
12240  lastValPercent = valPercent;
12241  });
12242  } else {
12243  value = this.value();
12244  valueMin = this._valueMin();
12245  valueMax = this._valueMax();
12246  valPercent = ( valueMax !== valueMin ) ?
12247  ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
12248  0;
12249  _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
12250  this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
12251 
12252  if ( oRange === "min" && this.orientation === "horizontal" ) {
12253  this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
12254  }
12255  if ( oRange === "max" && this.orientation === "horizontal" ) {
12256  this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
12257  }
12258  if ( oRange === "min" && this.orientation === "vertical" ) {
12259  this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
12260  }
12261  if ( oRange === "max" && this.orientation === "vertical" ) {
12262  this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
12263  }
12264  }
12265  },
12266 
12267  _handleEvents: {
12268  keydown: function( event ) {
12269  var allowed, curVal, newVal, step,
12270  index = $( event.target ).data( "ui-slider-handle-index" );
12271 
12272  switch ( event.keyCode ) {
12273  case $.ui.keyCode.HOME:
12274  case $.ui.keyCode.END:
12275  case $.ui.keyCode.PAGE_UP:
12276  case $.ui.keyCode.PAGE_DOWN:
12277  case $.ui.keyCode.UP:
12278  case $.ui.keyCode.RIGHT:
12279  case $.ui.keyCode.DOWN:
12280  case $.ui.keyCode.LEFT:
12281  event.preventDefault();
12282  if ( !this._keySliding ) {
12283  this._keySliding = true;
12284  $( event.target ).addClass( "ui-state-active" );
12285  allowed = this._start( event, index );
12286  if ( allowed === false ) {
12287  return;
12288  }
12289  }
12290  break;
12291  }
12292 
12293  step = this.options.step;
12294  if ( this.options.values && this.options.values.length ) {
12295  curVal = newVal = this.values( index );
12296  } else {
12297  curVal = newVal = this.value();
12298  }
12299 
12300  switch ( event.keyCode ) {
12301  case $.ui.keyCode.HOME:
12302  newVal = this._valueMin();
12303  break;
12304  case $.ui.keyCode.END:
12305  newVal = this._valueMax();
12306  break;
12307  case $.ui.keyCode.PAGE_UP:
12308  newVal = this._trimAlignValue(
12309  curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
12310  );
12311  break;
12312  case $.ui.keyCode.PAGE_DOWN:
12313  newVal = this._trimAlignValue(
12314  curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );
12315  break;
12316  case $.ui.keyCode.UP:
12317  case $.ui.keyCode.RIGHT:
12318  if ( curVal === this._valueMax() ) {
12319  return;
12320  }
12321  newVal = this._trimAlignValue( curVal + step );
12322  break;
12323  case $.ui.keyCode.DOWN:
12324  case $.ui.keyCode.LEFT:
12325  if ( curVal === this._valueMin() ) {
12326  return;
12327  }
12328  newVal = this._trimAlignValue( curVal - step );
12329  break;
12330  }
12331 
12332  this._slide( event, index, newVal );
12333  },
12334  keyup: function( event ) {
12335  var index = $( event.target ).data( "ui-slider-handle-index" );
12336 
12337  if ( this._keySliding ) {
12338  this._keySliding = false;
12339  this._stop( event, index );
12340  this._change( event, index );
12341  $( event.target ).removeClass( "ui-state-active" );
12342  }
12343  }
12344  }
12345 });
12346 
12347 
12348 /*!
12349  * jQuery UI Spinner 1.11.2
12350  * http://jqueryui.com
12351  *
12352  * Copyright 2014 jQuery Foundation and other contributors
12353  * Released under the MIT license.
12354  * http://jquery.org/license
12355  *
12356  * http://api.jqueryui.com/spinner/
12357  */
12358 
12359 
12360 function spinner_modifier( fn ) {
12361  return function() {
12362  var previous = this.element.val();
12363  fn.apply( this, arguments );
12364  this._refresh();
12365  if ( previous !== this.element.val() ) {
12366  this._trigger( "change" );
12367  }
12368  };
12369 }
12370 
12371 var spinner = $.widget( "ui.spinner", {
12372  version: "1.11.2",
12373  defaultElement: "<input>",
12374  widgetEventPrefix: "spin",
12375  options: {
12376  culture: null,
12377  icons: {
12378  down: "ui-icon-triangle-1-s",
12379  up: "ui-icon-triangle-1-n"
12380  },
12381  incremental: true,
12382  max: null,
12383  min: null,
12384  numberFormat: null,
12385  page: 10,
12386  step: 1,
12387 
12388  change: null,
12389  spin: null,
12390  start: null,
12391  stop: null
12392  },
12393 
12394  _create: function() {
12395  // handle string values that need to be parsed
12396  this._setOption( "max", this.options.max );
12397  this._setOption( "min", this.options.min );
12398  this._setOption( "step", this.options.step );
12399 
12400  // Only format if there is a value, prevents the field from being marked
12401  // as invalid in Firefox, see #9573.
12402  if ( this.value() !== "" ) {
12403  // Format the value, but don't constrain.
12404  this._value( this.element.val(), true );
12405  }
12406 
12407  this._draw();
12408  this._on( this._events );
12409  this._refresh();
12410 
12411  // turning off autocomplete prevents the browser from remembering the
12412  // value when navigating through history, so we re-enable autocomplete
12413  // if the page is unloaded before the widget is destroyed. #7790
12414  this._on( this.window, {
12415  beforeunload: function() {
12416  this.element.removeAttr( "autocomplete" );
12417  }
12418  });
12419  },
12420 
12421  _getCreateOptions: function() {
12422  var options = {},
12423  element = this.element;
12424 
12425  $.each( [ "min", "max", "step" ], function( i, option ) {
12426  var value = element.attr( option );
12427  if ( value !== undefined && value.length ) {
12428  options[ option ] = value;
12429  }
12430  });
12431 
12432  return options;
12433  },
12434 
12435  _events: {
12436  keydown: function( event ) {
12437  if ( this._start( event ) && this._keydown( event ) ) {
12438  event.preventDefault();
12439  }
12440  },
12441  keyup: "_stop",
12442  focus: function() {
12443  this.previous = this.element.val();
12444  },
12445  blur: function( event ) {
12446  if ( this.cancelBlur ) {
12447  delete this.cancelBlur;
12448  return;
12449  }
12450 
12451  this._stop();
12452  this._refresh();
12453  if ( this.previous !== this.element.val() ) {
12454  this._trigger( "change", event );
12455  }
12456  },
12457  mousewheel: function( event, delta ) {
12458  if ( !delta ) {
12459  return;
12460  }
12461  if ( !this.spinning && !this._start( event ) ) {
12462  return false;
12463  }
12464 
12465  this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
12466  clearTimeout( this.mousewheelTimer );
12467  this.mousewheelTimer = this._delay(function() {
12468  if ( this.spinning ) {
12469  this._stop( event );
12470  }
12471  }, 100 );
12472  event.preventDefault();
12473  },
12474  "mousedown .ui-spinner-button": function( event ) {
12475  var previous;
12476 
12477  // We never want the buttons to have focus; whenever the user is
12478  // interacting with the spinner, the focus should be on the input.
12479  // If the input is focused then this.previous is properly set from
12480  // when the input first received focus. If the input is not focused
12481  // then we need to set this.previous based on the value before spinning.
12482  previous = this.element[0] === this.document[0].activeElement ?
12483  this.previous : this.element.val();
12484  function checkFocus() {
12485  var isActive = this.element[0] === this.document[0].activeElement;
12486  if ( !isActive ) {
12487  this.element.focus();
12488  this.previous = previous;
12489  // support: IE
12490  // IE sets focus asynchronously, so we need to check if focus
12491  // moved off of the input because the user clicked on the button.
12492  this._delay(function() {
12493  this.previous = previous;
12494  });
12495  }
12496  }
12497 
12498  // ensure focus is on (or stays on) the text field
12499  event.preventDefault();
12500  checkFocus.call( this );
12501 
12502  // support: IE
12503  // IE doesn't prevent moving focus even with event.preventDefault()
12504  // so we set a flag to know when we should ignore the blur event
12505  // and check (again) if focus moved off of the input.
12506  this.cancelBlur = true;
12507  this._delay(function() {
12508  delete this.cancelBlur;
12509  checkFocus.call( this );
12510  });
12511 
12512  if ( this._start( event ) === false ) {
12513  return;
12514  }
12515 
12516  this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
12517  },
12518  "mouseup .ui-spinner-button": "_stop",
12519  "mouseenter .ui-spinner-button": function( event ) {
12520  // button will add ui-state-active if mouse was down while mouseleave and kept down
12521  if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
12522  return;
12523  }
12524 
12525  if ( this._start( event ) === false ) {
12526  return false;
12527  }
12528  this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
12529  },
12530  // TODO: do we really want to consider this a stop?
12531  // shouldn't we just stop the repeater and wait until mouseup before
12532  // we trigger the stop event?
12533  "mouseleave .ui-spinner-button": "_stop"
12534  },
12535 
12536  _draw: function() {
12537  var uiSpinner = this.uiSpinner = this.element
12538  .addClass( "ui-spinner-input" )
12539  .attr( "autocomplete", "off" )
12540  .wrap( this._uiSpinnerHtml() )
12541  .parent()
12542  // add buttons
12543  .append( this._buttonHtml() );
12544 
12545  this.element.attr( "role", "spinbutton" );
12546 
12547  // button bindings
12548  this.buttons = uiSpinner.find( ".ui-spinner-button" )
12549  .attr( "tabIndex", -1 )
12550  .button()
12551  .removeClass( "ui-corner-all" );
12552 
12553  // IE 6 doesn't understand height: 50% for the buttons
12554  // unless the wrapper has an explicit height
12555  if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
12556  uiSpinner.height() > 0 ) {
12557  uiSpinner.height( uiSpinner.height() );
12558  }
12559 
12560  // disable spinner if element was already disabled
12561  if ( this.options.disabled ) {
12562  this.disable();
12563  }
12564  },
12565 
12566  _keydown: function( event ) {
12567  var options = this.options,
12568  keyCode = $.ui.keyCode;
12569 
12570  switch ( event.keyCode ) {
12571  case keyCode.UP:
12572  this._repeat( null, 1, event );
12573  return true;
12574  case keyCode.DOWN:
12575  this._repeat( null, -1, event );
12576  return true;
12577  case keyCode.PAGE_UP:
12578  this._repeat( null, options.page, event );
12579  return true;
12580  case keyCode.PAGE_DOWN:
12581  this._repeat( null, -options.page, event );
12582  return true;
12583  }
12584 
12585  return false;
12586  },
12587 
12588  _uiSpinnerHtml: function() {
12589  return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
12590  },
12591 
12592  _buttonHtml: function() {
12593  return "" +
12594  "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
12595  "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
12596  "</a>" +
12597  "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
12598  "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
12599  "</a>";
12600  },
12601 
12602  _start: function( event ) {
12603  if ( !this.spinning && this._trigger( "start", event ) === false ) {
12604  return false;
12605  }
12606 
12607  if ( !this.counter ) {
12608  this.counter = 1;
12609  }
12610  this.spinning = true;
12611  return true;
12612  },
12613 
12614  _repeat: function( i, steps, event ) {
12615  i = i || 500;
12616 
12617  clearTimeout( this.timer );
12618  this.timer = this._delay(function() {
12619  this._repeat( 40, steps, event );
12620  }, i );
12621 
12622  this._spin( steps * this.options.step, event );
12623  },
12624 
12625  _spin: function( step, event ) {
12626  var value = this.value() || 0;
12627 
12628  if ( !this.counter ) {
12629  this.counter = 1;
12630  }
12631 
12632  value = this._adjustValue( value + step * this._increment( this.counter ) );
12633 
12634  if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
12635  this._value( value );
12636  this.counter++;
12637  }
12638  },
12639 
12640  _increment: function( i ) {
12641  var incremental = this.options.incremental;
12642 
12643  if ( incremental ) {
12644  return $.isFunction( incremental ) ?
12645  incremental( i ) :
12646  Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
12647  }
12648 
12649  return 1;
12650  },
12651 
12652  _precision: function() {
12653  var precision = this._precisionOf( this.options.step );
12654  if ( this.options.min !== null ) {
12655  precision = Math.max( precision, this._precisionOf( this.options.min ) );
12656  }
12657  return precision;
12658  },
12659 
12660  _precisionOf: function( num ) {
12661  var str = num.toString(),
12662  decimal = str.indexOf( "." );
12663  return decimal === -1 ? 0 : str.length - decimal - 1;
12664  },
12665 
12666  _adjustValue: function( value ) {
12667  var base, aboveMin,
12668  options = this.options;
12669 
12670  // make sure we're at a valid step
12671  // - find out where we are relative to the base (min or 0)
12672  base = options.min !== null ? options.min : 0;
12673  aboveMin = value - base;
12674  // - round to the nearest step
12675  aboveMin = Math.round(aboveMin / options.step) * options.step;
12676  // - rounding is based on 0, so adjust back to our base
12677  value = base + aboveMin;
12678 
12679  // fix precision from bad JS floating point math
12680  value = parseFloat( value.toFixed( this._precision() ) );
12681 
12682  // clamp the value
12683  if ( options.max !== null && value > options.max) {
12684  return options.max;
12685  }
12686  if ( options.min !== null && value < options.min ) {
12687  return options.min;
12688  }
12689 
12690  return value;
12691  },
12692 
12693  _stop: function( event ) {
12694  if ( !this.spinning ) {
12695  return;
12696  }
12697 
12698  clearTimeout( this.timer );
12699  clearTimeout( this.mousewheelTimer );
12700  this.counter = 0;
12701  this.spinning = false;
12702  this._trigger( "stop", event );
12703  },
12704 
12705  _setOption: function( key, value ) {
12706  if ( key === "culture" || key === "numberFormat" ) {
12707  var prevValue = this._parse( this.element.val() );
12708  this.options[ key ] = value;
12709  this.element.val( this._format( prevValue ) );
12710  return;
12711  }
12712 
12713  if ( key === "max" || key === "min" || key === "step" ) {
12714  if ( typeof value === "string" ) {
12715  value = this._parse( value );
12716  }
12717  }
12718  if ( key === "icons" ) {
12719  this.buttons.first().find( ".ui-icon" )
12720  .removeClass( this.options.icons.up )
12721  .addClass( value.up );
12722  this.buttons.last().find( ".ui-icon" )
12723  .removeClass( this.options.icons.down )
12724  .addClass( value.down );
12725  }
12726 
12727  this._super( key, value );
12728 
12729  if ( key === "disabled" ) {
12730  this.widget().toggleClass( "ui-state-disabled", !!value );
12731  this.element.prop( "disabled", !!value );
12732  this.buttons.button( value ? "disable" : "enable" );
12733  }
12734  },
12735 
12736  _setOptions: spinner_modifier(function( options ) {
12737  this._super( options );
12738  }),
12739 
12740  _parse: function( val ) {
12741  if ( typeof val === "string" && val !== "" ) {
12742  val = window.Globalize && this.options.numberFormat ?
12743  Globalize.parseFloat( val, 10, this.options.culture ) : +val;
12744  }
12745  return val === "" || isNaN( val ) ? null : val;
12746  },
12747 
12748  _format: function( value ) {
12749  if ( value === "" ) {
12750  return "";
12751  }
12752  return window.Globalize && this.options.numberFormat ?
12753  Globalize.format( value, this.options.numberFormat, this.options.culture ) :
12754  value;
12755  },
12756 
12757  _refresh: function() {
12758  this.element.attr({
12759  "aria-valuemin": this.options.min,
12760  "aria-valuemax": this.options.max,
12761  // TODO: what should we do with values that can't be parsed?
12762  "aria-valuenow": this._parse( this.element.val() )
12763  });
12764  },
12765 
12766  isValid: function() {
12767  var value = this.value();
12768 
12769  // null is invalid
12770  if ( value === null ) {
12771  return false;
12772  }
12773 
12774  // if value gets adjusted, it's invalid
12775  return value === this._adjustValue( value );
12776  },
12777 
12778  // update the value without triggering change
12779  _value: function( value, allowAny ) {
12780  var parsed;
12781  if ( value !== "" ) {
12782  parsed = this._parse( value );
12783  if ( parsed !== null ) {
12784  if ( !allowAny ) {
12785  parsed = this._adjustValue( parsed );
12786  }
12787  value = this._format( parsed );
12788  }
12789  }
12790  this.element.val( value );
12791  this._refresh();
12792  },
12793 
12794  _destroy: function() {
12795  this.element
12796  .removeClass( "ui-spinner-input" )
12797  .prop( "disabled", false )
12798  .removeAttr( "autocomplete" )
12799  .removeAttr( "role" )
12800  .removeAttr( "aria-valuemin" )
12801  .removeAttr( "aria-valuemax" )
12802  .removeAttr( "aria-valuenow" );
12803  this.uiSpinner.replaceWith( this.element );
12804  },
12805 
12806  stepUp: spinner_modifier(function( steps ) {
12807  this._stepUp( steps );
12808  }),
12809  _stepUp: function( steps ) {
12810  if ( this._start() ) {
12811  this._spin( (steps || 1) * this.options.step );
12812  this._stop();
12813  }
12814  },
12815 
12816  stepDown: spinner_modifier(function( steps ) {
12817  this._stepDown( steps );
12818  }),
12819  _stepDown: function( steps ) {
12820  if ( this._start() ) {
12821  this._spin( (steps || 1) * -this.options.step );
12822  this._stop();
12823  }
12824  },
12825 
12826  pageUp: spinner_modifier(function( pages ) {
12827  this._stepUp( (pages || 1) * this.options.page );
12828  }),
12829 
12830  pageDown: spinner_modifier(function( pages ) {
12831  this._stepDown( (pages || 1) * this.options.page );
12832  }),
12833 
12834  value: function( newVal ) {
12835  if ( !arguments.length ) {
12836  return this._parse( this.element.val() );
12837  }
12838  spinner_modifier( this._value ).call( this, newVal );
12839  },
12840 
12841  widget: function() {
12842  return this.uiSpinner;
12843  }
12844 });
12845 
12846 
12847 /*!
12848  * jQuery UI Tabs 1.11.2
12849  * http://jqueryui.com
12850  *
12851  * Copyright 2014 jQuery Foundation and other contributors
12852  * Released under the MIT license.
12853  * http://jquery.org/license
12854  *
12855  * http://api.jqueryui.com/tabs/
12856  */
12857 
12858 
12859 var tabs = $.widget( "ui.tabs", {
12860  version: "1.11.2",
12861  delay: 300,
12862  options: {
12863  active: null,
12864  collapsible: false,
12865  event: "click",
12866  heightStyle: "content",
12867  hide: null,
12868  show: null,
12869 
12870  // callbacks
12871  activate: null,
12872  beforeActivate: null,
12873  beforeLoad: null,
12874  load: null
12875  },
12876 
12877  _isLocal: (function() {
12878  var rhash = /#.*$/;
12879 
12880  return function( anchor ) {
12881  var anchorUrl, locationUrl;
12882 
12883  // support: IE7
12884  // IE7 doesn't normalize the href property when set via script (#9317)
12885  anchor = anchor.cloneNode( false );
12886 
12887  anchorUrl = anchor.href.replace( rhash, "" );
12888  locationUrl = location.href.replace( rhash, "" );
12889 
12890  // decoding may throw an error if the URL isn't UTF-8 (#9518)
12891  try {
12892  anchorUrl = decodeURIComponent( anchorUrl );
12893  } catch ( error ) {}
12894  try {
12895  locationUrl = decodeURIComponent( locationUrl );
12896  } catch ( error ) {}
12897 
12898  return anchor.hash.length > 1 && anchorUrl === locationUrl;
12899  };
12900  })(),
12901 
12902  _create: function() {
12903  var that = this,
12904  options = this.options;
12905 
12906  this.running = false;
12907 
12908  this.element
12909  .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
12910  .toggleClass( "ui-tabs-collapsible", options.collapsible );
12911 
12912  this._processTabs();
12913  options.active = this._initialActive();
12914 
12915  // Take disabling tabs via class attribute from HTML
12916  // into account and update option properly.
12917  if ( $.isArray( options.disabled ) ) {
12918  options.disabled = $.unique( options.disabled.concat(
12919  $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
12920  return that.tabs.index( li );
12921  })
12922  ) ).sort();
12923  }
12924 
12925  // check for length avoids error when initializing empty list
12926  if ( this.options.active !== false && this.anchors.length ) {
12927  this.active = this._findActive( options.active );
12928  } else {
12929  this.active = $();
12930  }
12931 
12932  this._refresh();
12933 
12934  if ( this.active.length ) {
12935  this.load( options.active );
12936  }
12937  },
12938 
12939  _initialActive: function() {
12940  var active = this.options.active,
12941  collapsible = this.options.collapsible,
12942  locationHash = location.hash.substring( 1 );
12943 
12944  if ( active === null ) {
12945  // check the fragment identifier in the URL
12946  if ( locationHash ) {
12947  this.tabs.each(function( i, tab ) {
12948  if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
12949  active = i;
12950  return false;
12951  }
12952  });
12953  }
12954 
12955  // check for a tab marked active via a class
12956  if ( active === null ) {
12957  active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
12958  }
12959 
12960  // no active tab, set to false
12961  if ( active === null || active === -1 ) {
12962  active = this.tabs.length ? 0 : false;
12963  }
12964  }
12965 
12966  // handle numbers: negative, out of range
12967  if ( active !== false ) {
12968  active = this.tabs.index( this.tabs.eq( active ) );
12969  if ( active === -1 ) {
12970  active = collapsible ? false : 0;
12971  }
12972  }
12973 
12974  // don't allow collapsible: false and active: false
12975  if ( !collapsible && active === false && this.anchors.length ) {
12976  active = 0;
12977  }
12978 
12979  return active;
12980  },
12981 
12982  _getCreateEventData: function() {
12983  return {
12984  tab: this.active,
12985  panel: !this.active.length ? $() : this._getPanelForTab( this.active )
12986  };
12987  },
12988 
12989  _tabKeydown: function( event ) {
12990  var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
12991  selectedIndex = this.tabs.index( focusedTab ),
12992  goingForward = true;
12993 
12994  if ( this._handlePageNav( event ) ) {
12995  return;
12996  }
12997 
12998  switch ( event.keyCode ) {
12999  case $.ui.keyCode.RIGHT:
13000  case $.ui.keyCode.DOWN:
13001  selectedIndex++;
13002  break;
13003  case $.ui.keyCode.UP:
13004  case $.ui.keyCode.LEFT:
13005  goingForward = false;
13006  selectedIndex--;
13007  break;
13008  case $.ui.keyCode.END:
13009  selectedIndex = this.anchors.length - 1;
13010  break;
13011  case $.ui.keyCode.HOME:
13012  selectedIndex = 0;
13013  break;
13014  case $.ui.keyCode.SPACE:
13015  // Activate only, no collapsing
13016  event.preventDefault();
13017  clearTimeout( this.activating );
13018  this._activate( selectedIndex );
13019  return;
13020  case $.ui.keyCode.ENTER:
13021  // Toggle (cancel delayed activation, allow collapsing)
13022  event.preventDefault();
13023  clearTimeout( this.activating );
13024  // Determine if we should collapse or activate
13025  this._activate( selectedIndex === this.options.active ? false : selectedIndex );
13026  return;
13027  default:
13028  return;
13029  }
13030 
13031  // Focus the appropriate tab, based on which key was pressed
13032  event.preventDefault();
13033  clearTimeout( this.activating );
13034  selectedIndex = this._focusNextTab( selectedIndex, goingForward );
13035 
13036  // Navigating with control key will prevent automatic activation
13037  if ( !event.ctrlKey ) {
13038  // Update aria-selected immediately so that AT think the tab is already selected.
13039  // Otherwise AT may confuse the user by stating that they need to activate the tab,
13040  // but the tab will already be activated by the time the announcement finishes.
13041  focusedTab.attr( "aria-selected", "false" );
13042  this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
13043 
13044  this.activating = this._delay(function() {
13045  this.option( "active", selectedIndex );
13046  }, this.delay );
13047  }
13048  },
13049 
13050  _panelKeydown: function( event ) {
13051  if ( this._handlePageNav( event ) ) {
13052  return;
13053  }
13054 
13055  // Ctrl+up moves focus to the current tab
13056  if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
13057  event.preventDefault();
13058  this.active.focus();
13059  }
13060  },
13061 
13062  // Alt+page up/down moves focus to the previous/next tab (and activates)
13063  _handlePageNav: function( event ) {
13064  if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
13065  this._activate( this._focusNextTab( this.options.active - 1, false ) );
13066  return true;
13067  }
13068  if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
13069  this._activate( this._focusNextTab( this.options.active + 1, true ) );
13070  return true;
13071  }
13072  },
13073 
13074  _findNextTab: function( index, goingForward ) {
13075  var lastTabIndex = this.tabs.length - 1;
13076 
13077  function constrain() {
13078  if ( index > lastTabIndex ) {
13079  index = 0;
13080  }
13081  if ( index < 0 ) {
13082  index = lastTabIndex;
13083  }
13084  return index;
13085  }
13086 
13087  while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
13088  index = goingForward ? index + 1 : index - 1;
13089  }
13090 
13091  return index;
13092  },
13093 
13094  _focusNextTab: function( index, goingForward ) {
13095  index = this._findNextTab( index, goingForward );
13096  this.tabs.eq( index ).focus();
13097  return index;
13098  },
13099 
13100  _setOption: function( key, value ) {
13101  if ( key === "active" ) {
13102  // _activate() will handle invalid values and update this.options
13103  this._activate( value );
13104  return;
13105  }
13106 
13107  if ( key === "disabled" ) {
13108  // don't use the widget factory's disabled handling
13109  this._setupDisabled( value );
13110  return;
13111  }
13112 
13113  this._super( key, value);
13114 
13115  if ( key === "collapsible" ) {
13116  this.element.toggleClass( "ui-tabs-collapsible", value );
13117  // Setting collapsible: false while collapsed; open first panel
13118  if ( !value && this.options.active === false ) {
13119  this._activate( 0 );
13120  }
13121  }
13122 
13123  if ( key === "event" ) {
13124  this._setupEvents( value );
13125  }
13126 
13127  if ( key === "heightStyle" ) {
13128  this._setupHeightStyle( value );
13129  }
13130  },
13131 
13132  _sanitizeSelector: function( hash ) {
13133  return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
13134  },
13135 
13136  refresh: function() {
13137  var options = this.options,
13138  lis = this.tablist.children( ":has(a[href])" );
13139 
13140  // get disabled tabs from class attribute from HTML
13141  // this will get converted to a boolean if needed in _refresh()
13142  options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
13143  return lis.index( tab );
13144  });
13145 
13146  this._processTabs();
13147 
13148  // was collapsed or no tabs
13149  if ( options.active === false || !this.anchors.length ) {
13150  options.active = false;
13151  this.active = $();
13152  // was active, but active tab is gone
13153  } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
13154  // all remaining tabs are disabled
13155  if ( this.tabs.length === options.disabled.length ) {
13156  options.active = false;
13157  this.active = $();
13158  // activate previous tab
13159  } else {
13160  this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
13161  }
13162  // was active, active tab still exists
13163  } else {
13164  // make sure active index is correct
13165  options.active = this.tabs.index( this.active );
13166  }
13167 
13168  this._refresh();
13169  },
13170 
13171  _refresh: function() {
13172  this._setupDisabled( this.options.disabled );
13173  this._setupEvents( this.options.event );
13174  this._setupHeightStyle( this.options.heightStyle );
13175 
13176  this.tabs.not( this.active ).attr({
13177  "aria-selected": "false",
13178  "aria-expanded": "false",
13179  tabIndex: -1
13180  });
13181  this.panels.not( this._getPanelForTab( this.active ) )
13182  .hide()
13183  .attr({
13184  "aria-hidden": "true"
13185  });
13186 
13187  // Make sure one tab is in the tab order
13188  if ( !this.active.length ) {
13189  this.tabs.eq( 0 ).attr( "tabIndex", 0 );
13190  } else {
13191  this.active
13192  .addClass( "ui-tabs-active ui-state-active" )
13193  .attr({
13194  "aria-selected": "true",
13195  "aria-expanded": "true",
13196  tabIndex: 0
13197  });
13198  this._getPanelForTab( this.active )
13199  .show()
13200  .attr({
13201  "aria-hidden": "false"
13202  });
13203  }
13204  },
13205 
13206  _processTabs: function() {
13207  var that = this,
13208  prevTabs = this.tabs,
13209  prevAnchors = this.anchors,
13210  prevPanels = this.panels;
13211 
13212  this.tablist = this._getList()
13213  .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
13214  .attr( "role", "tablist" )
13215 
13216  // Prevent users from focusing disabled tabs via click
13217  .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
13218  if ( $( this ).is( ".ui-state-disabled" ) ) {
13219  event.preventDefault();
13220  }
13221  })
13222 
13223  // support: IE <9
13224  // Preventing the default action in mousedown doesn't prevent IE
13225  // from focusing the element, so if the anchor gets focused, blur.
13226  // We don't have to worry about focusing the previously focused
13227  // element since clicking on a non-focusable element should focus
13228  // the body anyway.
13229  .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
13230  if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
13231  this.blur();
13232  }
13233  });
13234 
13235  this.tabs = this.tablist.find( "> li:has(a[href])" )
13236  .addClass( "ui-state-default ui-corner-top" )
13237  .attr({
13238  role: "tab",
13239  tabIndex: -1
13240  });
13241 
13242  this.anchors = this.tabs.map(function() {
13243  return $( "a", this )[ 0 ];
13244  })
13245  .addClass( "ui-tabs-anchor" )
13246  .attr({
13247  role: "presentation",
13248  tabIndex: -1
13249  });
13250 
13251  this.panels = $();
13252 
13253  this.anchors.each(function( i, anchor ) {
13254  var selector, panel, panelId,
13255  anchorId = $( anchor ).uniqueId().attr( "id" ),
13256  tab = $( anchor ).closest( "li" ),
13257  originalAriaControls = tab.attr( "aria-controls" );
13258 
13259  // inline tab
13260  if ( that._isLocal( anchor ) ) {
13261  selector = anchor.hash;
13262  panelId = selector.substring( 1 );
13263  panel = that.element.find( that._sanitizeSelector( selector ) );
13264  // remote tab
13265  } else {
13266  // If the tab doesn't already have aria-controls,
13267  // generate an id by using a throw-away element
13268  panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
13269  selector = "#" + panelId;
13270  panel = that.element.find( selector );
13271  if ( !panel.length ) {
13272  panel = that._createPanel( panelId );
13273  panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
13274  }
13275  panel.attr( "aria-live", "polite" );
13276  }
13277 
13278  if ( panel.length) {
13279  that.panels = that.panels.add( panel );
13280  }
13281  if ( originalAriaControls ) {
13282  tab.data( "ui-tabs-aria-controls", originalAriaControls );
13283  }
13284  tab.attr({
13285  "aria-controls": panelId,
13286  "aria-labelledby": anchorId
13287  });
13288  panel.attr( "aria-labelledby", anchorId );
13289  });
13290 
13291  this.panels
13292  .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
13293  .attr( "role", "tabpanel" );
13294 
13295  // Avoid memory leaks (#10056)
13296  if ( prevTabs ) {
13297  this._off( prevTabs.not( this.tabs ) );
13298  this._off( prevAnchors.not( this.anchors ) );
13299  this._off( prevPanels.not( this.panels ) );
13300  }
13301  },
13302 
13303  // allow overriding how to find the list for rare usage scenarios (#7715)
13304  _getList: function() {
13305  return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
13306  },
13307 
13308  _createPanel: function( id ) {
13309  return $( "<div>" )
13310  .attr( "id", id )
13311  .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
13312  .data( "ui-tabs-destroy", true );
13313  },
13314 
13315  _setupDisabled: function( disabled ) {
13316  if ( $.isArray( disabled ) ) {
13317  if ( !disabled.length ) {
13318  disabled = false;
13319  } else if ( disabled.length === this.anchors.length ) {
13320  disabled = true;
13321  }
13322  }
13323 
13324  // disable tabs
13325  for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
13326  if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
13327  $( li )
13328  .addClass( "ui-state-disabled" )
13329  .attr( "aria-disabled", "true" );
13330  } else {
13331  $( li )
13332  .removeClass( "ui-state-disabled" )
13333  .removeAttr( "aria-disabled" );
13334  }
13335  }
13336 
13337  this.options.disabled = disabled;
13338  },
13339 
13340  _setupEvents: function( event ) {
13341  var events = {};
13342  if ( event ) {
13343  $.each( event.split(" "), function( index, eventName ) {
13344  events[ eventName ] = "_eventHandler";
13345  });
13346  }
13347 
13348  this._off( this.anchors.add( this.tabs ).add( this.panels ) );
13349  // Always prevent the default action, even when disabled
13350  this._on( true, this.anchors, {
13351  click: function( event ) {
13352  event.preventDefault();
13353  }
13354  });
13355  this._on( this.anchors, events );
13356  this._on( this.tabs, { keydown: "_tabKeydown" } );
13357  this._on( this.panels, { keydown: "_panelKeydown" } );
13358 
13359  this._focusable( this.tabs );
13360  this._hoverable( this.tabs );
13361  },
13362 
13363  _setupHeightStyle: function( heightStyle ) {
13364  var maxHeight,
13365  parent = this.element.parent();
13366 
13367  if ( heightStyle === "fill" ) {
13368  maxHeight = parent.height();
13369  maxHeight -= this.element.outerHeight() - this.element.height();
13370 
13371  this.element.siblings( ":visible" ).each(function() {
13372  var elem = $( this ),
13373  position = elem.css( "position" );
13374 
13375  if ( position === "absolute" || position === "fixed" ) {
13376  return;
13377  }
13378  maxHeight -= elem.outerHeight( true );
13379  });
13380 
13381  this.element.children().not( this.panels ).each(function() {
13382  maxHeight -= $( this ).outerHeight( true );
13383  });
13384 
13385  this.panels.each(function() {
13386  $( this ).height( Math.max( 0, maxHeight -
13387  $( this ).innerHeight() + $( this ).height() ) );
13388  })
13389  .css( "overflow", "auto" );
13390  } else if ( heightStyle === "auto" ) {
13391  maxHeight = 0;
13392  this.panels.each(function() {
13393  maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
13394  }).height( maxHeight );
13395  }
13396  },
13397 
13398  _eventHandler: function( event ) {
13399  var options = this.options,
13400  active = this.active,
13401  anchor = $( event.currentTarget ),
13402  tab = anchor.closest( "li" ),
13403  clickedIsActive = tab[ 0 ] === active[ 0 ],
13404  collapsing = clickedIsActive && options.collapsible,
13405  toShow = collapsing ? $() : this._getPanelForTab( tab ),
13406  toHide = !active.length ? $() : this._getPanelForTab( active ),
13407  eventData = {
13408  oldTab: active,
13409  oldPanel: toHide,
13410  newTab: collapsing ? $() : tab,
13411  newPanel: toShow
13412  };
13413 
13414  event.preventDefault();
13415 
13416  if ( tab.hasClass( "ui-state-disabled" ) ||
13417  // tab is already loading
13418  tab.hasClass( "ui-tabs-loading" ) ||
13419  // can't switch durning an animation
13420  this.running ||
13421  // click on active header, but not collapsible
13422  ( clickedIsActive && !options.collapsible ) ||
13423  // allow canceling activation
13424  ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
13425  return;
13426  }
13427 
13428  options.active = collapsing ? false : this.tabs.index( tab );
13429 
13430  this.active = clickedIsActive ? $() : tab;
13431  if ( this.xhr ) {
13432  this.xhr.abort();
13433  }
13434 
13435  if ( !toHide.length && !toShow.length ) {
13436  $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
13437  }
13438 
13439  if ( toShow.length ) {
13440  this.load( this.tabs.index( tab ), event );
13441  }
13442  this._toggle( event, eventData );
13443  },
13444 
13445  // handles show/hide for selecting tabs
13446  _toggle: function( event, eventData ) {
13447  var that = this,
13448  toShow = eventData.newPanel,
13449  toHide = eventData.oldPanel;
13450 
13451  this.running = true;
13452 
13453  function complete() {
13454  that.running = false;
13455  that._trigger( "activate", event, eventData );
13456  }
13457 
13458  function show() {
13459  eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
13460 
13461  if ( toShow.length && that.options.show ) {
13462  that._show( toShow, that.options.show, complete );
13463  } else {
13464  toShow.show();
13465  complete();
13466  }
13467  }
13468 
13469  // start out by hiding, then showing, then completing
13470  if ( toHide.length && this.options.hide ) {
13471  this._hide( toHide, this.options.hide, function() {
13472  eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
13473  show();
13474  });
13475  } else {
13476  eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
13477  toHide.hide();
13478  show();
13479  }
13480 
13481  toHide.attr( "aria-hidden", "true" );
13482  eventData.oldTab.attr({
13483  "aria-selected": "false",
13484  "aria-expanded": "false"
13485  });
13486  // If we're switching tabs, remove the old tab from the tab order.
13487  // If we're opening from collapsed state, remove the previous tab from the tab order.
13488  // If we're collapsing, then keep the collapsing tab in the tab order.
13489  if ( toShow.length && toHide.length ) {
13490  eventData.oldTab.attr( "tabIndex", -1 );
13491  } else if ( toShow.length ) {
13492  this.tabs.filter(function() {
13493  return $( this ).attr( "tabIndex" ) === 0;
13494  })
13495  .attr( "tabIndex", -1 );
13496  }
13497 
13498  toShow.attr( "aria-hidden", "false" );
13499  eventData.newTab.attr({
13500  "aria-selected": "true",
13501  "aria-expanded": "true",
13502  tabIndex: 0
13503  });
13504  },
13505 
13506  _activate: function( index ) {
13507  var anchor,
13508  active = this._findActive( index );
13509 
13510  // trying to activate the already active panel
13511  if ( active[ 0 ] === this.active[ 0 ] ) {
13512  return;
13513  }
13514 
13515  // trying to collapse, simulate a click on the current active header
13516  if ( !active.length ) {
13517  active = this.active;
13518  }
13519 
13520  anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
13521  this._eventHandler({
13522  target: anchor,
13523  currentTarget: anchor,
13524  preventDefault: $.noop
13525  });
13526  },
13527 
13528  _findActive: function( index ) {
13529  return index === false ? $() : this.tabs.eq( index );
13530  },
13531 
13532  _getIndex: function( index ) {
13533  // meta-function to give users option to provide a href string instead of a numerical index.
13534  if ( typeof index === "string" ) {
13535  index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
13536  }
13537 
13538  return index;
13539  },
13540 
13541  _destroy: function() {
13542  if ( this.xhr ) {
13543  this.xhr.abort();
13544  }
13545 
13546  this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
13547 
13548  this.tablist
13549  .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
13550  .removeAttr( "role" );
13551 
13552  this.anchors
13553  .removeClass( "ui-tabs-anchor" )
13554  .removeAttr( "role" )
13555  .removeAttr( "tabIndex" )
13556  .removeUniqueId();
13557 
13558  this.tablist.unbind( this.eventNamespace );
13559 
13560  this.tabs.add( this.panels ).each(function() {
13561  if ( $.data( this, "ui-tabs-destroy" ) ) {
13562  $( this ).remove();
13563  } else {
13564  $( this )
13565  .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
13566  "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
13567  .removeAttr( "tabIndex" )
13568  .removeAttr( "aria-live" )
13569  .removeAttr( "aria-busy" )
13570  .removeAttr( "aria-selected" )
13571  .removeAttr( "aria-labelledby" )
13572  .removeAttr( "aria-hidden" )
13573  .removeAttr( "aria-expanded" )
13574  .removeAttr( "role" );
13575  }
13576  });
13577 
13578  this.tabs.each(function() {
13579  var li = $( this ),
13580  prev = li.data( "ui-tabs-aria-controls" );
13581  if ( prev ) {
13582  li
13583  .attr( "aria-controls", prev )
13584  .removeData( "ui-tabs-aria-controls" );
13585  } else {
13586  li.removeAttr( "aria-controls" );
13587  }
13588  });
13589 
13590  this.panels.show();
13591 
13592  if ( this.options.heightStyle !== "content" ) {
13593  this.panels.css( "height", "" );
13594  }
13595  },
13596 
13597  enable: function( index ) {
13598  var disabled = this.options.disabled;
13599  if ( disabled === false ) {
13600  return;
13601  }
13602 
13603  if ( index === undefined ) {
13604  disabled = false;
13605  } else {
13606  index = this._getIndex( index );
13607  if ( $.isArray( disabled ) ) {
13608  disabled = $.map( disabled, function( num ) {
13609  return num !== index ? num : null;
13610  });
13611  } else {
13612  disabled = $.map( this.tabs, function( li, num ) {
13613  return num !== index ? num : null;
13614  });
13615  }
13616  }
13617  this._setupDisabled( disabled );
13618  },
13619 
13620  disable: function( index ) {
13621  var disabled = this.options.disabled;
13622  if ( disabled === true ) {
13623  return;
13624  }
13625 
13626  if ( index === undefined ) {
13627  disabled = true;
13628  } else {
13629  index = this._getIndex( index );
13630  if ( $.inArray( index, disabled ) !== -1 ) {
13631  return;
13632  }
13633  if ( $.isArray( disabled ) ) {
13634  disabled = $.merge( [ index ], disabled ).sort();
13635  } else {
13636  disabled = [ index ];
13637  }
13638  }
13639  this._setupDisabled( disabled );
13640  },
13641 
13642  load: function( index, event ) {
13643  index = this._getIndex( index );
13644  var that = this,
13645  tab = this.tabs.eq( index ),
13646  anchor = tab.find( ".ui-tabs-anchor" ),
13647  panel = this._getPanelForTab( tab ),
13648  eventData = {
13649  tab: tab,
13650  panel: panel
13651  };
13652 
13653  // not remote
13654  if ( this._isLocal( anchor[ 0 ] ) ) {
13655  return;
13656  }
13657 
13658  this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
13659 
13660  // support: jQuery <1.8
13661  // jQuery <1.8 returns false if the request is canceled in beforeSend,
13662  // but as of 1.8, $.ajax() always returns a jqXHR object.
13663  if ( this.xhr && this.xhr.statusText !== "canceled" ) {
13664  tab.addClass( "ui-tabs-loading" );
13665  panel.attr( "aria-busy", "true" );
13666 
13667  this.xhr
13668  .success(function( response ) {
13669  // support: jQuery <1.8
13670  // http://bugs.jquery.com/ticket/11778
13671  setTimeout(function() {
13672  panel.html( response );
13673  that._trigger( "load", event, eventData );
13674  }, 1 );
13675  })
13676  .complete(function( jqXHR, status ) {
13677  // support: jQuery <1.8
13678  // http://bugs.jquery.com/ticket/11778
13679  setTimeout(function() {
13680  if ( status === "abort" ) {
13681  that.panels.stop( false, true );
13682  }
13683 
13684  tab.removeClass( "ui-tabs-loading" );
13685  panel.removeAttr( "aria-busy" );
13686 
13687  if ( jqXHR === that.xhr ) {
13688  delete that.xhr;
13689  }
13690  }, 1 );
13691  });
13692  }
13693  },
13694 
13695  _ajaxSettings: function( anchor, event, eventData ) {
13696  var that = this;
13697  return {
13698  url: anchor.attr( "href" ),
13699  beforeSend: function( jqXHR, settings ) {
13700  return that._trigger( "beforeLoad", event,
13701  $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
13702  }
13703  };
13704  },
13705 
13706  _getPanelForTab: function( tab ) {
13707  var id = $( tab ).attr( "aria-controls" );
13708  return this.element.find( this._sanitizeSelector( "#" + id ) );
13709  }
13710 });
13711 
13712 
13713 /*!
13714  * jQuery UI Tooltip 1.11.2
13715  * http://jqueryui.com
13716  *
13717  * Copyright 2014 jQuery Foundation and other contributors
13718  * Released under the MIT license.
13719  * http://jquery.org/license
13720  *
13721  * http://api.jqueryui.com/tooltip/
13722  */
13723 
13724 
13725 var tooltip = $.widget( "ui.tooltip", {
13726  version: "1.11.2",
13727  options: {
13728  content: function() {
13729  // support: IE<9, Opera in jQuery <1.7
13730  // .text() can't accept undefined, so coerce to a string
13731  var title = $( this ).attr( "title" ) || "";
13732  // Escape title, since we're going from an attribute to raw HTML
13733  return $( "<a>" ).text( title ).html();
13734  },
13735  hide: true,
13736  // Disabled elements have inconsistent behavior across browsers (#8661)
13737  items: "[title]:not([disabled])",
13738  position: {
13739  my: "left top+15",
13740  at: "left bottom",
13741  collision: "flipfit flip"
13742  },
13743  show: true,
13744  tooltipClass: null,
13745  track: false,
13746 
13747  // callbacks
13748  close: null,
13749  open: null
13750  },
13751 
13752  _addDescribedBy: function( elem, id ) {
13753  var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
13754  describedby.push( id );
13755  elem
13756  .data( "ui-tooltip-id", id )
13757  .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
13758  },
13759 
13760  _removeDescribedBy: function( elem ) {
13761  var id = elem.data( "ui-tooltip-id" ),
13762  describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
13763  index = $.inArray( id, describedby );
13764 
13765  if ( index !== -1 ) {
13766  describedby.splice( index, 1 );
13767  }
13768 
13769  elem.removeData( "ui-tooltip-id" );
13770  describedby = $.trim( describedby.join( " " ) );
13771  if ( describedby ) {
13772  elem.attr( "aria-describedby", describedby );
13773  } else {
13774  elem.removeAttr( "aria-describedby" );
13775  }
13776  },
13777 
13778  _create: function() {
13779  this._on({
13780  mouseover: "open",
13781  focusin: "open"
13782  });
13783 
13784  // IDs of generated tooltips, needed for destroy
13785  this.tooltips = {};
13786 
13787  // IDs of parent tooltips where we removed the title attribute
13788  this.parents = {};
13789 
13790  if ( this.options.disabled ) {
13791  this._disable();
13792  }
13793 
13794  // Append the aria-live region so tooltips announce correctly
13795  this.liveRegion = $( "<div>" )
13796  .attr({
13797  role: "log",
13798  "aria-live": "assertive",
13799  "aria-relevant": "additions"
13800  })
13801  .addClass( "ui-helper-hidden-accessible" )
13802  .appendTo( this.document[ 0 ].body );
13803  },
13804 
13805  _setOption: function( key, value ) {
13806  var that = this;
13807 
13808  if ( key === "disabled" ) {
13809  this[ value ? "_disable" : "_enable" ]();
13810  this.options[ key ] = value;
13811  // disable element style changes
13812  return;
13813  }
13814 
13815  this._super( key, value );
13816 
13817  if ( key === "content" ) {
13818  $.each( this.tooltips, function( id, tooltipData ) {
13819  that._updateContent( tooltipData.element );
13820  });
13821  }
13822  },
13823 
13824  _disable: function() {
13825  var that = this;
13826 
13827  // close open tooltips
13828  $.each( this.tooltips, function( id, tooltipData ) {
13829  var event = $.Event( "blur" );
13830  event.target = event.currentTarget = tooltipData.element[ 0 ];
13831  that.close( event, true );
13832  });
13833 
13834  // remove title attributes to prevent native tooltips
13835  this.element.find( this.options.items ).addBack().each(function() {
13836  var element = $( this );
13837  if ( element.is( "[title]" ) ) {
13838  element
13839  .data( "ui-tooltip-title", element.attr( "title" ) )
13840  .removeAttr( "title" );
13841  }
13842  });
13843  },
13844 
13845  _enable: function() {
13846  // restore title attributes
13847  this.element.find( this.options.items ).addBack().each(function() {
13848  var element = $( this );
13849  if ( element.data( "ui-tooltip-title" ) ) {
13850  element.attr( "title", element.data( "ui-tooltip-title" ) );
13851  }
13852  });
13853  },
13854 
13855  open: function( event ) {
13856  var that = this,
13857  target = $( event ? event.target : this.element )
13858  // we need closest here due to mouseover bubbling,
13859  // but always pointing at the same event target
13860  .closest( this.options.items );
13861 
13862  // No element to show a tooltip for or the tooltip is already open
13863  if ( !target.length || target.data( "ui-tooltip-id" ) ) {
13864  return;
13865  }
13866 
13867  if ( target.attr( "title" ) ) {
13868  target.data( "ui-tooltip-title", target.attr( "title" ) );
13869  }
13870 
13871  target.data( "ui-tooltip-open", true );
13872 
13873  // kill parent tooltips, custom or native, for hover
13874  if ( event && event.type === "mouseover" ) {
13875  target.parents().each(function() {
13876  var parent = $( this ),
13877  blurEvent;
13878  if ( parent.data( "ui-tooltip-open" ) ) {
13879  blurEvent = $.Event( "blur" );
13880  blurEvent.target = blurEvent.currentTarget = this;
13881  that.close( blurEvent, true );
13882  }
13883  if ( parent.attr( "title" ) ) {
13884  parent.uniqueId();
13885  that.parents[ this.id ] = {
13886  element: this,
13887  title: parent.attr( "title" )
13888  };
13889  parent.attr( "title", "" );
13890  }
13891  });
13892  }
13893 
13894  this._updateContent( target, event );
13895  },
13896 
13897  _updateContent: function( target, event ) {
13898  var content,
13899  contentOption = this.options.content,
13900  that = this,
13901  eventType = event ? event.type : null;
13902 
13903  if ( typeof contentOption === "string" ) {
13904  return this._open( event, target, contentOption );
13905  }
13906 
13907  content = contentOption.call( target[0], function( response ) {
13908  // ignore async response if tooltip was closed already
13909  if ( !target.data( "ui-tooltip-open" ) ) {
13910  return;
13911  }
13912  // IE may instantly serve a cached response for ajax requests
13913  // delay this call to _open so the other call to _open runs first
13914  that._delay(function() {
13915  // jQuery creates a special event for focusin when it doesn't
13916  // exist natively. To improve performance, the native event
13917  // object is reused and the type is changed. Therefore, we can't
13918  // rely on the type being correct after the event finished
13919  // bubbling, so we set it back to the previous value. (#8740)
13920  if ( event ) {
13921  event.type = eventType;
13922  }
13923  this._open( event, target, response );
13924  });
13925  });
13926  if ( content ) {
13927  this._open( event, target, content );
13928  }
13929  },
13930 
13931  _open: function( event, target, content ) {
13932  var tooltipData, tooltip, events, delayedShow, a11yContent,
13933  positionOption = $.extend( {}, this.options.position );
13934 
13935  if ( !content ) {
13936  return;
13937  }
13938 
13939  // Content can be updated multiple times. If the tooltip already
13940  // exists, then just update the content and bail.
13941  tooltipData = this._find( target );
13942  if ( tooltipData ) {
13943  tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
13944  return;
13945  }
13946 
13947  // if we have a title, clear it to prevent the native tooltip
13948  // we have to check first to avoid defining a title if none exists
13949  // (we don't want to cause an element to start matching [title])
13950  //
13951  // We use removeAttr only for key events, to allow IE to export the correct
13952  // accessible attributes. For mouse events, set to empty string to avoid
13953  // native tooltip showing up (happens only when removing inside mouseover).
13954  if ( target.is( "[title]" ) ) {
13955  if ( event && event.type === "mouseover" ) {
13956  target.attr( "title", "" );
13957  } else {
13958  target.removeAttr( "title" );
13959  }
13960  }
13961 
13962  tooltipData = this._tooltip( target );
13963  tooltip = tooltipData.tooltip;
13964  this._addDescribedBy( target, tooltip.attr( "id" ) );
13965  tooltip.find( ".ui-tooltip-content" ).html( content );
13966 
13967  // Support: Voiceover on OS X, JAWS on IE <= 9
13968  // JAWS announces deletions even when aria-relevant="additions"
13969  // Voiceover will sometimes re-read the entire log region's contents from the beginning
13970  this.liveRegion.children().hide();
13971  if ( content.clone ) {
13972  a11yContent = content.clone();
13973  a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
13974  } else {
13975  a11yContent = content;
13976  }
13977  $( "<div>" ).html( a11yContent ).appendTo( this.liveRegion );
13978 
13979  function position( event ) {
13980  positionOption.of = event;
13981  if ( tooltip.is( ":hidden" ) ) {
13982  return;
13983  }
13984  tooltip.position( positionOption );
13985  }
13986  if ( this.options.track && event && /^mouse/.test( event.type ) ) {
13987  this._on( this.document, {
13988  mousemove: position
13989  });
13990  // trigger once to override element-relative positioning
13991  position( event );
13992  } else {
13993  tooltip.position( $.extend({
13994  of: target
13995  }, this.options.position ) );
13996  }
13997 
13998  tooltip.hide();
13999 
14000  this._show( tooltip, this.options.show );
14001  // Handle tracking tooltips that are shown with a delay (#8644). As soon
14002  // as the tooltip is visible, position the tooltip using the most recent
14003  // event.
14004  if ( this.options.show && this.options.show.delay ) {
14005  delayedShow = this.delayedShow = setInterval(function() {
14006  if ( tooltip.is( ":visible" ) ) {
14007  position( positionOption.of );
14008  clearInterval( delayedShow );
14009  }
14010  }, $.fx.interval );
14011  }
14012 
14013  this._trigger( "open", event, { tooltip: tooltip } );
14014 
14015  events = {
14016  keyup: function( event ) {
14017  if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
14018  var fakeEvent = $.Event(event);
14019  fakeEvent.currentTarget = target[0];
14020  this.close( fakeEvent, true );
14021  }
14022  }
14023  };
14024 
14025  // Only bind remove handler for delegated targets. Non-delegated
14026  // tooltips will handle this in destroy.
14027  if ( target[ 0 ] !== this.element[ 0 ] ) {
14028  events.remove = function() {
14029  this._removeTooltip( tooltip );
14030  };
14031  }
14032 
14033  if ( !event || event.type === "mouseover" ) {
14034  events.mouseleave = "close";
14035  }
14036  if ( !event || event.type === "focusin" ) {
14037  events.focusout = "close";
14038  }
14039  this._on( true, target, events );
14040  },
14041 
14042  close: function( event ) {
14043  var tooltip,
14044  that = this,
14045  target = $( event ? event.currentTarget : this.element ),
14046  tooltipData = this._find( target );
14047 
14048  // The tooltip may already be closed
14049  if ( !tooltipData ) {
14050  return;
14051  }
14052 
14053  tooltip = tooltipData.tooltip;
14054 
14055  // disabling closes the tooltip, so we need to track when we're closing
14056  // to avoid an infinite loop in case the tooltip becomes disabled on close
14057  if ( tooltipData.closing ) {
14058  return;
14059  }
14060 
14061  // Clear the interval for delayed tracking tooltips
14062  clearInterval( this.delayedShow );
14063 
14064  // only set title if we had one before (see comment in _open())
14065  // If the title attribute has changed since open(), don't restore
14066  if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
14067  target.attr( "title", target.data( "ui-tooltip-title" ) );
14068  }
14069 
14070  this._removeDescribedBy( target );
14071 
14072  tooltipData.hiding = true;
14073  tooltip.stop( true );
14074  this._hide( tooltip, this.options.hide, function() {
14075  that._removeTooltip( $( this ) );
14076  });
14077 
14078  target.removeData( "ui-tooltip-open" );
14079  this._off( target, "mouseleave focusout keyup" );
14080 
14081  // Remove 'remove' binding only on delegated targets
14082  if ( target[ 0 ] !== this.element[ 0 ] ) {
14083  this._off( target, "remove" );
14084  }
14085  this._off( this.document, "mousemove" );
14086 
14087  if ( event && event.type === "mouseleave" ) {
14088  $.each( this.parents, function( id, parent ) {
14089  $( parent.element ).attr( "title", parent.title );
14090  delete that.parents[ id ];
14091  });
14092  }
14093 
14094  tooltipData.closing = true;
14095  this._trigger( "close", event, { tooltip: tooltip } );
14096  if ( !tooltipData.hiding ) {
14097  tooltipData.closing = false;
14098  }
14099  },
14100 
14101  _tooltip: function( element ) {
14102  var tooltip = $( "<div>" )
14103  .attr( "role", "tooltip" )
14104  .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
14105  ( this.options.tooltipClass || "" ) ),
14106  id = tooltip.uniqueId().attr( "id" );
14107 
14108  $( "<div>" )
14109  .addClass( "ui-tooltip-content" )
14110  .appendTo( tooltip );
14111 
14112  tooltip.appendTo( this.document[0].body );
14113 
14114  return this.tooltips[ id ] = {
14115  element: element,
14116  tooltip: tooltip
14117  };
14118  },
14119 
14120  _find: function( target ) {
14121  var id = target.data( "ui-tooltip-id" );
14122  return id ? this.tooltips[ id ] : null;
14123  },
14124 
14125  _removeTooltip: function( tooltip ) {
14126  tooltip.remove();
14127  delete this.tooltips[ tooltip.attr( "id" ) ];
14128  },
14129 
14130  _destroy: function() {
14131  var that = this;
14132 
14133  // close open tooltips
14134  $.each( this.tooltips, function( id, tooltipData ) {
14135  // Delegate to close method to handle common cleanup
14136  var event = $.Event( "blur" ),
14137  element = tooltipData.element;
14138  event.target = event.currentTarget = element[ 0 ];
14139  that.close( event, true );
14140 
14141  // Remove immediately; destroying an open tooltip doesn't use the
14142  // hide animation
14143  $( "#" + id ).remove();
14144 
14145  // Restore the title
14146  if ( element.data( "ui-tooltip-title" ) ) {
14147  // If the title attribute has changed since open(), don't restore
14148  if ( !element.attr( "title" ) ) {
14149  element.attr( "title", element.data( "ui-tooltip-title" ) );
14150  }
14151  element.removeData( "ui-tooltip-title" );
14152  }
14153  });
14154  this.liveRegion.remove();
14155  }
14156 });
14157 
14158 
14159 /*!
14160  * jQuery UI Effects 1.11.2
14161  * http://jqueryui.com
14162  *
14163  * Copyright 2014 jQuery Foundation and other contributors
14164  * Released under the MIT license.
14165  * http://jquery.org/license
14166  *
14167  * http://api.jqueryui.com/category/effects-core/
14168  */
14169 
14170 
14171 var dataSpace = "ui-effects-",
14172 
14173  // Create a local jQuery because jQuery Color relies on it and the
14174  // global may not exist with AMD and a custom build (#10199)
14175  jQuery = $;
14176 
14177 $.effects = {
14178  effect: {}
14179 };
14180 
14181 /*!
14182  * jQuery Color Animations v2.1.2
14183  * https://github.com/jquery/jquery-color
14184  *
14185  * Copyright 2014 jQuery Foundation and other contributors
14186  * Released under the MIT license.
14187  * http://jquery.org/license
14188  *
14189  * Date: Wed Jan 16 08:47:09 2013 -0600
14190  */
14191 (function( jQuery, undefined ) {
14192 
14193  var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
14194 
14195  // plusequals test for += 100 -= 100
14196  rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
14197  // a set of RE's that can match strings and generate color tuples.
14198  stringParsers = [ {
14199  re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
14200  parse: function( execResult ) {
14201  return [
14202  execResult[ 1 ],
14203  execResult[ 2 ],
14204  execResult[ 3 ],
14205  execResult[ 4 ]
14206  ];
14207  }
14208  }, {
14209  re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
14210  parse: function( execResult ) {
14211  return [
14212  execResult[ 1 ] * 2.55,
14213  execResult[ 2 ] * 2.55,
14214  execResult[ 3 ] * 2.55,
14215  execResult[ 4 ]
14216  ];
14217  }
14218  }, {
14219  // this regex ignores A-F because it's compared against an already lowercased string
14220  re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
14221  parse: function( execResult ) {
14222  return [
14223  parseInt( execResult[ 1 ], 16 ),
14224  parseInt( execResult[ 2 ], 16 ),
14225  parseInt( execResult[ 3 ], 16 )
14226  ];
14227  }
14228  }, {
14229  // this regex ignores A-F because it's compared against an already lowercased string
14230  re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
14231  parse: function( execResult ) {
14232  return [
14233  parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
14234  parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
14235  parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
14236  ];
14237  }
14238  }, {
14239  re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
14240  space: "hsla",
14241  parse: function( execResult ) {
14242  return [
14243  execResult[ 1 ],
14244  execResult[ 2 ] / 100,
14245  execResult[ 3 ] / 100,
14246  execResult[ 4 ]
14247  ];
14248  }
14249  } ],
14250 
14251  // jQuery.Color( )
14252  color = jQuery.Color = function( color, green, blue, alpha ) {
14253  return new jQuery.Color.fn.parse( color, green, blue, alpha );
14254  },
14255  spaces = {
14256  rgba: {
14257  props: {
14258  red: {
14259  idx: 0,
14260  type: "byte"
14261  },
14262  green: {
14263  idx: 1,
14264  type: "byte"
14265  },
14266  blue: {
14267  idx: 2,
14268  type: "byte"
14269  }
14270  }
14271  },
14272 
14273  hsla: {
14274  props: {
14275  hue: {
14276  idx: 0,
14277  type: "degrees"
14278  },
14279  saturation: {
14280  idx: 1,
14281  type: "percent"
14282  },
14283  lightness: {
14284  idx: 2,
14285  type: "percent"
14286  }
14287  }
14288  }
14289  },
14290  propTypes = {
14291  "byte": {
14292  floor: true,
14293  max: 255
14294  },
14295  "percent": {
14296  max: 1
14297  },
14298  "degrees": {
14299  mod: 360,
14300  floor: true
14301  }
14302  },
14303  support = color.support = {},
14304 
14305  // element for support tests
14306  supportElem = jQuery( "<p>" )[ 0 ],
14307 
14308  // colors = jQuery.Color.names
14309  colors,
14310 
14311  // local aliases of functions called often
14312  each = jQuery.each;
14313 
14314 // determine rgba support immediately
14315 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
14316 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
14317 
14318 // define cache name and alpha properties
14319 // for rgba and hsla spaces
14320 each( spaces, function( spaceName, space ) {
14321  space.cache = "_" + spaceName;
14322  space.props.alpha = {
14323  idx: 3,
14324  type: "percent",
14325  def: 1
14326  };
14327 });
14328 
14329 function clamp( value, prop, allowEmpty ) {
14330  var type = propTypes[ prop.type ] || {};
14331 
14332  if ( value == null ) {
14333  return (allowEmpty || !prop.def) ? null : prop.def;
14334  }
14335 
14336  // ~~ is an short way of doing floor for positive numbers
14337  value = type.floor ? ~~value : parseFloat( value );
14338 
14339  // IE will pass in empty strings as value for alpha,
14340  // which will hit this case
14341  if ( isNaN( value ) ) {
14342  return prop.def;
14343  }
14344 
14345  if ( type.mod ) {
14346  // we add mod before modding to make sure that negatives values
14347  // get converted properly: -10 -> 350
14348  return (value + type.mod) % type.mod;
14349  }
14350 
14351  // for now all property types without mod have min and max
14352  return 0 > value ? 0 : type.max < value ? type.max : value;
14353 }
14354 
14355 function stringParse( string ) {
14356  var inst = color(),
14357  rgba = inst._rgba = [];
14358 
14359  string = string.toLowerCase();
14360 
14361  each( stringParsers, function( i, parser ) {
14362  var parsed,
14363  match = parser.re.exec( string ),
14364  values = match && parser.parse( match ),
14365  spaceName = parser.space || "rgba";
14366 
14367  if ( values ) {
14368  parsed = inst[ spaceName ]( values );
14369 
14370  // if this was an rgba parse the assignment might happen twice
14371  // oh well....
14372  inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
14373  rgba = inst._rgba = parsed._rgba;
14374 
14375  // exit each( stringParsers ) here because we matched
14376  return false;
14377  }
14378  });
14379 
14380  // Found a stringParser that handled it
14381  if ( rgba.length ) {
14382 
14383  // if this came from a parsed string, force "transparent" when alpha is 0
14384  // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
14385  if ( rgba.join() === "0,0,0,0" ) {
14386  jQuery.extend( rgba, colors.transparent );
14387  }
14388  return inst;
14389  }
14390 
14391  // named colors
14392  return colors[ string ];
14393 }
14394 
14395 color.fn = jQuery.extend( color.prototype, {
14396  parse: function( red, green, blue, alpha ) {
14397  if ( red === undefined ) {
14398  this._rgba = [ null, null, null, null ];
14399  return this;
14400  }
14401  if ( red.jquery || red.nodeType ) {
14402  red = jQuery( red ).css( green );
14403  green = undefined;
14404  }
14405 
14406  var inst = this,
14407  type = jQuery.type( red ),
14408  rgba = this._rgba = [];
14409 
14410  // more than 1 argument specified - assume ( red, green, blue, alpha )
14411  if ( green !== undefined ) {
14412  red = [ red, green, blue, alpha ];
14413  type = "array";
14414  }
14415 
14416  if ( type === "string" ) {
14417  return this.parse( stringParse( red ) || colors._default );
14418  }
14419 
14420  if ( type === "array" ) {
14421  each( spaces.rgba.props, function( key, prop ) {
14422  rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
14423  });
14424  return this;
14425  }
14426 
14427  if ( type === "object" ) {
14428  if ( red instanceof color ) {
14429  each( spaces, function( spaceName, space ) {
14430  if ( red[ space.cache ] ) {
14431  inst[ space.cache ] = red[ space.cache ].slice();
14432  }
14433  });
14434  } else {
14435  each( spaces, function( spaceName, space ) {
14436  var cache = space.cache;
14437  each( space.props, function( key, prop ) {
14438 
14439  // if the cache doesn't exist, and we know how to convert
14440  if ( !inst[ cache ] && space.to ) {
14441 
14442  // if the value was null, we don't need to copy it
14443  // if the key was alpha, we don't need to copy it either
14444  if ( key === "alpha" || red[ key ] == null ) {
14445  return;
14446  }
14447  inst[ cache ] = space.to( inst._rgba );
14448  }
14449 
14450  // this is the only case where we allow nulls for ALL properties.
14451  // call clamp with alwaysAllowEmpty
14452  inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
14453  });
14454 
14455  // everything defined but alpha?
14456  if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
14457  // use the default of 1
14458  inst[ cache ][ 3 ] = 1;
14459  if ( space.from ) {
14460  inst._rgba = space.from( inst[ cache ] );
14461  }
14462  }
14463  });
14464  }
14465  return this;
14466  }
14467  },
14468  is: function( compare ) {
14469  var is = color( compare ),
14470  same = true,
14471  inst = this;
14472 
14473  each( spaces, function( _, space ) {
14474  var localCache,
14475  isCache = is[ space.cache ];
14476  if (isCache) {
14477  localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
14478  each( space.props, function( _, prop ) {
14479  if ( isCache[ prop.idx ] != null ) {
14480  same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
14481  return same;
14482  }
14483  });
14484  }
14485  return same;
14486  });
14487  return same;
14488  },
14489  _space: function() {
14490  var used = [],
14491  inst = this;
14492  each( spaces, function( spaceName, space ) {
14493  if ( inst[ space.cache ] ) {
14494  used.push( spaceName );
14495  }
14496  });
14497  return used.pop();
14498  },
14499  transition: function( other, distance ) {
14500  var end = color( other ),
14501  spaceName = end._space(),
14502  space = spaces[ spaceName ],
14503  startColor = this.alpha() === 0 ? color( "transparent" ) : this,
14504  start = startColor[ space.cache ] || space.to( startColor._rgba ),
14505  result = start.slice();
14506 
14507  end = end[ space.cache ];
14508  each( space.props, function( key, prop ) {
14509  var index = prop.idx,
14510  startValue = start[ index ],
14511  endValue = end[ index ],
14512  type = propTypes[ prop.type ] || {};
14513 
14514  // if null, don't override start value
14515  if ( endValue === null ) {
14516  return;
14517  }
14518  // if null - use end
14519  if ( startValue === null ) {
14520  result[ index ] = endValue;
14521  } else {
14522  if ( type.mod ) {
14523  if ( endValue - startValue > type.mod / 2 ) {
14524  startValue += type.mod;
14525  } else if ( startValue - endValue > type.mod / 2 ) {
14526  startValue -= type.mod;
14527  }
14528  }
14529  result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
14530  }
14531  });
14532  return this[ spaceName ]( result );
14533  },
14534  blend: function( opaque ) {
14535  // if we are already opaque - return ourself
14536  if ( this._rgba[ 3 ] === 1 ) {
14537  return this;
14538  }
14539 
14540  var rgb = this._rgba.slice(),
14541  a = rgb.pop(),
14542  blend = color( opaque )._rgba;
14543 
14544  return color( jQuery.map( rgb, function( v, i ) {
14545  return ( 1 - a ) * blend[ i ] + a * v;
14546  }));
14547  },
14548  toRgbaString: function() {
14549  var prefix = "rgba(",
14550  rgba = jQuery.map( this._rgba, function( v, i ) {
14551  return v == null ? ( i > 2 ? 1 : 0 ) : v;
14552  });
14553 
14554  if ( rgba[ 3 ] === 1 ) {
14555  rgba.pop();
14556  prefix = "rgb(";
14557  }
14558 
14559  return prefix + rgba.join() + ")";
14560  },
14561  toHslaString: function() {
14562  var prefix = "hsla(",
14563  hsla = jQuery.map( this.hsla(), function( v, i ) {
14564  if ( v == null ) {
14565  v = i > 2 ? 1 : 0;
14566  }
14567 
14568  // catch 1 and 2
14569  if ( i && i < 3 ) {
14570  v = Math.round( v * 100 ) + "%";
14571  }
14572  return v;
14573  });
14574 
14575  if ( hsla[ 3 ] === 1 ) {
14576  hsla.pop();
14577  prefix = "hsl(";
14578  }
14579  return prefix + hsla.join() + ")";
14580  },
14581  toHexString: function( includeAlpha ) {
14582  var rgba = this._rgba.slice(),
14583  alpha = rgba.pop();
14584 
14585  if ( includeAlpha ) {
14586  rgba.push( ~~( alpha * 255 ) );
14587  }
14588 
14589  return "#" + jQuery.map( rgba, function( v ) {
14590 
14591  // default to 0 when nulls exist
14592  v = ( v || 0 ).toString( 16 );
14593  return v.length === 1 ? "0" + v : v;
14594  }).join("");
14595  },
14596  toString: function() {
14597  return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
14598  }
14599 });
14600 color.fn.parse.prototype = color.fn;
14601 
14602 // hsla conversions adapted from:
14603 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
14604 
14605 function hue2rgb( p, q, h ) {
14606  h = ( h + 1 ) % 1;
14607  if ( h * 6 < 1 ) {
14608  return p + ( q - p ) * h * 6;
14609  }
14610  if ( h * 2 < 1) {
14611  return q;
14612  }
14613  if ( h * 3 < 2 ) {
14614  return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
14615  }
14616  return p;
14617 }
14618 
14619 spaces.hsla.to = function( rgba ) {
14620  if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
14621  return [ null, null, null, rgba[ 3 ] ];
14622  }
14623  var r = rgba[ 0 ] / 255,
14624  g = rgba[ 1 ] / 255,
14625  b = rgba[ 2 ] / 255,
14626  a = rgba[ 3 ],
14627  max = Math.max( r, g, b ),
14628  min = Math.min( r, g, b ),
14629  diff = max - min,
14630  add = max + min,
14631  l = add * 0.5,
14632  h, s;
14633 
14634  if ( min === max ) {
14635  h = 0;
14636  } else if ( r === max ) {
14637  h = ( 60 * ( g - b ) / diff ) + 360;
14638  } else if ( g === max ) {
14639  h = ( 60 * ( b - r ) / diff ) + 120;
14640  } else {
14641  h = ( 60 * ( r - g ) / diff ) + 240;
14642  }
14643 
14644  // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
14645  // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
14646  if ( diff === 0 ) {
14647  s = 0;
14648  } else if ( l <= 0.5 ) {
14649  s = diff / add;
14650  } else {
14651  s = diff / ( 2 - add );
14652  }
14653  return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
14654 };
14655 
14656 spaces.hsla.from = function( hsla ) {
14657  if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
14658  return [ null, null, null, hsla[ 3 ] ];
14659  }
14660  var h = hsla[ 0 ] / 360,
14661  s = hsla[ 1 ],
14662  l = hsla[ 2 ],
14663  a = hsla[ 3 ],
14664  q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
14665  p = 2 * l - q;
14666 
14667  return [
14668  Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
14669  Math.round( hue2rgb( p, q, h ) * 255 ),
14670  Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
14671  a
14672  ];
14673 };
14674 
14675 each( spaces, function( spaceName, space ) {
14676  var props = space.props,
14677  cache = space.cache,
14678  to = space.to,
14679  from = space.from;
14680 
14681  // makes rgba() and hsla()
14682  color.fn[ spaceName ] = function( value ) {
14683 
14684  // generate a cache for this space if it doesn't exist
14685  if ( to && !this[ cache ] ) {
14686  this[ cache ] = to( this._rgba );
14687  }
14688  if ( value === undefined ) {
14689  return this[ cache ].slice();
14690  }
14691 
14692  var ret,
14693  type = jQuery.type( value ),
14694  arr = ( type === "array" || type === "object" ) ? value : arguments,
14695  local = this[ cache ].slice();
14696 
14697  each( props, function( key, prop ) {
14698  var val = arr[ type === "object" ? key : prop.idx ];
14699  if ( val == null ) {
14700  val = local[ prop.idx ];
14701  }
14702  local[ prop.idx ] = clamp( val, prop );
14703  });
14704 
14705  if ( from ) {
14706  ret = color( from( local ) );
14707  ret[ cache ] = local;
14708  return ret;
14709  } else {
14710  return color( local );
14711  }
14712  };
14713 
14714  // makes red() green() blue() alpha() hue() saturation() lightness()
14715  each( props, function( key, prop ) {
14716  // alpha is included in more than one space
14717  if ( color.fn[ key ] ) {
14718  return;
14719  }
14720  color.fn[ key ] = function( value ) {
14721  var vtype = jQuery.type( value ),
14722  fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
14723  local = this[ fn ](),
14724  cur = local[ prop.idx ],
14725  match;
14726 
14727  if ( vtype === "undefined" ) {
14728  return cur;
14729  }
14730 
14731  if ( vtype === "function" ) {
14732  value = value.call( this, cur );
14733  vtype = jQuery.type( value );
14734  }
14735  if ( value == null && prop.empty ) {
14736  return this;
14737  }
14738  if ( vtype === "string" ) {
14739  match = rplusequals.exec( value );
14740  if ( match ) {
14741  value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
14742  }
14743  }
14744  local[ prop.idx ] = value;
14745  return this[ fn ]( local );
14746  };
14747  });
14748 });
14749 
14750 // add cssHook and .fx.step function for each named hook.
14751 // accept a space separated string of properties
14752 color.hook = function( hook ) {
14753  var hooks = hook.split( " " );
14754  each( hooks, function( i, hook ) {
14755  jQuery.cssHooks[ hook ] = {
14756  set: function( elem, value ) {
14757  var parsed, curElem,
14758  backgroundColor = "";
14759 
14760  if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
14761  value = color( parsed || value );
14762  if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
14763  curElem = hook === "backgroundColor" ? elem.parentNode : elem;
14764  while (
14765  (backgroundColor === "" || backgroundColor === "transparent") &&
14766  curElem && curElem.style
14767  ) {
14768  try {
14769  backgroundColor = jQuery.css( curElem, "backgroundColor" );
14770  curElem = curElem.parentNode;
14771  } catch ( e ) {
14772  }
14773  }
14774 
14775  value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
14776  backgroundColor :
14777  "_default" );
14778  }
14779 
14780  value = value.toRgbaString();
14781  }
14782  try {
14783  elem.style[ hook ] = value;
14784  } catch ( e ) {
14785  // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
14786  }
14787  }
14788  };
14789  jQuery.fx.step[ hook ] = function( fx ) {
14790  if ( !fx.colorInit ) {
14791  fx.start = color( fx.elem, hook );
14792  fx.end = color( fx.end );
14793  fx.colorInit = true;
14794  }
14795  jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
14796  };
14797  });
14798 
14799 };
14800 
14801 color.hook( stepHooks );
14802 
14803 jQuery.cssHooks.borderColor = {
14804  expand: function( value ) {
14805  var expanded = {};
14806 
14807  each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
14808  expanded[ "border" + part + "Color" ] = value;
14809  });
14810  return expanded;
14811  }
14812 };
14813 
14814 // Basic color names only.
14815 // Usage of any of the other color names requires adding yourself or including
14816 // jquery.color.svg-names.js.
14817 colors = jQuery.Color.names = {
14818  // 4.1. Basic color keywords
14819  aqua: "#00ffff",
14820  black: "#000000",
14821  blue: "#0000ff",
14822  fuchsia: "#ff00ff",
14823  gray: "#808080",
14824  green: "#008000",
14825  lime: "#00ff00",
14826  maroon: "#800000",
14827  navy: "#000080",
14828  olive: "#808000",
14829  purple: "#800080",
14830  red: "#ff0000",
14831  silver: "#c0c0c0",
14832  teal: "#008080",
14833  white: "#ffffff",
14834  yellow: "#ffff00",
14835 
14836  // 4.2.3. "transparent" color keyword
14837  transparent: [ null, null, null, 0 ],
14838 
14839  _default: "#ffffff"
14840 };
14841 
14842 })( jQuery );
14843 
14844 /******************************************************************************/
14845 /****************************** CLASS ANIMATIONS ******************************/
14846 /******************************************************************************/
14847 (function() {
14848 
14849 var classAnimationActions = [ "add", "remove", "toggle" ],
14850  shorthandStyles = {
14851  border: 1,
14852  borderBottom: 1,
14853  borderColor: 1,
14854  borderLeft: 1,
14855  borderRight: 1,
14856  borderTop: 1,
14857  borderWidth: 1,
14858  margin: 1,
14859  padding: 1
14860  };
14861 
14862 $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
14863  $.fx.step[ prop ] = function( fx ) {
14864  if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
14865  jQuery.style( fx.elem, prop, fx.end );
14866  fx.setAttr = true;
14867  }
14868  };
14869 });
14870 
14871 function getElementStyles( elem ) {
14872  var key, len,
14873  style = elem.ownerDocument.defaultView ?
14874  elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
14875  elem.currentStyle,
14876  styles = {};
14877 
14878  if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
14879  len = style.length;
14880  while ( len-- ) {
14881  key = style[ len ];
14882  if ( typeof style[ key ] === "string" ) {
14883  styles[ $.camelCase( key ) ] = style[ key ];
14884  }
14885  }
14886  // support: Opera, IE <9
14887  } else {
14888  for ( key in style ) {
14889  if ( typeof style[ key ] === "string" ) {
14890  styles[ key ] = style[ key ];
14891  }
14892  }
14893  }
14894 
14895  return styles;
14896 }
14897 
14898 function styleDifference( oldStyle, newStyle ) {
14899  var diff = {},
14900  name, value;
14901 
14902  for ( name in newStyle ) {
14903  value = newStyle[ name ];
14904  if ( oldStyle[ name ] !== value ) {
14905  if ( !shorthandStyles[ name ] ) {
14906  if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
14907  diff[ name ] = value;
14908  }
14909  }
14910  }
14911  }
14912 
14913  return diff;
14914 }
14915 
14916 // support: jQuery <1.8
14917 if ( !$.fn.addBack ) {
14918  $.fn.addBack = function( selector ) {
14919  return this.add( selector == null ?
14920  this.prevObject : this.prevObject.filter( selector )
14921  );
14922  };
14923 }
14924 
14925 $.effects.animateClass = function( value, duration, easing, callback ) {
14926  var o = $.speed( duration, easing, callback );
14927 
14928  return this.queue( function() {
14929  var animated = $( this ),
14930  baseClass = animated.attr( "class" ) || "",
14931  applyClassChange,
14932  allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
14933 
14934  // map the animated objects to store the original styles.
14935  allAnimations = allAnimations.map(function() {
14936  var el = $( this );
14937  return {
14938  el: el,
14939  start: getElementStyles( this )
14940  };
14941  });
14942 
14943  // apply class change
14944  applyClassChange = function() {
14945  $.each( classAnimationActions, function(i, action) {
14946  if ( value[ action ] ) {
14947  animated[ action + "Class" ]( value[ action ] );
14948  }
14949  });
14950  };
14951  applyClassChange();
14952 
14953  // map all animated objects again - calculate new styles and diff
14954  allAnimations = allAnimations.map(function() {
14955  this.end = getElementStyles( this.el[ 0 ] );
14956  this.diff = styleDifference( this.start, this.end );
14957  return this;
14958  });
14959 
14960  // apply original class
14961  animated.attr( "class", baseClass );
14962 
14963  // map all animated objects again - this time collecting a promise
14964  allAnimations = allAnimations.map(function() {
14965  var styleInfo = this,
14966  dfd = $.Deferred(),
14967  opts = $.extend({}, o, {
14968  queue: false,
14969  complete: function() {
14970  dfd.resolve( styleInfo );
14971  }
14972  });
14973 
14974  this.el.animate( this.diff, opts );
14975  return dfd.promise();
14976  });
14977 
14978  // once all animations have completed:
14979  $.when.apply( $, allAnimations.get() ).done(function() {
14980 
14981  // set the final class
14982  applyClassChange();
14983 
14984  // for each animated element,
14985  // clear all css properties that were animated
14986  $.each( arguments, function() {
14987  var el = this.el;
14988  $.each( this.diff, function(key) {
14989  el.css( key, "" );
14990  });
14991  });
14992 
14993  // this is guarnteed to be there if you use jQuery.speed()
14994  // it also handles dequeuing the next anim...
14995  o.complete.call( animated[ 0 ] );
14996  });
14997  });
14998 };
14999 
15000 $.fn.extend({
15001  addClass: (function( orig ) {
15002  return function( classNames, speed, easing, callback ) {
15003  return speed ?
15004  $.effects.animateClass.call( this,
15005  { add: classNames }, speed, easing, callback ) :
15006  orig.apply( this, arguments );
15007  };
15008  })( $.fn.addClass ),
15009 
15010  removeClass: (function( orig ) {
15011  return function( classNames, speed, easing, callback ) {
15012  return arguments.length > 1 ?
15013  $.effects.animateClass.call( this,
15014  { remove: classNames }, speed, easing, callback ) :
15015  orig.apply( this, arguments );
15016  };
15017  })( $.fn.removeClass ),
15018 
15019  toggleClass: (function( orig ) {
15020  return function( classNames, force, speed, easing, callback ) {
15021  if ( typeof force === "boolean" || force === undefined ) {
15022  if ( !speed ) {
15023  // without speed parameter
15024  return orig.apply( this, arguments );
15025  } else {
15026  return $.effects.animateClass.call( this,
15027  (force ? { add: classNames } : { remove: classNames }),
15028  speed, easing, callback );
15029  }
15030  } else {
15031  // without force parameter
15032  return $.effects.animateClass.call( this,
15033  { toggle: classNames }, force, speed, easing );
15034  }
15035  };
15036  })( $.fn.toggleClass ),
15037 
15038  switchClass: function( remove, add, speed, easing, callback) {
15039  return $.effects.animateClass.call( this, {
15040  add: add,
15041  remove: remove
15042  }, speed, easing, callback );
15043  }
15044 });
15045 
15046 })();
15047 
15048 /******************************************************************************/
15049 /*********************************** EFFECTS **********************************/
15050 /******************************************************************************/
15051 
15052 (function() {
15053 
15054 $.extend( $.effects, {
15055  version: "1.11.2",
15056 
15057  // Saves a set of properties in a data storage
15058  save: function( element, set ) {
15059  for ( var i = 0; i < set.length; i++ ) {
15060  if ( set[ i ] !== null ) {
15061  element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
15062  }
15063  }
15064  },
15065 
15066  // Restores a set of previously saved properties from a data storage
15067  restore: function( element, set ) {
15068  var val, i;
15069  for ( i = 0; i < set.length; i++ ) {
15070  if ( set[ i ] !== null ) {
15071  val = element.data( dataSpace + set[ i ] );
15072  // support: jQuery 1.6.2
15073  // http://bugs.jquery.com/ticket/9917
15074  // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
15075  // We can't differentiate between "" and 0 here, so we just assume
15076  // empty string since it's likely to be a more common value...
15077  if ( val === undefined ) {
15078  val = "";
15079  }
15080  element.css( set[ i ], val );
15081  }
15082  }
15083  },
15084 
15085  setMode: function( el, mode ) {
15086  if (mode === "toggle") {
15087  mode = el.is( ":hidden" ) ? "show" : "hide";
15088  }
15089  return mode;
15090  },
15091 
15092  // Translates a [top,left] array into a baseline value
15093  // this should be a little more flexible in the future to handle a string & hash
15094  getBaseline: function( origin, original ) {
15095  var y, x;
15096  switch ( origin[ 0 ] ) {
15097  case "top": y = 0; break;
15098  case "middle": y = 0.5; break;
15099  case "bottom": y = 1; break;
15100  default: y = origin[ 0 ] / original.height;
15101  }
15102  switch ( origin[ 1 ] ) {
15103  case "left": x = 0; break;
15104  case "center": x = 0.5; break;
15105  case "right": x = 1; break;
15106  default: x = origin[ 1 ] / original.width;
15107  }
15108  return {
15109  x: x,
15110  y: y
15111  };
15112  },
15113 
15114  // Wraps the element around a wrapper that copies position properties
15115  createWrapper: function( element ) {
15116 
15117  // if the element is already wrapped, return it
15118  if ( element.parent().is( ".ui-effects-wrapper" )) {
15119  return element.parent();
15120  }
15121 
15122  // wrap the element
15123  var props = {
15124  width: element.outerWidth(true),
15125  height: element.outerHeight(true),
15126  "float": element.css( "float" )
15127  },
15128  wrapper = $( "<div></div>" )
15129  .addClass( "ui-effects-wrapper" )
15130  .css({
15131  fontSize: "100%",
15132  background: "transparent",
15133  border: "none",
15134  margin: 0,
15135  padding: 0
15136  }),
15137  // Store the size in case width/height are defined in % - Fixes #5245
15138  size = {
15139  width: element.width(),
15140  height: element.height()
15141  },
15142  active = document.activeElement;
15143 
15144  // support: Firefox
15145  // Firefox incorrectly exposes anonymous content
15146  // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
15147  try {
15148  active.id;
15149  } catch ( e ) {
15150  active = document.body;
15151  }
15152 
15153  element.wrap( wrapper );
15154 
15155  // Fixes #7595 - Elements lose focus when wrapped.
15156  if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
15157  $( active ).focus();
15158  }
15159 
15160  wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
15161 
15162  // transfer positioning properties to the wrapper
15163  if ( element.css( "position" ) === "static" ) {
15164  wrapper.css({ position: "relative" });
15165  element.css({ position: "relative" });
15166  } else {
15167  $.extend( props, {
15168  position: element.css( "position" ),
15169  zIndex: element.css( "z-index" )
15170  });
15171  $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
15172  props[ pos ] = element.css( pos );
15173  if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
15174  props[ pos ] = "auto";
15175  }
15176  });
15177  element.css({
15178  position: "relative",
15179  top: 0,
15180  left: 0,
15181  right: "auto",
15182  bottom: "auto"
15183  });
15184  }
15185  element.css(size);
15186 
15187  return wrapper.css( props ).show();
15188  },
15189 
15190  removeWrapper: function( element ) {
15191  var active = document.activeElement;
15192 
15193  if ( element.parent().is( ".ui-effects-wrapper" ) ) {
15194  element.parent().replaceWith( element );
15195 
15196  // Fixes #7595 - Elements lose focus when wrapped.
15197  if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
15198  $( active ).focus();
15199  }
15200  }
15201 
15202  return element;
15203  },
15204 
15205  setTransition: function( element, list, factor, value ) {
15206  value = value || {};
15207  $.each( list, function( i, x ) {
15208  var unit = element.cssUnit( x );
15209  if ( unit[ 0 ] > 0 ) {
15210  value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
15211  }
15212  });
15213  return value;
15214  }
15215 });
15216 
15217 // return an effect options object for the given parameters:
15218 function _normalizeArguments( effect, options, speed, callback ) {
15219 
15220  // allow passing all options as the first parameter
15221  if ( $.isPlainObject( effect ) ) {
15222  options = effect;
15223  effect = effect.effect;
15224  }
15225 
15226  // convert to an object
15227  effect = { effect: effect };
15228 
15229  // catch (effect, null, ...)
15230  if ( options == null ) {
15231  options = {};
15232  }
15233 
15234  // catch (effect, callback)
15235  if ( $.isFunction( options ) ) {
15236  callback = options;
15237  speed = null;
15238  options = {};
15239  }
15240 
15241  // catch (effect, speed, ?)
15242  if ( typeof options === "number" || $.fx.speeds[ options ] ) {
15243  callback = speed;
15244  speed = options;
15245  options = {};
15246  }
15247 
15248  // catch (effect, options, callback)
15249  if ( $.isFunction( speed ) ) {
15250  callback = speed;
15251  speed = null;
15252  }
15253 
15254  // add options to effect
15255  if ( options ) {
15256  $.extend( effect, options );
15257  }
15258 
15259  speed = speed || options.duration;
15260  effect.duration = $.fx.off ? 0 :
15261  typeof speed === "number" ? speed :
15262  speed in $.fx.speeds ? $.fx.speeds[ speed ] :
15263  $.fx.speeds._default;
15264 
15265  effect.complete = callback || options.complete;
15266 
15267  return effect;
15268 }
15269 
15270 function standardAnimationOption( option ) {
15271  // Valid standard speeds (nothing, number, named speed)
15272  if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
15273  return true;
15274  }
15275 
15276  // Invalid strings - treat as "normal" speed
15277  if ( typeof option === "string" && !$.effects.effect[ option ] ) {
15278  return true;
15279  }
15280 
15281  // Complete callback
15282  if ( $.isFunction( option ) ) {
15283  return true;
15284  }
15285 
15286  // Options hash (but not naming an effect)
15287  if ( typeof option === "object" && !option.effect ) {
15288  return true;
15289  }
15290 
15291  // Didn't match any standard API
15292  return false;
15293 }
15294 
15295 $.fn.extend({
15296  effect: function( /* effect, options, speed, callback */ ) {
15297  var args = _normalizeArguments.apply( this, arguments ),
15298  mode = args.mode,
15299  queue = args.queue,
15300  effectMethod = $.effects.effect[ args.effect ];
15301 
15302  if ( $.fx.off || !effectMethod ) {
15303  // delegate to the original method (e.g., .show()) if possible
15304  if ( mode ) {
15305  return this[ mode ]( args.duration, args.complete );
15306  } else {
15307  return this.each( function() {
15308  if ( args.complete ) {
15309  args.complete.call( this );
15310  }
15311  });
15312  }
15313  }
15314 
15315  function run( next ) {
15316  var elem = $( this ),
15317  complete = args.complete,
15318  mode = args.mode;
15319 
15320  function done() {
15321  if ( $.isFunction( complete ) ) {
15322  complete.call( elem[0] );
15323  }
15324  if ( $.isFunction( next ) ) {
15325  next();
15326  }
15327  }
15328 
15329  // If the element already has the correct final state, delegate to
15330  // the core methods so the internal tracking of "olddisplay" works.
15331  if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
15332  elem[ mode ]();
15333  done();
15334  } else {
15335  effectMethod.call( elem[0], args, done );
15336  }
15337  }
15338 
15339  return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
15340  },
15341 
15342  show: (function( orig ) {
15343  return function( option ) {
15344  if ( standardAnimationOption( option ) ) {
15345  return orig.apply( this, arguments );
15346  } else {
15347  var args = _normalizeArguments.apply( this, arguments );
15348  args.mode = "show";
15349  return this.effect.call( this, args );
15350  }
15351  };
15352  })( $.fn.show ),
15353 
15354  hide: (function( orig ) {
15355  return function( option ) {
15356  if ( standardAnimationOption( option ) ) {
15357  return orig.apply( this, arguments );
15358  } else {
15359  var args = _normalizeArguments.apply( this, arguments );
15360  args.mode = "hide";
15361  return this.effect.call( this, args );
15362  }
15363  };
15364  })( $.fn.hide ),
15365 
15366  toggle: (function( orig ) {
15367  return function( option ) {
15368  if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
15369  return orig.apply( this, arguments );
15370  } else {
15371  var args = _normalizeArguments.apply( this, arguments );
15372  args.mode = "toggle";
15373  return this.effect.call( this, args );
15374  }
15375  };
15376  })( $.fn.toggle ),
15377 
15378  // helper functions
15379  cssUnit: function(key) {
15380  var style = this.css( key ),
15381  val = [];
15382 
15383  $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
15384  if ( style.indexOf( unit ) > 0 ) {
15385  val = [ parseFloat( style ), unit ];
15386  }
15387  });
15388  return val;
15389  }
15390 });
15391 
15392 })();
15393 
15394 /******************************************************************************/
15395 /*********************************** EASING ***********************************/
15396 /******************************************************************************/
15397 
15398 (function() {
15399 
15400 // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
15401 
15402 var baseEasings = {};
15403 
15404 $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
15405  baseEasings[ name ] = function( p ) {
15406  return Math.pow( p, i + 2 );
15407  };
15408 });
15409 
15410 $.extend( baseEasings, {
15411  Sine: function( p ) {
15412  return 1 - Math.cos( p * Math.PI / 2 );
15413  },
15414  Circ: function( p ) {
15415  return 1 - Math.sqrt( 1 - p * p );
15416  },
15417  Elastic: function( p ) {
15418  return p === 0 || p === 1 ? p :
15419  -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
15420  },
15421  Back: function( p ) {
15422  return p * p * ( 3 * p - 2 );
15423  },
15424  Bounce: function( p ) {
15425  var pow2,
15426  bounce = 4;
15427 
15428  while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
15429  return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
15430  }
15431 });
15432 
15433 $.each( baseEasings, function( name, easeIn ) {
15434  $.easing[ "easeIn" + name ] = easeIn;
15435  $.easing[ "easeOut" + name ] = function( p ) {
15436  return 1 - easeIn( 1 - p );
15437  };
15438  $.easing[ "easeInOut" + name ] = function( p ) {
15439  return p < 0.5 ?
15440  easeIn( p * 2 ) / 2 :
15441  1 - easeIn( p * -2 + 2 ) / 2;
15442  };
15443 });
15444 
15445 })();
15446 
15447 var effect = $.effects;
15448 
15449 
15450 /*!
15451  * jQuery UI Effects Blind 1.11.2
15452  * http://jqueryui.com
15453  *
15454  * Copyright 2014 jQuery Foundation and other contributors
15455  * Released under the MIT license.
15456  * http://jquery.org/license
15457  *
15458  * http://api.jqueryui.com/blind-effect/
15459  */
15460 
15461 
15462 var effectBlind = $.effects.effect.blind = function( o, done ) {
15463  // Create element
15464  var el = $( this ),
15465  rvertical = /up|down|vertical/,
15466  rpositivemotion = /up|left|vertical|horizontal/,
15467  props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15468  mode = $.effects.setMode( el, o.mode || "hide" ),
15469  direction = o.direction || "up",
15470  vertical = rvertical.test( direction ),
15471  ref = vertical ? "height" : "width",
15472  ref2 = vertical ? "top" : "left",
15473  motion = rpositivemotion.test( direction ),
15474  animation = {},
15475  show = mode === "show",
15476  wrapper, distance, margin;
15477 
15478  // if already wrapped, the wrapper's properties are my property. #6245
15479  if ( el.parent().is( ".ui-effects-wrapper" ) ) {
15480  $.effects.save( el.parent(), props );
15481  } else {
15482  $.effects.save( el, props );
15483  }
15484  el.show();
15485  wrapper = $.effects.createWrapper( el ).css({
15486  overflow: "hidden"
15487  });
15488 
15489  distance = wrapper[ ref ]();
15490  margin = parseFloat( wrapper.css( ref2 ) ) || 0;
15491 
15492  animation[ ref ] = show ? distance : 0;
15493  if ( !motion ) {
15494  el
15495  .css( vertical ? "bottom" : "right", 0 )
15496  .css( vertical ? "top" : "left", "auto" )
15497  .css({ position: "absolute" });
15498 
15499  animation[ ref2 ] = show ? margin : distance + margin;
15500  }
15501 
15502  // start at 0 if we are showing
15503  if ( show ) {
15504  wrapper.css( ref, 0 );
15505  if ( !motion ) {
15506  wrapper.css( ref2, margin + distance );
15507  }
15508  }
15509 
15510  // Animate
15511  wrapper.animate( animation, {
15512  duration: o.duration,
15513  easing: o.easing,
15514  queue: false,
15515  complete: function() {
15516  if ( mode === "hide" ) {
15517  el.hide();
15518  }
15519  $.effects.restore( el, props );
15520  $.effects.removeWrapper( el );
15521  done();
15522  }
15523  });
15524 };
15525 
15526 
15527 /*!
15528  * jQuery UI Effects Bounce 1.11.2
15529  * http://jqueryui.com
15530  *
15531  * Copyright 2014 jQuery Foundation and other contributors
15532  * Released under the MIT license.
15533  * http://jquery.org/license
15534  *
15535  * http://api.jqueryui.com/bounce-effect/
15536  */
15537 
15538 
15539 var effectBounce = $.effects.effect.bounce = function( o, done ) {
15540  var el = $( this ),
15541  props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15542 
15543  // defaults:
15544  mode = $.effects.setMode( el, o.mode || "effect" ),
15545  hide = mode === "hide",
15546  show = mode === "show",
15547  direction = o.direction || "up",
15548  distance = o.distance,
15549  times = o.times || 5,
15550 
15551  // number of internal animations
15552  anims = times * 2 + ( show || hide ? 1 : 0 ),
15553  speed = o.duration / anims,
15554  easing = o.easing,
15555 
15556  // utility:
15557  ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
15558  motion = ( direction === "up" || direction === "left" ),
15559  i,
15560  upAnim,
15561  downAnim,
15562 
15563  // we will need to re-assemble the queue to stack our animations in place
15564  queue = el.queue(),
15565  queuelen = queue.length;
15566 
15567  // Avoid touching opacity to prevent clearType and PNG issues in IE
15568  if ( show || hide ) {
15569  props.push( "opacity" );
15570  }
15571 
15572  $.effects.save( el, props );
15573  el.show();
15574  $.effects.createWrapper( el ); // Create Wrapper
15575 
15576  // default distance for the BIGGEST bounce is the outer Distance / 3
15577  if ( !distance ) {
15578  distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
15579  }
15580 
15581  if ( show ) {
15582  downAnim = { opacity: 1 };
15583  downAnim[ ref ] = 0;
15584 
15585  // if we are showing, force opacity 0 and set the initial position
15586  // then do the "first" animation
15587  el.css( "opacity", 0 )
15588  .css( ref, motion ? -distance * 2 : distance * 2 )
15589  .animate( downAnim, speed, easing );
15590  }
15591 
15592  // start at the smallest distance if we are hiding
15593  if ( hide ) {
15594  distance = distance / Math.pow( 2, times - 1 );
15595  }
15596 
15597  downAnim = {};
15598  downAnim[ ref ] = 0;
15599  // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
15600  for ( i = 0; i < times; i++ ) {
15601  upAnim = {};
15602  upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
15603 
15604  el.animate( upAnim, speed, easing )
15605  .animate( downAnim, speed, easing );
15606 
15607  distance = hide ? distance * 2 : distance / 2;
15608  }
15609 
15610  // Last Bounce when Hiding
15611  if ( hide ) {
15612  upAnim = { opacity: 0 };
15613  upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
15614 
15615  el.animate( upAnim, speed, easing );
15616  }
15617 
15618  el.queue(function() {
15619  if ( hide ) {
15620  el.hide();
15621  }
15622  $.effects.restore( el, props );
15623  $.effects.removeWrapper( el );
15624  done();
15625  });
15626 
15627  // inject all the animations we just queued to be first in line (after "inprogress")
15628  if ( queuelen > 1) {
15629  queue.splice.apply( queue,
15630  [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
15631  }
15632  el.dequeue();
15633 
15634 };
15635 
15636 
15637 /*!
15638  * jQuery UI Effects Clip 1.11.2
15639  * http://jqueryui.com
15640  *
15641  * Copyright 2014 jQuery Foundation and other contributors
15642  * Released under the MIT license.
15643  * http://jquery.org/license
15644  *
15645  * http://api.jqueryui.com/clip-effect/
15646  */
15647 
15648 
15649 var effectClip = $.effects.effect.clip = function( o, done ) {
15650  // Create element
15651  var el = $( this ),
15652  props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15653  mode = $.effects.setMode( el, o.mode || "hide" ),
15654  show = mode === "show",
15655  direction = o.direction || "vertical",
15656  vert = direction === "vertical",
15657  size = vert ? "height" : "width",
15658  position = vert ? "top" : "left",
15659  animation = {},
15660  wrapper, animate, distance;
15661 
15662  // Save & Show
15663  $.effects.save( el, props );
15664  el.show();
15665 
15666  // Create Wrapper
15667  wrapper = $.effects.createWrapper( el ).css({
15668  overflow: "hidden"
15669  });
15670  animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
15671  distance = animate[ size ]();
15672 
15673  // Shift
15674  if ( show ) {
15675  animate.css( size, 0 );
15676  animate.css( position, distance / 2 );
15677  }
15678 
15679  // Create Animation Object:
15680  animation[ size ] = show ? distance : 0;
15681  animation[ position ] = show ? 0 : distance / 2;
15682 
15683  // Animate
15684  animate.animate( animation, {
15685  queue: false,
15686  duration: o.duration,
15687  easing: o.easing,
15688  complete: function() {
15689  if ( !show ) {
15690  el.hide();
15691  }
15692  $.effects.restore( el, props );
15693  $.effects.removeWrapper( el );
15694  done();
15695  }
15696  });
15697 
15698 };
15699 
15700 
15701 /*!
15702  * jQuery UI Effects Drop 1.11.2
15703  * http://jqueryui.com
15704  *
15705  * Copyright 2014 jQuery Foundation and other contributors
15706  * Released under the MIT license.
15707  * http://jquery.org/license
15708  *
15709  * http://api.jqueryui.com/drop-effect/
15710  */
15711 
15712 
15713 var effectDrop = $.effects.effect.drop = function( o, done ) {
15714 
15715  var el = $( this ),
15716  props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
15717  mode = $.effects.setMode( el, o.mode || "hide" ),
15718  show = mode === "show",
15719  direction = o.direction || "left",
15720  ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
15721  motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
15722  animation = {
15723  opacity: show ? 1 : 0
15724  },
15725  distance;
15726 
15727  // Adjust
15728  $.effects.save( el, props );
15729  el.show();
15730  $.effects.createWrapper( el );
15731 
15732  distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
15733 
15734  if ( show ) {
15735  el
15736  .css( "opacity", 0 )
15737  .css( ref, motion === "pos" ? -distance : distance );
15738  }
15739 
15740  // Animation
15741  animation[ ref ] = ( show ?
15742  ( motion === "pos" ? "+=" : "-=" ) :
15743  ( motion === "pos" ? "-=" : "+=" ) ) +
15744  distance;
15745 
15746  // Animate
15747  el.animate( animation, {
15748  queue: false,
15749  duration: o.duration,
15750  easing: o.easing,
15751  complete: function() {
15752  if ( mode === "hide" ) {
15753  el.hide();
15754  }
15755  $.effects.restore( el, props );
15756  $.effects.removeWrapper( el );
15757  done();
15758  }
15759  });
15760 };
15761 
15762 
15763 /*!
15764  * jQuery UI Effects Explode 1.11.2
15765  * http://jqueryui.com
15766  *
15767  * Copyright 2014 jQuery Foundation and other contributors
15768  * Released under the MIT license.
15769  * http://jquery.org/license
15770  *
15771  * http://api.jqueryui.com/explode-effect/
15772  */
15773 
15774 
15775 var effectExplode = $.effects.effect.explode = function( o, done ) {
15776 
15777  var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
15778  cells = rows,
15779  el = $( this ),
15780  mode = $.effects.setMode( el, o.mode || "hide" ),
15781  show = mode === "show",
15782 
15783  // show and then visibility:hidden the element before calculating offset
15784  offset = el.show().css( "visibility", "hidden" ).offset(),
15785 
15786  // width and height of a piece
15787  width = Math.ceil( el.outerWidth() / cells ),
15788  height = Math.ceil( el.outerHeight() / rows ),
15789  pieces = [],
15790 
15791  // loop
15792  i, j, left, top, mx, my;
15793 
15794  // children animate complete:
15795  function childComplete() {
15796  pieces.push( this );
15797  if ( pieces.length === rows * cells ) {
15798  animComplete();
15799  }
15800  }
15801 
15802  // clone the element for each row and cell.
15803  for ( i = 0; i < rows ; i++ ) { // ===>
15804  top = offset.top + i * height;
15805  my = i - ( rows - 1 ) / 2 ;
15806 
15807  for ( j = 0; j < cells ; j++ ) { // |||
15808  left = offset.left + j * width;
15809  mx = j - ( cells - 1 ) / 2 ;
15810 
15811  // Create a clone of the now hidden main element that will be absolute positioned
15812  // within a wrapper div off the -left and -top equal to size of our pieces
15813  el
15814  .clone()
15815  .appendTo( "body" )
15816  .wrap( "<div></div>" )
15817  .css({
15818  position: "absolute",
15819  visibility: "visible",
15820  left: -j * width,
15821  top: -i * height
15822  })
15823 
15824  // select the wrapper - make it overflow: hidden and absolute positioned based on
15825  // where the original was located +left and +top equal to the size of pieces
15826  .parent()
15827  .addClass( "ui-effects-explode" )
15828  .css({
15829  position: "absolute",
15830  overflow: "hidden",
15831  width: width,
15832  height: height,
15833  left: left + ( show ? mx * width : 0 ),
15834  top: top + ( show ? my * height : 0 ),
15835  opacity: show ? 0 : 1
15836  }).animate({
15837  left: left + ( show ? 0 : mx * width ),
15838  top: top + ( show ? 0 : my * height ),
15839  opacity: show ? 1 : 0
15840  }, o.duration || 500, o.easing, childComplete );
15841  }
15842  }
15843 
15844  function animComplete() {
15845  el.css({
15846  visibility: "visible"
15847  });
15848  $( pieces ).remove();
15849  if ( !show ) {
15850  el.hide();
15851  }
15852  done();
15853  }
15854 };
15855 
15856 
15857 /*!
15858  * jQuery UI Effects Fade 1.11.2
15859  * http://jqueryui.com
15860  *
15861  * Copyright 2014 jQuery Foundation and other contributors
15862  * Released under the MIT license.
15863  * http://jquery.org/license
15864  *
15865  * http://api.jqueryui.com/fade-effect/
15866  */
15867 
15868 
15869 var effectFade = $.effects.effect.fade = function( o, done ) {
15870  var el = $( this ),
15871  mode = $.effects.setMode( el, o.mode || "toggle" );
15872 
15873  el.animate({
15874  opacity: mode
15875  }, {
15876  queue: false,
15877  duration: o.duration,
15878  easing: o.easing,
15879  complete: done
15880  });
15881 };
15882 
15883 
15884 /*!
15885  * jQuery UI Effects Fold 1.11.2
15886  * http://jqueryui.com
15887  *
15888  * Copyright 2014 jQuery Foundation and other contributors
15889  * Released under the MIT license.
15890  * http://jquery.org/license
15891  *
15892  * http://api.jqueryui.com/fold-effect/
15893  */
15894 
15895 
15896 var effectFold = $.effects.effect.fold = function( o, done ) {
15897 
15898  // Create element
15899  var el = $( this ),
15900  props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15901  mode = $.effects.setMode( el, o.mode || "hide" ),
15902  show = mode === "show",
15903  hide = mode === "hide",
15904  size = o.size || 15,
15905  percent = /([0-9]+)%/.exec( size ),
15906  horizFirst = !!o.horizFirst,
15907  widthFirst = show !== horizFirst,
15908  ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
15909  duration = o.duration / 2,
15910  wrapper, distance,
15911  animation1 = {},
15912  animation2 = {};
15913 
15914  $.effects.save( el, props );
15915  el.show();
15916 
15917  // Create Wrapper
15918  wrapper = $.effects.createWrapper( el ).css({
15919  overflow: "hidden"
15920  });
15921  distance = widthFirst ?
15922  [ wrapper.width(), wrapper.height() ] :
15923  [ wrapper.height(), wrapper.width() ];
15924 
15925  if ( percent ) {
15926  size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
15927  }
15928  if ( show ) {
15929  wrapper.css( horizFirst ? {
15930  height: 0,
15931  width: size
15932  } : {
15933  height: size,
15934  width: 0
15935  });
15936  }
15937 
15938  // Animation
15939  animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
15940  animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
15941 
15942  // Animate
15943  wrapper
15944  .animate( animation1, duration, o.easing )
15945  .animate( animation2, duration, o.easing, function() {
15946  if ( hide ) {
15947  el.hide();
15948  }
15949  $.effects.restore( el, props );
15950  $.effects.removeWrapper( el );
15951  done();
15952  });
15953 
15954 };
15955 
15956 
15957 /*!
15958  * jQuery UI Effects Highlight 1.11.2
15959  * http://jqueryui.com
15960  *
15961  * Copyright 2014 jQuery Foundation and other contributors
15962  * Released under the MIT license.
15963  * http://jquery.org/license
15964  *
15965  * http://api.jqueryui.com/highlight-effect/
15966  */
15967 
15968 
15969 var effectHighlight = $.effects.effect.highlight = function( o, done ) {
15970  var elem = $( this ),
15971  props = [ "backgroundImage", "backgroundColor", "opacity" ],
15972  mode = $.effects.setMode( elem, o.mode || "show" ),
15973  animation = {
15974  backgroundColor: elem.css( "backgroundColor" )
15975  };
15976 
15977  if (mode === "hide") {
15978  animation.opacity = 0;
15979  }
15980 
15981  $.effects.save( elem, props );
15982 
15983  elem
15984  .show()
15985  .css({
15986  backgroundImage: "none",
15987  backgroundColor: o.color || "#ffff99"
15988  })
15989  .animate( animation, {
15990  queue: false,
15991  duration: o.duration,
15992  easing: o.easing,
15993  complete: function() {
15994  if ( mode === "hide" ) {
15995  elem.hide();
15996  }
15997  $.effects.restore( elem, props );
15998  done();
15999  }
16000  });
16001 };
16002 
16003 
16004 /*!
16005  * jQuery UI Effects Size 1.11.2
16006  * http://jqueryui.com
16007  *
16008  * Copyright 2014 jQuery Foundation and other contributors
16009  * Released under the MIT license.
16010  * http://jquery.org/license
16011  *
16012  * http://api.jqueryui.com/size-effect/
16013  */
16014 
16015 
16016 var effectSize = $.effects.effect.size = function( o, done ) {
16017 
16018  // Create element
16019  var original, baseline, factor,
16020  el = $( this ),
16021  props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
16022 
16023  // Always restore
16024  props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
16025 
16026  // Copy for children
16027  props2 = [ "width", "height", "overflow" ],
16028  cProps = [ "fontSize" ],
16029  vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
16030  hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
16031 
16032  // Set options
16033  mode = $.effects.setMode( el, o.mode || "effect" ),
16034  restore = o.restore || mode !== "effect",
16035  scale = o.scale || "both",
16036  origin = o.origin || [ "middle", "center" ],
16037  position = el.css( "position" ),
16038  props = restore ? props0 : props1,
16039  zero = {
16040  height: 0,
16041  width: 0,
16042  outerHeight: 0,
16043  outerWidth: 0
16044  };
16045 
16046  if ( mode === "show" ) {
16047  el.show();
16048  }
16049  original = {
16050  height: el.height(),
16051  width: el.width(),
16052  outerHeight: el.outerHeight(),
16053  outerWidth: el.outerWidth()
16054  };
16055 
16056  if ( o.mode === "toggle" && mode === "show" ) {
16057  el.from = o.to || zero;
16058  el.to = o.from || original;
16059  } else {
16060  el.from = o.from || ( mode === "show" ? zero : original );
16061  el.to = o.to || ( mode === "hide" ? zero : original );
16062  }
16063 
16064  // Set scaling factor
16065  factor = {
16066  from: {
16067  y: el.from.height / original.height,
16068  x: el.from.width / original.width
16069  },
16070  to: {
16071  y: el.to.height / original.height,
16072  x: el.to.width / original.width
16073  }
16074  };
16075 
16076  // Scale the css box
16077  if ( scale === "box" || scale === "both" ) {
16078 
16079  // Vertical props scaling
16080  if ( factor.from.y !== factor.to.y ) {
16081  props = props.concat( vProps );
16082  el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
16083  el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
16084  }
16085 
16086  // Horizontal props scaling
16087  if ( factor.from.x !== factor.to.x ) {
16088  props = props.concat( hProps );
16089  el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
16090  el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
16091  }
16092  }
16093 
16094  // Scale the content
16095  if ( scale === "content" || scale === "both" ) {
16096 
16097  // Vertical props scaling
16098  if ( factor.from.y !== factor.to.y ) {
16099  props = props.concat( cProps ).concat( props2 );
16100  el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
16101  el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
16102  }
16103  }
16104 
16105  $.effects.save( el, props );
16106  el.show();
16107  $.effects.createWrapper( el );
16108  el.css( "overflow", "hidden" ).css( el.from );
16109 
16110  // Adjust
16111  if (origin) { // Calculate baseline shifts
16112  baseline = $.effects.getBaseline( origin, original );
16113  el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
16114  el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
16115  el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
16116  el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
16117  }
16118  el.css( el.from ); // set top & left
16119 
16120  // Animate
16121  if ( scale === "content" || scale === "both" ) { // Scale the children
16122 
16123  // Add margins/font-size
16124  vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
16125  hProps = hProps.concat([ "marginLeft", "marginRight" ]);
16126  props2 = props0.concat(vProps).concat(hProps);
16127 
16128  el.find( "*[width]" ).each( function() {
16129  var child = $( this ),
16130  c_original = {
16131  height: child.height(),
16132  width: child.width(),
16133  outerHeight: child.outerHeight(),
16134  outerWidth: child.outerWidth()
16135  };
16136  if (restore) {
16137  $.effects.save(child, props2);
16138  }
16139 
16140  child.from = {
16141  height: c_original.height * factor.from.y,
16142  width: c_original.width * factor.from.x,
16143  outerHeight: c_original.outerHeight * factor.from.y,
16144  outerWidth: c_original.outerWidth * factor.from.x
16145  };
16146  child.to = {
16147  height: c_original.height * factor.to.y,
16148  width: c_original.width * factor.to.x,
16149  outerHeight: c_original.height * factor.to.y,
16150  outerWidth: c_original.width * factor.to.x
16151  };
16152 
16153  // Vertical props scaling
16154  if ( factor.from.y !== factor.to.y ) {
16155  child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
16156  child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
16157  }
16158 
16159  // Horizontal props scaling
16160  if ( factor.from.x !== factor.to.x ) {
16161  child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
16162  child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
16163  }
16164 
16165  // Animate children
16166  child.css( child.from );
16167  child.animate( child.to, o.duration, o.easing, function() {
16168 
16169  // Restore children
16170  if ( restore ) {
16171  $.effects.restore( child, props2 );
16172  }
16173  });
16174  });
16175  }
16176 
16177  // Animate
16178  el.animate( el.to, {
16179  queue: false,
16180  duration: o.duration,
16181  easing: o.easing,
16182  complete: function() {
16183  if ( el.to.opacity === 0 ) {
16184  el.css( "opacity", el.from.opacity );
16185  }
16186  if ( mode === "hide" ) {
16187  el.hide();
16188  }
16189  $.effects.restore( el, props );
16190  if ( !restore ) {
16191 
16192  // we need to calculate our new positioning based on the scaling
16193  if ( position === "static" ) {
16194  el.css({
16195  position: "relative",
16196  top: el.to.top,
16197  left: el.to.left
16198  });
16199  } else {
16200  $.each([ "top", "left" ], function( idx, pos ) {
16201  el.css( pos, function( _, str ) {
16202  var val = parseInt( str, 10 ),
16203  toRef = idx ? el.to.left : el.to.top;
16204 
16205  // if original was "auto", recalculate the new value from wrapper
16206  if ( str === "auto" ) {
16207  return toRef + "px";
16208  }
16209 
16210  return val + toRef + "px";
16211  });
16212  });
16213  }
16214  }
16215 
16216  $.effects.removeWrapper( el );
16217  done();
16218  }
16219  });
16220 
16221 };
16222 
16223 
16224 /*!
16225  * jQuery UI Effects Scale 1.11.2
16226  * http://jqueryui.com
16227  *
16228  * Copyright 2014 jQuery Foundation and other contributors
16229  * Released under the MIT license.
16230  * http://jquery.org/license
16231  *
16232  * http://api.jqueryui.com/scale-effect/
16233  */
16234 
16235 
16236 var effectScale = $.effects.effect.scale = function( o, done ) {
16237 
16238  // Create element
16239  var el = $( this ),
16240  options = $.extend( true, {}, o ),
16241  mode = $.effects.setMode( el, o.mode || "effect" ),
16242  percent = parseInt( o.percent, 10 ) ||
16243  ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
16244  direction = o.direction || "both",
16245  origin = o.origin,
16246  original = {
16247  height: el.height(),
16248  width: el.width(),
16249  outerHeight: el.outerHeight(),
16250  outerWidth: el.outerWidth()
16251  },
16252  factor = {
16253  y: direction !== "horizontal" ? (percent / 100) : 1,
16254  x: direction !== "vertical" ? (percent / 100) : 1
16255  };
16256 
16257  // We are going to pass this effect to the size effect:
16258  options.effect = "size";
16259  options.queue = false;
16260  options.complete = done;
16261 
16262  // Set default origin and restore for show/hide
16263  if ( mode !== "effect" ) {
16264  options.origin = origin || [ "middle", "center" ];
16265  options.restore = true;
16266  }
16267 
16268  options.from = o.from || ( mode === "show" ? {
16269  height: 0,
16270  width: 0,
16271  outerHeight: 0,
16272  outerWidth: 0
16273  } : original );
16274  options.to = {
16275  height: original.height * factor.y,
16276  width: original.width * factor.x,
16277  outerHeight: original.outerHeight * factor.y,
16278  outerWidth: original.outerWidth * factor.x
16279  };
16280 
16281  // Fade option to support puff
16282  if ( options.fade ) {
16283  if ( mode === "show" ) {
16284  options.from.opacity = 0;
16285  options.to.opacity = 1;
16286  }
16287  if ( mode === "hide" ) {
16288  options.from.opacity = 1;
16289  options.to.opacity = 0;
16290  }
16291  }
16292 
16293  // Animate
16294  el.effect( options );
16295 
16296 };
16297 
16298 
16299 /*!
16300  * jQuery UI Effects Puff 1.11.2
16301  * http://jqueryui.com
16302  *
16303  * Copyright 2014 jQuery Foundation and other contributors
16304  * Released under the MIT license.
16305  * http://jquery.org/license
16306  *
16307  * http://api.jqueryui.com/puff-effect/
16308  */
16309 
16310 
16311 var effectPuff = $.effects.effect.puff = function( o, done ) {
16312  var elem = $( this ),
16313  mode = $.effects.setMode( elem, o.mode || "hide" ),
16314  hide = mode === "hide",
16315  percent = parseInt( o.percent, 10 ) || 150,
16316  factor = percent / 100,
16317  original = {
16318  height: elem.height(),
16319  width: elem.width(),
16320  outerHeight: elem.outerHeight(),
16321  outerWidth: elem.outerWidth()
16322  };
16323 
16324  $.extend( o, {
16325  effect: "scale",
16326  queue: false,
16327  fade: true,
16328  mode: mode,
16329  complete: done,
16330  percent: hide ? percent : 100,
16331  from: hide ?
16332  original :
16333  {
16334  height: original.height * factor,
16335  width: original.width * factor,
16336  outerHeight: original.outerHeight * factor,
16337  outerWidth: original.outerWidth * factor
16338  }
16339  });
16340 
16341  elem.effect( o );
16342 };
16343 
16344 
16345 /*!
16346  * jQuery UI Effects Pulsate 1.11.2
16347  * http://jqueryui.com
16348  *
16349  * Copyright 2014 jQuery Foundation and other contributors
16350  * Released under the MIT license.
16351  * http://jquery.org/license
16352  *
16353  * http://api.jqueryui.com/pulsate-effect/
16354  */
16355 
16356 
16357 var effectPulsate = $.effects.effect.pulsate = function( o, done ) {
16358  var elem = $( this ),
16359  mode = $.effects.setMode( elem, o.mode || "show" ),
16360  show = mode === "show",
16361  hide = mode === "hide",
16362  showhide = ( show || mode === "hide" ),
16363 
16364  // showing or hiding leaves of the "last" animation
16365  anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
16366  duration = o.duration / anims,
16367  animateTo = 0,
16368  queue = elem.queue(),
16369  queuelen = queue.length,
16370  i;
16371 
16372  if ( show || !elem.is(":visible")) {
16373  elem.css( "opacity", 0 ).show();
16374  animateTo = 1;
16375  }
16376 
16377  // anims - 1 opacity "toggles"
16378  for ( i = 1; i < anims; i++ ) {
16379  elem.animate({
16380  opacity: animateTo
16381  }, duration, o.easing );
16382  animateTo = 1 - animateTo;
16383  }
16384 
16385  elem.animate({
16386  opacity: animateTo
16387  }, duration, o.easing);
16388 
16389  elem.queue(function() {
16390  if ( hide ) {
16391  elem.hide();
16392  }
16393  done();
16394  });
16395 
16396  // We just queued up "anims" animations, we need to put them next in the queue
16397  if ( queuelen > 1 ) {
16398  queue.splice.apply( queue,
16399  [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
16400  }
16401  elem.dequeue();
16402 };
16403 
16404 
16405 /*!
16406  * jQuery UI Effects Shake 1.11.2
16407  * http://jqueryui.com
16408  *
16409  * Copyright 2014 jQuery Foundation and other contributors
16410  * Released under the MIT license.
16411  * http://jquery.org/license
16412  *
16413  * http://api.jqueryui.com/shake-effect/
16414  */
16415 
16416 
16417 var effectShake = $.effects.effect.shake = function( o, done ) {
16418 
16419  var el = $( this ),
16420  props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
16421  mode = $.effects.setMode( el, o.mode || "effect" ),
16422  direction = o.direction || "left",
16423  distance = o.distance || 20,
16424  times = o.times || 3,
16425  anims = times * 2 + 1,
16426  speed = Math.round( o.duration / anims ),
16427  ref = (direction === "up" || direction === "down") ? "top" : "left",
16428  positiveMotion = (direction === "up" || direction === "left"),
16429  animation = {},
16430  animation1 = {},
16431  animation2 = {},
16432  i,
16433 
16434  // we will need to re-assemble the queue to stack our animations in place
16435  queue = el.queue(),
16436  queuelen = queue.length;
16437 
16438  $.effects.save( el, props );
16439  el.show();
16440  $.effects.createWrapper( el );
16441 
16442  // Animation
16443  animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
16444  animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
16445  animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
16446 
16447  // Animate
16448  el.animate( animation, speed, o.easing );
16449 
16450  // Shakes
16451  for ( i = 1; i < times; i++ ) {
16452  el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
16453  }
16454  el
16455  .animate( animation1, speed, o.easing )
16456  .animate( animation, speed / 2, o.easing )
16457  .queue(function() {
16458  if ( mode === "hide" ) {
16459  el.hide();
16460  }
16461  $.effects.restore( el, props );
16462  $.effects.removeWrapper( el );
16463  done();
16464  });
16465 
16466  // inject all the animations we just queued to be first in line (after "inprogress")
16467  if ( queuelen > 1) {
16468  queue.splice.apply( queue,
16469  [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
16470  }
16471  el.dequeue();
16472 
16473 };
16474 
16475 
16476 /*!
16477  * jQuery UI Effects Slide 1.11.2
16478  * http://jqueryui.com
16479  *
16480  * Copyright 2014 jQuery Foundation and other contributors
16481  * Released under the MIT license.
16482  * http://jquery.org/license
16483  *
16484  * http://api.jqueryui.com/slide-effect/
16485  */
16486 
16487 
16488 var effectSlide = $.effects.effect.slide = function( o, done ) {
16489 
16490  // Create element
16491  var el = $( this ),
16492  props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
16493  mode = $.effects.setMode( el, o.mode || "show" ),
16494  show = mode === "show",
16495  direction = o.direction || "left",
16496  ref = (direction === "up" || direction === "down") ? "top" : "left",
16497  positiveMotion = (direction === "up" || direction === "left"),
16498  distance,
16499  animation = {};
16500 
16501  // Adjust
16502  $.effects.save( el, props );
16503  el.show();
16504  distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
16505 
16506  $.effects.createWrapper( el ).css({
16507  overflow: "hidden"
16508  });
16509 
16510  if ( show ) {
16511  el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
16512  }
16513 
16514  // Animation
16515  animation[ ref ] = ( show ?
16516  ( positiveMotion ? "+=" : "-=") :
16517  ( positiveMotion ? "-=" : "+=")) +
16518  distance;
16519 
16520  // Animate
16521  el.animate( animation, {
16522  queue: false,
16523  duration: o.duration,
16524  easing: o.easing,
16525  complete: function() {
16526  if ( mode === "hide" ) {
16527  el.hide();
16528  }
16529  $.effects.restore( el, props );
16530  $.effects.removeWrapper( el );
16531  done();
16532  }
16533  });
16534 };
16535 
16536 
16537 /*!
16538  * jQuery UI Effects Transfer 1.11.2
16539  * http://jqueryui.com
16540  *
16541  * Copyright 2014 jQuery Foundation and other contributors
16542  * Released under the MIT license.
16543  * http://jquery.org/license
16544  *
16545  * http://api.jqueryui.com/transfer-effect/
16546  */
16547 
16548 
16549 var effectTransfer = $.effects.effect.transfer = function( o, done ) {
16550  var elem = $( this ),
16551  target = $( o.to ),
16552  targetFixed = target.css( "position" ) === "fixed",
16553  body = $("body"),
16554  fixTop = targetFixed ? body.scrollTop() : 0,
16555  fixLeft = targetFixed ? body.scrollLeft() : 0,
16556  endPosition = target.offset(),
16557  animation = {
16558  top: endPosition.top - fixTop,
16559  left: endPosition.left - fixLeft,
16560  height: target.innerHeight(),
16561  width: target.innerWidth()
16562  },
16563  startPosition = elem.offset(),
16564  transfer = $( "<div class='ui-effects-transfer'></div>" )
16565  .appendTo( document.body )
16566  .addClass( o.className )
16567  .css({
16568  top: startPosition.top - fixTop,
16569  left: startPosition.left - fixLeft,
16570  height: elem.innerHeight(),
16571  width: elem.innerWidth(),
16572  position: targetFixed ? "fixed" : "absolute"
16573  })
16574  .animate( animation, o.duration, o.easing, function() {
16575  transfer.remove();
16576  done();
16577  });
16578 };
16579 
16580 
16581 
16582 }));
jQuery fx start
Definition: jquery.js:9518
jQuery(function(){if(!jQuery.support.reliableMarginRight){jQuery.cssHooks.marginRight={get:function(elem, computed){if(computed){return jQuery.swap(elem,{"display":"inline-block"}, curCSS, [elem,"marginRight"]);}}};}if(!jQuery.support.pixelPosition &&jQuery.fn.position){jQuery.each(["top","left"], function(i, prop){jQuery.cssHooks[prop]={get:function(elem, computed){if(computed){computed=curCSS(elem, prop);return rnumnonpx.test(computed)?jQuery(elem).position()[prop]+"px":computed;}}};});}})
var a[b] f
function window
Definition: jquery.js:14
This class represents a media clip on the timeline.
Definition: effect.py:34
jQuery fn offset
Definition: jquery.js:9546
se
Definition: logger.py:77
if(window.getComputedStyle)
Definition: jquery.js:7083
jQuery fn load
Definition: jquery.js:7717
Tween prototype
Definition: jquery.js:9193
jQuery fn size
Definition: jquery.js:9760
var a[b] g
var a[b] h
jQuery fn extend({css:function(name, value){return jQuery.access(this, function(elem, name, value){var len, styles, map={}, i=0;if(jQuery.isArray(name)){styles=getStyles(elem);len=name.length;for(;i< len;i++){map[name[i]]=jQuery.css(elem, name[i], false, styles);}return map;}return value!==undefined?jQuery.style(elem, name, value):jQuery.css(elem, name);}, name, value, arguments.length > 1);}, show:function(){return showHide(this, true);}, hide:function(){return showHide(this);}, toggle:function(state){if(typeof state==="boolean"){return state?this.show():this.hide();}return this.each(function(){if(isHidden(this)){jQuery(this).show();}else{jQuery(this).hide();}});}})
log
Definition: logger.py:63
jQuery fx stop
Definition: jquery.js:9524
Definition: effect.py:1
jQuery fx timer
Definition: jquery.js:9510
function z(b)
Definition: angular.min.js:6
function undefined
Definition: jquery.js:14
document ready(function(){$(window).resize(function(){var track_offset=$("#track_controls").offset().top;var new_track_height=$(this).height()-track_offset;$("#track_controls").height(new_track_height);$("#scrolling_tracks").height(new_track_height);$('body').scope().playhead_height=$("#track-container").height();$(".playhead-line").height($('body').scope().playhead_height);});if(typeof timeline!= 'undefined'){timeline.qt_log("Qt Found!");$('body').scope().EnableQt()}else{console.log("Qt NOT Found!");}$(window).trigger('resize');$("body").keydown(function(event){if(event.which==16)$('body').scope().shift_pressed=true;});$("body").keyup(function(event){if($('body').scope().shift_pressed)$('body').scope().shift_pressed=false;});})
jQuery ajaxSettings xhr
Definition: jquery.js:8633
function Right
Definition: jquery.js:14
var a[b] e
Tween propHooks scrollTop
Definition: jquery.js:9274
d module("ngAnimate",["ng"]).directive("ngAnimateChildren"
var dragging
Definition: clip.js:31
jQuery easing
Definition: jquery.js:9478
jQuery each(["height","width"], function(i, name){jQuery.cssHooks[name]={get:function(elem, computed, extra){if(computed){return elem.offsetWidth===0 &&rdisplayswap.test(jQuery.css(elem,"display"))?jQuery.swap(elem, cssShow, function(){return getWidthOrHeight(elem, name, extra);}):getWidthOrHeight(elem, name, extra);}}, set:function(elem, value, extra){var styles=extra &&getStyles(elem);return setPositiveNumber(elem, value, extra?augmentWidthOrHeight(elem, name, extra, jQuery.support.boxSizing &&jQuery.css(elem,"boxSizing", false, styles)==="border-box", styles):0);}};})
function Left
Definition: jquery.js:14
function d
var rhash
Definition: jquery.js:7593
function W
Definition: angular.min.js:6
function Bottom
Definition: jquery.js:14
jQuery fx step
Definition: jquery.js:9537
jQuery fx
Definition: jquery.js:9488
b addClass("collapse")}