[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/lib/scripts/jquery/ -> jquery-ui.js (source)

   1  /*! jQuery UI - v1.11.4 - 2015-03-11
   2  * http://jqueryui.com
   3  * Includes: core.js, widget.js, mouse.js, position.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, draggable.js, droppable.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, menu.js, progressbar.js, resizable.js, selectable.js, selectmenu.js, slider.js, sortable.js, spinner.js, tabs.js, tooltip.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.4
  19   * http://jqueryui.com
  20   *
  21   * Copyright 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.4",
  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.4
 313   * http://jqueryui.com
 314   *
 315   * Copyright 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          if ( isMethodCall ) {
 494              this.each(function() {
 495                  var methodValue,
 496                      instance = $.data( this, fullName );
 497                  if ( options === "instance" ) {
 498                      returnValue = instance;
 499                      return false;
 500                  }
 501                  if ( !instance ) {
 502                      return $.error( "cannot call methods on " + name + " prior to initialization; " +
 503                          "attempted to call method '" + options + "'" );
 504                  }
 505                  if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
 506                      return $.error( "no such method '" + options + "' for " + name + " widget instance" );
 507                  }
 508                  methodValue = instance[ options ].apply( instance, args );
 509                  if ( methodValue !== instance && methodValue !== undefined ) {
 510                      returnValue = methodValue && methodValue.jquery ?
 511                          returnValue.pushStack( methodValue.get() ) :
 512                          methodValue;
 513                      return false;
 514                  }
 515              });
 516          } else {
 517  
 518              // Allow multiple hashes to be passed on init
 519              if ( args.length ) {
 520                  options = $.widget.extend.apply( null, [ options ].concat(args) );
 521              }
 522  
 523              this.each(function() {
 524                  var instance = $.data( this, fullName );
 525                  if ( instance ) {
 526                      instance.option( options || {} );
 527                      if ( instance._init ) {
 528                          instance._init();
 529                      }
 530                  } else {
 531                      $.data( this, fullName, new object( options, this ) );
 532                  }
 533              });
 534          }
 535  
 536          return returnValue;
 537      };
 538  };
 539  
 540  $.Widget = function( /* options, element */ ) {};
 541  $.Widget._childConstructors = [];
 542  
 543  $.Widget.prototype = {
 544      widgetName: "widget",
 545      widgetEventPrefix: "",
 546      defaultElement: "<div>",
 547      options: {
 548          disabled: false,
 549  
 550          // callbacks
 551          create: null
 552      },
 553      _createWidget: function( options, element ) {
 554          element = $( element || this.defaultElement || this )[ 0 ];
 555          this.element = $( element );
 556          this.uuid = widget_uuid++;
 557          this.eventNamespace = "." + this.widgetName + this.uuid;
 558  
 559          this.bindings = $();
 560          this.hoverable = $();
 561          this.focusable = $();
 562  
 563          if ( element !== this ) {
 564              $.data( element, this.widgetFullName, this );
 565              this._on( true, this.element, {
 566                  remove: function( event ) {
 567                      if ( event.target === element ) {
 568                          this.destroy();
 569                      }
 570                  }
 571              });
 572              this.document = $( element.style ?
 573                  // element within the document
 574                  element.ownerDocument :
 575                  // element is window or document
 576                  element.document || element );
 577              this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
 578          }
 579  
 580          this.options = $.widget.extend( {},
 581              this.options,
 582              this._getCreateOptions(),
 583              options );
 584  
 585          this._create();
 586          this._trigger( "create", null, this._getCreateEventData() );
 587          this._init();
 588      },
 589      _getCreateOptions: $.noop,
 590      _getCreateEventData: $.noop,
 591      _create: $.noop,
 592      _init: $.noop,
 593  
 594      destroy: function() {
 595          this._destroy();
 596          // we can probably remove the unbind calls in 2.0
 597          // all event bindings should go through this._on()
 598          this.element
 599              .unbind( this.eventNamespace )
 600              .removeData( this.widgetFullName )
 601              // support: jquery <1.6.3
 602              // http://bugs.jquery.com/ticket/9413
 603              .removeData( $.camelCase( this.widgetFullName ) );
 604          this.widget()
 605              .unbind( this.eventNamespace )
 606              .removeAttr( "aria-disabled" )
 607              .removeClass(
 608                  this.widgetFullName + "-disabled " +
 609                  "ui-state-disabled" );
 610  
 611          // clean up events and states
 612          this.bindings.unbind( this.eventNamespace );
 613          this.hoverable.removeClass( "ui-state-hover" );
 614          this.focusable.removeClass( "ui-state-focus" );
 615      },
 616      _destroy: $.noop,
 617  
 618      widget: function() {
 619          return this.element;
 620      },
 621  
 622      option: function( key, value ) {
 623          var options = key,
 624              parts,
 625              curOption,
 626              i;
 627  
 628          if ( arguments.length === 0 ) {
 629              // don't return a reference to the internal hash
 630              return $.widget.extend( {}, this.options );
 631          }
 632  
 633          if ( typeof key === "string" ) {
 634              // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
 635              options = {};
 636              parts = key.split( "." );
 637              key = parts.shift();
 638              if ( parts.length ) {
 639                  curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
 640                  for ( i = 0; i < parts.length - 1; i++ ) {
 641                      curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
 642                      curOption = curOption[ parts[ i ] ];
 643                  }
 644                  key = parts.pop();
 645                  if ( arguments.length === 1 ) {
 646                      return curOption[ key ] === undefined ? null : curOption[ key ];
 647                  }
 648                  curOption[ key ] = value;
 649              } else {
 650                  if ( arguments.length === 1 ) {
 651                      return this.options[ key ] === undefined ? null : this.options[ key ];
 652                  }
 653                  options[ key ] = value;
 654              }
 655          }
 656  
 657          this._setOptions( options );
 658  
 659          return this;
 660      },
 661      _setOptions: function( options ) {
 662          var key;
 663  
 664          for ( key in options ) {
 665              this._setOption( key, options[ key ] );
 666          }
 667  
 668          return this;
 669      },
 670      _setOption: function( key, value ) {
 671          this.options[ key ] = value;
 672  
 673          if ( key === "disabled" ) {
 674              this.widget()
 675                  .toggleClass( this.widgetFullName + "-disabled", !!value );
 676  
 677              // If the widget is becoming disabled, then nothing is interactive
 678              if ( value ) {
 679                  this.hoverable.removeClass( "ui-state-hover" );
 680                  this.focusable.removeClass( "ui-state-focus" );
 681              }
 682          }
 683  
 684          return this;
 685      },
 686  
 687      enable: function() {
 688          return this._setOptions({ disabled: false });
 689      },
 690      disable: function() {
 691          return this._setOptions({ disabled: true });
 692      },
 693  
 694      _on: function( suppressDisabledCheck, element, handlers ) {
 695          var delegateElement,
 696              instance = this;
 697  
 698          // no suppressDisabledCheck flag, shuffle arguments
 699          if ( typeof suppressDisabledCheck !== "boolean" ) {
 700              handlers = element;
 701              element = suppressDisabledCheck;
 702              suppressDisabledCheck = false;
 703          }
 704  
 705          // no element argument, shuffle and use this.element
 706          if ( !handlers ) {
 707              handlers = element;
 708              element = this.element;
 709              delegateElement = this.widget();
 710          } else {
 711              element = delegateElement = $( element );
 712              this.bindings = this.bindings.add( element );
 713          }
 714  
 715          $.each( handlers, function( event, handler ) {
 716  			function handlerProxy() {
 717                  // allow widgets to customize the disabled handling
 718                  // - disabled as an array instead of boolean
 719                  // - disabled class as method for disabling individual parts
 720                  if ( !suppressDisabledCheck &&
 721                          ( instance.options.disabled === true ||
 722                              $( this ).hasClass( "ui-state-disabled" ) ) ) {
 723                      return;
 724                  }
 725                  return ( typeof handler === "string" ? instance[ handler ] : handler )
 726                      .apply( instance, arguments );
 727              }
 728  
 729              // copy the guid so direct unbinding works
 730              if ( typeof handler !== "string" ) {
 731                  handlerProxy.guid = handler.guid =
 732                      handler.guid || handlerProxy.guid || $.guid++;
 733              }
 734  
 735              var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
 736                  eventName = match[1] + instance.eventNamespace,
 737                  selector = match[2];
 738              if ( selector ) {
 739                  delegateElement.delegate( selector, eventName, handlerProxy );
 740              } else {
 741                  element.bind( eventName, handlerProxy );
 742              }
 743          });
 744      },
 745  
 746      _off: function( element, eventName ) {
 747          eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
 748              this.eventNamespace;
 749          element.unbind( eventName ).undelegate( eventName );
 750  
 751          // Clear the stack to avoid memory leaks (#10056)
 752          this.bindings = $( this.bindings.not( element ).get() );
 753          this.focusable = $( this.focusable.not( element ).get() );
 754          this.hoverable = $( this.hoverable.not( element ).get() );
 755      },
 756  
 757      _delay: function( handler, delay ) {
 758  		function handlerProxy() {
 759              return ( typeof handler === "string" ? instance[ handler ] : handler )
 760                  .apply( instance, arguments );
 761          }
 762          var instance = this;
 763          return setTimeout( handlerProxy, delay || 0 );
 764      },
 765  
 766      _hoverable: function( element ) {
 767          this.hoverable = this.hoverable.add( element );
 768          this._on( element, {
 769              mouseenter: function( event ) {
 770                  $( event.currentTarget ).addClass( "ui-state-hover" );
 771              },
 772              mouseleave: function( event ) {
 773                  $( event.currentTarget ).removeClass( "ui-state-hover" );
 774              }
 775          });
 776      },
 777  
 778      _focusable: function( element ) {
 779          this.focusable = this.focusable.add( element );
 780          this._on( element, {
 781              focusin: function( event ) {
 782                  $( event.currentTarget ).addClass( "ui-state-focus" );
 783              },
 784              focusout: function( event ) {
 785                  $( event.currentTarget ).removeClass( "ui-state-focus" );
 786              }
 787          });
 788      },
 789  
 790      _trigger: function( type, event, data ) {
 791          var prop, orig,
 792              callback = this.options[ type ];
 793  
 794          data = data || {};
 795          event = $.Event( event );
 796          event.type = ( type === this.widgetEventPrefix ?
 797              type :
 798              this.widgetEventPrefix + type ).toLowerCase();
 799          // the original event may come from any element
 800          // so we need to reset the target on the new event
 801          event.target = this.element[ 0 ];
 802  
 803          // copy original event properties over to the new event
 804          orig = event.originalEvent;
 805          if ( orig ) {
 806              for ( prop in orig ) {
 807                  if ( !( prop in event ) ) {
 808                      event[ prop ] = orig[ prop ];
 809                  }
 810              }
 811          }
 812  
 813          this.element.trigger( event, data );
 814          return !( $.isFunction( callback ) &&
 815              callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
 816              event.isDefaultPrevented() );
 817      }
 818  };
 819  
 820  $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
 821      $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
 822          if ( typeof options === "string" ) {
 823              options = { effect: options };
 824          }
 825          var hasOptions,
 826              effectName = !options ?
 827                  method :
 828                  options === true || typeof options === "number" ?
 829                      defaultEffect :
 830                      options.effect || defaultEffect;
 831          options = options || {};
 832          if ( typeof options === "number" ) {
 833              options = { duration: options };
 834          }
 835          hasOptions = !$.isEmptyObject( options );
 836          options.complete = callback;
 837          if ( options.delay ) {
 838              element.delay( options.delay );
 839          }
 840          if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
 841              element[ method ]( options );
 842          } else if ( effectName !== method && element[ effectName ] ) {
 843              element[ effectName ]( options.duration, options.easing, callback );
 844          } else {
 845              element.queue(function( next ) {
 846                  $( this )[ method ]();
 847                  if ( callback ) {
 848                      callback.call( element[ 0 ] );
 849                  }
 850                  next();
 851              });
 852          }
 853      };
 854  });
 855  
 856  var widget = $.widget;
 857  
 858  
 859  /*!
 860   * jQuery UI Mouse 1.11.4
 861   * http://jqueryui.com
 862   *
 863   * Copyright jQuery Foundation and other contributors
 864   * Released under the MIT license.
 865   * http://jquery.org/license
 866   *
 867   * http://api.jqueryui.com/mouse/
 868   */
 869  
 870  
 871  var mouseHandled = false;
 872  $( document ).mouseup( function() {
 873      mouseHandled = false;
 874  });
 875  
 876  var mouse = $.widget("ui.mouse", {
 877      version: "1.11.4",
 878      options: {
 879          cancel: "input,textarea,button,select,option",
 880          distance: 1,
 881          delay: 0
 882      },
 883      _mouseInit: function() {
 884          var that = this;
 885  
 886          this.element
 887              .bind("mousedown." + this.widgetName, function(event) {
 888                  return that._mouseDown(event);
 889              })
 890              .bind("click." + this.widgetName, function(event) {
 891                  if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
 892                      $.removeData(event.target, that.widgetName + ".preventClickEvent");
 893                      event.stopImmediatePropagation();
 894                      return false;
 895                  }
 896              });
 897  
 898          this.started = false;
 899      },
 900  
 901      // TODO: make sure destroying one instance of mouse doesn't mess with
 902      // other instances of mouse
 903      _mouseDestroy: function() {
 904          this.element.unbind("." + this.widgetName);
 905          if ( this._mouseMoveDelegate ) {
 906              this.document
 907                  .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
 908                  .unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
 909          }
 910      },
 911  
 912      _mouseDown: function(event) {
 913          // don't let more than one widget handle mouseStart
 914          if ( mouseHandled ) {
 915              return;
 916          }
 917  
 918          this._mouseMoved = false;
 919  
 920          // we may have missed mouseup (out of window)
 921          (this._mouseStarted && this._mouseUp(event));
 922  
 923          this._mouseDownEvent = event;
 924  
 925          var that = this,
 926              btnIsLeft = (event.which === 1),
 927              // event.target.nodeName works around a bug in IE 8 with
 928              // disabled inputs (#7620)
 929              elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
 930          if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
 931              return true;
 932          }
 933  
 934          this.mouseDelayMet = !this.options.delay;
 935          if (!this.mouseDelayMet) {
 936              this._mouseDelayTimer = setTimeout(function() {
 937                  that.mouseDelayMet = true;
 938              }, this.options.delay);
 939          }
 940  
 941          if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
 942              this._mouseStarted = (this._mouseStart(event) !== false);
 943              if (!this._mouseStarted) {
 944                  event.preventDefault();
 945                  return true;
 946              }
 947          }
 948  
 949          // Click event may never have fired (Gecko & Opera)
 950          if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
 951              $.removeData(event.target, this.widgetName + ".preventClickEvent");
 952          }
 953  
 954          // these delegates are required to keep context
 955          this._mouseMoveDelegate = function(event) {
 956              return that._mouseMove(event);
 957          };
 958          this._mouseUpDelegate = function(event) {
 959              return that._mouseUp(event);
 960          };
 961  
 962          this.document
 963              .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
 964              .bind( "mouseup." + this.widgetName, this._mouseUpDelegate );
 965  
 966          event.preventDefault();
 967  
 968          mouseHandled = true;
 969          return true;
 970      },
 971  
 972      _mouseMove: function(event) {
 973          // Only check for mouseups outside the document if you've moved inside the document
 974          // at least once. This prevents the firing of mouseup in the case of IE<9, which will
 975          // fire a mousemove event if content is placed under the cursor. See #7778
 976          // Support: IE <9
 977          if ( this._mouseMoved ) {
 978              // IE mouseup check - mouseup happened when mouse was out of window
 979              if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
 980                  return this._mouseUp(event);
 981  
 982              // Iframe mouseup check - mouseup occurred in another document
 983              } else if ( !event.which ) {
 984                  return this._mouseUp( event );
 985              }
 986          }
 987  
 988          if ( event.which || event.button ) {
 989              this._mouseMoved = true;
 990          }
 991  
 992          if (this._mouseStarted) {
 993              this._mouseDrag(event);
 994              return event.preventDefault();
 995          }
 996  
 997          if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
 998              this._mouseStarted =
 999                  (this._mouseStart(this._mouseDownEvent, event) !== false);
1000              (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
1001          }
1002  
1003          return !this._mouseStarted;
1004      },
1005  
1006      _mouseUp: function(event) {
1007          this.document
1008              .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1009              .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );
1010  
1011          if (this._mouseStarted) {
1012              this._mouseStarted = false;
1013  
1014              if (event.target === this._mouseDownEvent.target) {
1015                  $.data(event.target, this.widgetName + ".preventClickEvent", true);
1016              }
1017  
1018              this._mouseStop(event);
1019          }
1020  
1021          mouseHandled = false;
1022          return false;
1023      },
1024  
1025      _mouseDistanceMet: function(event) {
1026          return (Math.max(
1027                  Math.abs(this._mouseDownEvent.pageX - event.pageX),
1028                  Math.abs(this._mouseDownEvent.pageY - event.pageY)
1029              ) >= this.options.distance
1030          );
1031      },
1032  
1033      _mouseDelayMet: function(/* event */) {
1034          return this.mouseDelayMet;
1035      },
1036  
1037      // These are placeholder methods, to be overriden by extending plugin
1038      _mouseStart: function(/* event */) {},
1039      _mouseDrag: function(/* event */) {},
1040      _mouseStop: function(/* event */) {},
1041      _mouseCapture: function(/* event */) { return true; }
1042  });
1043  
1044  
1045  /*!
1046   * jQuery UI Position 1.11.4
1047   * http://jqueryui.com
1048   *
1049   * Copyright jQuery Foundation and other contributors
1050   * Released under the MIT license.
1051   * http://jquery.org/license
1052   *
1053   * http://api.jqueryui.com/position/
1054   */
1055  
1056  (function() {
1057  
1058  $.ui = $.ui || {};
1059  
1060  var cachedScrollbarWidth, supportsOffsetFractions,
1061      max = Math.max,
1062      abs = Math.abs,
1063      round = Math.round,
1064      rhorizontal = /left|center|right/,
1065      rvertical = /top|center|bottom/,
1066      roffset = /[\+\-]\d+(\.[\d]+)?%?/,
1067      rposition = /^\w+/,
1068      rpercent = /%$/,
1069      _position = $.fn.position;
1070  
1071  function getOffsets( offsets, width, height ) {
1072      return [
1073          parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1074          parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1075      ];
1076  }
1077  
1078  function parseCss( element, property ) {
1079      return parseInt( $.css( element, property ), 10 ) || 0;
1080  }
1081  
1082  function getDimensions( elem ) {
1083      var raw = elem[0];
1084      if ( raw.nodeType === 9 ) {
1085          return {
1086              width: elem.width(),
1087              height: elem.height(),
1088              offset: { top: 0, left: 0 }
1089          };
1090      }
1091      if ( $.isWindow( raw ) ) {
1092          return {
1093              width: elem.width(),
1094              height: elem.height(),
1095              offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
1096          };
1097      }
1098      if ( raw.preventDefault ) {
1099          return {
1100              width: 0,
1101              height: 0,
1102              offset: { top: raw.pageY, left: raw.pageX }
1103          };
1104      }
1105      return {
1106          width: elem.outerWidth(),
1107          height: elem.outerHeight(),
1108          offset: elem.offset()
1109      };
1110  }
1111  
1112  $.position = {
1113      scrollbarWidth: function() {
1114          if ( cachedScrollbarWidth !== undefined ) {
1115              return cachedScrollbarWidth;
1116          }
1117          var w1, w2,
1118              div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1119              innerDiv = div.children()[0];
1120  
1121          $( "body" ).append( div );
1122          w1 = innerDiv.offsetWidth;
1123          div.css( "overflow", "scroll" );
1124  
1125          w2 = innerDiv.offsetWidth;
1126  
1127          if ( w1 === w2 ) {
1128              w2 = div[0].clientWidth;
1129          }
1130  
1131          div.remove();
1132  
1133          return (cachedScrollbarWidth = w1 - w2);
1134      },
1135      getScrollInfo: function( within ) {
1136          var overflowX = within.isWindow || within.isDocument ? "" :
1137                  within.element.css( "overflow-x" ),
1138              overflowY = within.isWindow || within.isDocument ? "" :
1139                  within.element.css( "overflow-y" ),
1140              hasOverflowX = overflowX === "scroll" ||
1141                  ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1142              hasOverflowY = overflowY === "scroll" ||
1143                  ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1144          return {
1145              width: hasOverflowY ? $.position.scrollbarWidth() : 0,
1146              height: hasOverflowX ? $.position.scrollbarWidth() : 0
1147          };
1148      },
1149      getWithinInfo: function( element ) {
1150          var withinElement = $( element || window ),
1151              isWindow = $.isWindow( withinElement[0] ),
1152              isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
1153          return {
1154              element: withinElement,
1155              isWindow: isWindow,
1156              isDocument: isDocument,
1157              offset: withinElement.offset() || { left: 0, top: 0 },
1158              scrollLeft: withinElement.scrollLeft(),
1159              scrollTop: withinElement.scrollTop(),
1160  
1161              // support: jQuery 1.6.x
1162              // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
1163              width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
1164              height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
1165          };
1166      }
1167  };
1168  
1169  $.fn.position = function( options ) {
1170      if ( !options || !options.of ) {
1171          return _position.apply( this, arguments );
1172      }
1173  
1174      // make a copy, we don't want to modify arguments
1175      options = $.extend( {}, options );
1176  
1177      var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
1178          target = $( options.of ),
1179          within = $.position.getWithinInfo( options.within ),
1180          scrollInfo = $.position.getScrollInfo( within ),
1181          collision = ( options.collision || "flip" ).split( " " ),
1182          offsets = {};
1183  
1184      dimensions = getDimensions( target );
1185      if ( target[0].preventDefault ) {
1186          // force left top to allow flipping
1187          options.at = "left top";
1188      }
1189      targetWidth = dimensions.width;
1190      targetHeight = dimensions.height;
1191      targetOffset = dimensions.offset;
1192      // clone to reuse original targetOffset later
1193      basePosition = $.extend( {}, targetOffset );
1194  
1195      // force my and at to have valid horizontal and vertical positions
1196      // if a value is missing or invalid, it will be converted to center
1197      $.each( [ "my", "at" ], function() {
1198          var pos = ( options[ this ] || "" ).split( " " ),
1199              horizontalOffset,
1200              verticalOffset;
1201  
1202          if ( pos.length === 1) {
1203              pos = rhorizontal.test( pos[ 0 ] ) ?
1204                  pos.concat( [ "center" ] ) :
1205                  rvertical.test( pos[ 0 ] ) ?
1206                      [ "center" ].concat( pos ) :
1207                      [ "center", "center" ];
1208          }
1209          pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1210          pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1211  
1212          // calculate offsets
1213          horizontalOffset = roffset.exec( pos[ 0 ] );
1214          verticalOffset = roffset.exec( pos[ 1 ] );
1215          offsets[ this ] = [
1216              horizontalOffset ? horizontalOffset[ 0 ] : 0,
1217              verticalOffset ? verticalOffset[ 0 ] : 0
1218          ];
1219  
1220          // reduce to just the positions without the offsets
1221          options[ this ] = [
1222              rposition.exec( pos[ 0 ] )[ 0 ],
1223              rposition.exec( pos[ 1 ] )[ 0 ]
1224          ];
1225      });
1226  
1227      // normalize collision option
1228      if ( collision.length === 1 ) {
1229          collision[ 1 ] = collision[ 0 ];
1230      }
1231  
1232      if ( options.at[ 0 ] === "right" ) {
1233          basePosition.left += targetWidth;
1234      } else if ( options.at[ 0 ] === "center" ) {
1235          basePosition.left += targetWidth / 2;
1236      }
1237  
1238      if ( options.at[ 1 ] === "bottom" ) {
1239          basePosition.top += targetHeight;
1240      } else if ( options.at[ 1 ] === "center" ) {
1241          basePosition.top += targetHeight / 2;
1242      }
1243  
1244      atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1245      basePosition.left += atOffset[ 0 ];
1246      basePosition.top += atOffset[ 1 ];
1247  
1248      return this.each(function() {
1249          var collisionPosition, using,
1250              elem = $( this ),
1251              elemWidth = elem.outerWidth(),
1252              elemHeight = elem.outerHeight(),
1253              marginLeft = parseCss( this, "marginLeft" ),
1254              marginTop = parseCss( this, "marginTop" ),
1255              collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1256              collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1257              position = $.extend( {}, basePosition ),
1258              myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1259  
1260          if ( options.my[ 0 ] === "right" ) {
1261              position.left -= elemWidth;
1262          } else if ( options.my[ 0 ] === "center" ) {
1263              position.left -= elemWidth / 2;
1264          }
1265  
1266          if ( options.my[ 1 ] === "bottom" ) {
1267              position.top -= elemHeight;
1268          } else if ( options.my[ 1 ] === "center" ) {
1269              position.top -= elemHeight / 2;
1270          }
1271  
1272          position.left += myOffset[ 0 ];
1273          position.top += myOffset[ 1 ];
1274  
1275          // if the browser doesn't support fractions, then round for consistent results
1276          if ( !supportsOffsetFractions ) {
1277              position.left = round( position.left );
1278              position.top = round( position.top );
1279          }
1280  
1281          collisionPosition = {
1282              marginLeft: marginLeft,
1283              marginTop: marginTop
1284          };
1285  
1286          $.each( [ "left", "top" ], function( i, dir ) {
1287              if ( $.ui.position[ collision[ i ] ] ) {
1288                  $.ui.position[ collision[ i ] ][ dir ]( position, {
1289                      targetWidth: targetWidth,
1290                      targetHeight: targetHeight,
1291                      elemWidth: elemWidth,
1292                      elemHeight: elemHeight,
1293                      collisionPosition: collisionPosition,
1294                      collisionWidth: collisionWidth,
1295                      collisionHeight: collisionHeight,
1296                      offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1297                      my: options.my,
1298                      at: options.at,
1299                      within: within,
1300                      elem: elem
1301                  });
1302              }
1303          });
1304  
1305          if ( options.using ) {
1306              // adds feedback as second argument to using callback, if present
1307              using = function( props ) {
1308                  var left = targetOffset.left - position.left,
1309                      right = left + targetWidth - elemWidth,
1310                      top = targetOffset.top - position.top,
1311                      bottom = top + targetHeight - elemHeight,
1312                      feedback = {
1313                          target: {
1314                              element: target,
1315                              left: targetOffset.left,
1316                              top: targetOffset.top,
1317                              width: targetWidth,
1318                              height: targetHeight
1319                          },
1320                          element: {
1321                              element: elem,
1322                              left: position.left,
1323                              top: position.top,
1324                              width: elemWidth,
1325                              height: elemHeight
1326                          },
1327                          horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1328                          vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1329                      };
1330                  if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1331                      feedback.horizontal = "center";
1332                  }
1333                  if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1334                      feedback.vertical = "middle";
1335                  }
1336                  if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1337                      feedback.important = "horizontal";
1338                  } else {
1339                      feedback.important = "vertical";
1340                  }
1341                  options.using.call( this, props, feedback );
1342              };
1343          }
1344  
1345          elem.offset( $.extend( position, { using: using } ) );
1346      });
1347  };
1348  
1349  $.ui.position = {
1350      fit: {
1351          left: function( position, data ) {
1352              var within = data.within,
1353                  withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1354                  outerWidth = within.width,
1355                  collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1356                  overLeft = withinOffset - collisionPosLeft,
1357                  overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1358                  newOverRight;
1359  
1360              // element is wider than within
1361              if ( data.collisionWidth > outerWidth ) {
1362                  // element is initially over the left side of within
1363                  if ( overLeft > 0 && overRight <= 0 ) {
1364                      newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1365                      position.left += overLeft - newOverRight;
1366                  // element is initially over right side of within
1367                  } else if ( overRight > 0 && overLeft <= 0 ) {
1368                      position.left = withinOffset;
1369                  // element is initially over both left and right sides of within
1370                  } else {
1371                      if ( overLeft > overRight ) {
1372                          position.left = withinOffset + outerWidth - data.collisionWidth;
1373                      } else {
1374                          position.left = withinOffset;
1375                      }
1376                  }
1377              // too far left -> align with left edge
1378              } else if ( overLeft > 0 ) {
1379                  position.left += overLeft;
1380              // too far right -> align with right edge
1381              } else if ( overRight > 0 ) {
1382                  position.left -= overRight;
1383              // adjust based on position and margin
1384              } else {
1385                  position.left = max( position.left - collisionPosLeft, position.left );
1386              }
1387          },
1388          top: function( position, data ) {
1389              var within = data.within,
1390                  withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1391                  outerHeight = data.within.height,
1392                  collisionPosTop = position.top - data.collisionPosition.marginTop,
1393                  overTop = withinOffset - collisionPosTop,
1394                  overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1395                  newOverBottom;
1396  
1397              // element is taller than within
1398              if ( data.collisionHeight > outerHeight ) {
1399                  // element is initially over the top of within
1400                  if ( overTop > 0 && overBottom <= 0 ) {
1401                      newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1402                      position.top += overTop - newOverBottom;
1403                  // element is initially over bottom of within
1404                  } else if ( overBottom > 0 && overTop <= 0 ) {
1405                      position.top = withinOffset;
1406                  // element is initially over both top and bottom of within
1407                  } else {
1408                      if ( overTop > overBottom ) {
1409                          position.top = withinOffset + outerHeight - data.collisionHeight;
1410                      } else {
1411                          position.top = withinOffset;
1412                      }
1413                  }
1414              // too far up -> align with top
1415              } else if ( overTop > 0 ) {
1416                  position.top += overTop;
1417              // too far down -> align with bottom edge
1418              } else if ( overBottom > 0 ) {
1419                  position.top -= overBottom;
1420              // adjust based on position and margin
1421              } else {
1422                  position.top = max( position.top - collisionPosTop, position.top );
1423              }
1424          }
1425      },
1426      flip: {
1427          left: function( position, data ) {
1428              var within = data.within,
1429                  withinOffset = within.offset.left + within.scrollLeft,
1430                  outerWidth = within.width,
1431                  offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1432                  collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1433                  overLeft = collisionPosLeft - offsetLeft,
1434                  overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1435                  myOffset = data.my[ 0 ] === "left" ?
1436                      -data.elemWidth :
1437                      data.my[ 0 ] === "right" ?
1438                          data.elemWidth :
1439                          0,
1440                  atOffset = data.at[ 0 ] === "left" ?
1441                      data.targetWidth :
1442                      data.at[ 0 ] === "right" ?
1443                          -data.targetWidth :
1444                          0,
1445                  offset = -2 * data.offset[ 0 ],
1446                  newOverRight,
1447                  newOverLeft;
1448  
1449              if ( overLeft < 0 ) {
1450                  newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1451                  if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1452                      position.left += myOffset + atOffset + offset;
1453                  }
1454              } else if ( overRight > 0 ) {
1455                  newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1456                  if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1457                      position.left += myOffset + atOffset + offset;
1458                  }
1459              }
1460          },
1461          top: function( position, data ) {
1462              var within = data.within,
1463                  withinOffset = within.offset.top + within.scrollTop,
1464                  outerHeight = within.height,
1465                  offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1466                  collisionPosTop = position.top - data.collisionPosition.marginTop,
1467                  overTop = collisionPosTop - offsetTop,
1468                  overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1469                  top = data.my[ 1 ] === "top",
1470                  myOffset = top ?
1471                      -data.elemHeight :
1472                      data.my[ 1 ] === "bottom" ?
1473                          data.elemHeight :
1474                          0,
1475                  atOffset = data.at[ 1 ] === "top" ?
1476                      data.targetHeight :
1477                      data.at[ 1 ] === "bottom" ?
1478                          -data.targetHeight :
1479                          0,
1480                  offset = -2 * data.offset[ 1 ],
1481                  newOverTop,
1482                  newOverBottom;
1483              if ( overTop < 0 ) {
1484                  newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1485                  if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1486                      position.top += myOffset + atOffset + offset;
1487                  }
1488              } else if ( overBottom > 0 ) {
1489                  newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1490                  if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1491                      position.top += myOffset + atOffset + offset;
1492                  }
1493              }
1494          }
1495      },
1496      flipfit: {
1497          left: function() {
1498              $.ui.position.flip.left.apply( this, arguments );
1499              $.ui.position.fit.left.apply( this, arguments );
1500          },
1501          top: function() {
1502              $.ui.position.flip.top.apply( this, arguments );
1503              $.ui.position.fit.top.apply( this, arguments );
1504          }
1505      }
1506  };
1507  
1508  // fraction support test
1509  (function() {
1510      var testElement, testElementParent, testElementStyle, offsetLeft, i,
1511          body = document.getElementsByTagName( "body" )[ 0 ],
1512          div = document.createElement( "div" );
1513  
1514      //Create a "fake body" for testing based on method used in jQuery.support
1515      testElement = document.createElement( body ? "div" : "body" );
1516      testElementStyle = {
1517          visibility: "hidden",
1518          width: 0,
1519          height: 0,
1520          border: 0,
1521          margin: 0,
1522          background: "none"
1523      };
1524      if ( body ) {
1525          $.extend( testElementStyle, {
1526              position: "absolute",
1527              left: "-1000px",
1528              top: "-1000px"
1529          });
1530      }
1531      for ( i in testElementStyle ) {
1532          testElement.style[ i ] = testElementStyle[ i ];
1533      }
1534      testElement.appendChild( div );
1535      testElementParent = body || document.documentElement;
1536      testElementParent.insertBefore( testElement, testElementParent.firstChild );
1537  
1538      div.style.cssText = "position: absolute; left: 10.7432222px;";
1539  
1540      offsetLeft = $( div ).offset().left;
1541      supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
1542  
1543      testElement.innerHTML = "";
1544      testElementParent.removeChild( testElement );
1545  })();
1546  
1547  })();
1548  
1549  var position = $.ui.position;
1550  
1551  
1552  /*!
1553   * jQuery UI Accordion 1.11.4
1554   * http://jqueryui.com
1555   *
1556   * Copyright jQuery Foundation and other contributors
1557   * Released under the MIT license.
1558   * http://jquery.org/license
1559   *
1560   * http://api.jqueryui.com/accordion/
1561   */
1562  
1563  
1564  var accordion = $.widget( "ui.accordion", {
1565      version: "1.11.4",
1566      options: {
1567          active: 0,
1568          animate: {},
1569          collapsible: false,
1570          event: "click",
1571          header: "> li > :first-child,> :not(li):even",
1572          heightStyle: "auto",
1573          icons: {
1574              activeHeader: "ui-icon-triangle-1-s",
1575              header: "ui-icon-triangle-1-e"
1576          },
1577  
1578          // callbacks
1579          activate: null,
1580          beforeActivate: null
1581      },
1582  
1583      hideProps: {
1584          borderTopWidth: "hide",
1585          borderBottomWidth: "hide",
1586          paddingTop: "hide",
1587          paddingBottom: "hide",
1588          height: "hide"
1589      },
1590  
1591      showProps: {
1592          borderTopWidth: "show",
1593          borderBottomWidth: "show",
1594          paddingTop: "show",
1595          paddingBottom: "show",
1596          height: "show"
1597      },
1598  
1599      _create: function() {
1600          var options = this.options;
1601          this.prevShow = this.prevHide = $();
1602          this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
1603              // ARIA
1604              .attr( "role", "tablist" );
1605  
1606          // don't allow collapsible: false and active: false / null
1607          if ( !options.collapsible && (options.active === false || options.active == null) ) {
1608              options.active = 0;
1609          }
1610  
1611          this._processPanels();
1612          // handle negative values
1613          if ( options.active < 0 ) {
1614              options.active += this.headers.length;
1615          }
1616          this._refresh();
1617      },
1618  
1619      _getCreateEventData: function() {
1620          return {
1621              header: this.active,
1622              panel: !this.active.length ? $() : this.active.next()
1623          };
1624      },
1625  
1626      _createIcons: function() {
1627          var icons = this.options.icons;
1628          if ( icons ) {
1629              $( "<span>" )
1630                  .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
1631                  .prependTo( this.headers );
1632              this.active.children( ".ui-accordion-header-icon" )
1633                  .removeClass( icons.header )
1634                  .addClass( icons.activeHeader );
1635              this.headers.addClass( "ui-accordion-icons" );
1636          }
1637      },
1638  
1639      _destroyIcons: function() {
1640          this.headers
1641              .removeClass( "ui-accordion-icons" )
1642              .children( ".ui-accordion-header-icon" )
1643                  .remove();
1644      },
1645  
1646      _destroy: function() {
1647          var contents;
1648  
1649          // clean up main element
1650          this.element
1651              .removeClass( "ui-accordion ui-widget ui-helper-reset" )
1652              .removeAttr( "role" );
1653  
1654          // clean up headers
1655          this.headers
1656              .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
1657                  "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
1658              .removeAttr( "role" )
1659              .removeAttr( "aria-expanded" )
1660              .removeAttr( "aria-selected" )
1661              .removeAttr( "aria-controls" )
1662              .removeAttr( "tabIndex" )
1663              .removeUniqueId();
1664  
1665          this._destroyIcons();
1666  
1667          // clean up content panels
1668          contents = this.headers.next()
1669              .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
1670                  "ui-accordion-content ui-accordion-content-active ui-state-disabled" )
1671              .css( "display", "" )
1672              .removeAttr( "role" )
1673              .removeAttr( "aria-hidden" )
1674              .removeAttr( "aria-labelledby" )
1675              .removeUniqueId();
1676  
1677          if ( this.options.heightStyle !== "content" ) {
1678              contents.css( "height", "" );
1679          }
1680      },
1681  
1682      _setOption: function( key, value ) {
1683          if ( key === "active" ) {
1684              // _activate() will handle invalid values and update this.options
1685              this._activate( value );
1686              return;
1687          }
1688  
1689          if ( key === "event" ) {
1690              if ( this.options.event ) {
1691                  this._off( this.headers, this.options.event );
1692              }
1693              this._setupEvents( value );
1694          }
1695  
1696          this._super( key, value );
1697  
1698          // setting collapsible: false while collapsed; open first panel
1699          if ( key === "collapsible" && !value && this.options.active === false ) {
1700              this._activate( 0 );
1701          }
1702  
1703          if ( key === "icons" ) {
1704              this._destroyIcons();
1705              if ( value ) {
1706                  this._createIcons();
1707              }
1708          }
1709  
1710          // #5332 - opacity doesn't cascade to positioned elements in IE
1711          // so we need to add the disabled class to the headers and panels
1712          if ( key === "disabled" ) {
1713              this.element
1714                  .toggleClass( "ui-state-disabled", !!value )
1715                  .attr( "aria-disabled", value );
1716              this.headers.add( this.headers.next() )
1717                  .toggleClass( "ui-state-disabled", !!value );
1718          }
1719      },
1720  
1721      _keydown: function( event ) {
1722          if ( event.altKey || event.ctrlKey ) {
1723              return;
1724          }
1725  
1726          var keyCode = $.ui.keyCode,
1727              length = this.headers.length,
1728              currentIndex = this.headers.index( event.target ),
1729              toFocus = false;
1730  
1731          switch ( event.keyCode ) {
1732              case keyCode.RIGHT:
1733              case keyCode.DOWN:
1734                  toFocus = this.headers[ ( currentIndex + 1 ) % length ];
1735                  break;
1736              case keyCode.LEFT:
1737              case keyCode.UP:
1738                  toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
1739                  break;
1740              case keyCode.SPACE:
1741              case keyCode.ENTER:
1742                  this._eventHandler( event );
1743                  break;
1744              case keyCode.HOME:
1745                  toFocus = this.headers[ 0 ];
1746                  break;
1747              case keyCode.END:
1748                  toFocus = this.headers[ length - 1 ];
1749                  break;
1750          }
1751  
1752          if ( toFocus ) {
1753              $( event.target ).attr( "tabIndex", -1 );
1754              $( toFocus ).attr( "tabIndex", 0 );
1755              toFocus.focus();
1756              event.preventDefault();
1757          }
1758      },
1759  
1760      _panelKeyDown: function( event ) {
1761          if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
1762              $( event.currentTarget ).prev().focus();
1763          }
1764      },
1765  
1766      refresh: function() {
1767          var options = this.options;
1768          this._processPanels();
1769  
1770          // was collapsed or no panel
1771          if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
1772              options.active = false;
1773              this.active = $();
1774          // active false only when collapsible is true
1775          } else if ( options.active === false ) {
1776              this._activate( 0 );
1777          // was active, but active panel is gone
1778          } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
1779              // all remaining panel are disabled
1780              if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
1781                  options.active = false;
1782                  this.active = $();
1783              // activate previous panel
1784              } else {
1785                  this._activate( Math.max( 0, options.active - 1 ) );
1786              }
1787          // was active, active panel still exists
1788          } else {
1789              // make sure active index is correct
1790              options.active = this.headers.index( this.active );
1791          }
1792  
1793          this._destroyIcons();
1794  
1795          this._refresh();
1796      },
1797  
1798      _processPanels: function() {
1799          var prevHeaders = this.headers,
1800              prevPanels = this.panels;
1801  
1802          this.headers = this.element.find( this.options.header )
1803              .addClass( "ui-accordion-header ui-state-default ui-corner-all" );
1804  
1805          this.panels = this.headers.next()
1806              .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
1807              .filter( ":not(.ui-accordion-content-active)" )
1808              .hide();
1809  
1810          // Avoid memory leaks (#10056)
1811          if ( prevPanels ) {
1812              this._off( prevHeaders.not( this.headers ) );
1813              this._off( prevPanels.not( this.panels ) );
1814          }
1815      },
1816  
1817      _refresh: function() {
1818          var maxHeight,
1819              options = this.options,
1820              heightStyle = options.heightStyle,
1821              parent = this.element.parent();
1822  
1823          this.active = this._findActive( options.active )
1824              .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
1825              .removeClass( "ui-corner-all" );
1826          this.active.next()
1827              .addClass( "ui-accordion-content-active" )
1828              .show();
1829  
1830          this.headers
1831              .attr( "role", "tab" )
1832              .each(function() {
1833                  var header = $( this ),
1834                      headerId = header.uniqueId().attr( "id" ),
1835                      panel = header.next(),
1836                      panelId = panel.uniqueId().attr( "id" );
1837                  header.attr( "aria-controls", panelId );
1838                  panel.attr( "aria-labelledby", headerId );
1839              })
1840              .next()
1841                  .attr( "role", "tabpanel" );
1842  
1843          this.headers
1844              .not( this.active )
1845              .attr({
1846                  "aria-selected": "false",
1847                  "aria-expanded": "false",
1848                  tabIndex: -1
1849              })
1850              .next()
1851                  .attr({
1852                      "aria-hidden": "true"
1853                  })
1854                  .hide();
1855  
1856          // make sure at least one header is in the tab order
1857          if ( !this.active.length ) {
1858              this.headers.eq( 0 ).attr( "tabIndex", 0 );
1859          } else {
1860              this.active.attr({
1861                  "aria-selected": "true",
1862                  "aria-expanded": "true",
1863                  tabIndex: 0
1864              })
1865              .next()
1866                  .attr({
1867                      "aria-hidden": "false"
1868                  });
1869          }
1870  
1871          this._createIcons();
1872  
1873          this._setupEvents( options.event );
1874  
1875          if ( heightStyle === "fill" ) {
1876              maxHeight = parent.height();
1877              this.element.siblings( ":visible" ).each(function() {
1878                  var elem = $( this ),
1879                      position = elem.css( "position" );
1880  
1881                  if ( position === "absolute" || position === "fixed" ) {
1882                      return;
1883                  }
1884                  maxHeight -= elem.outerHeight( true );
1885              });
1886  
1887              this.headers.each(function() {
1888                  maxHeight -= $( this ).outerHeight( true );
1889              });
1890  
1891              this.headers.next()
1892                  .each(function() {
1893                      $( this ).height( Math.max( 0, maxHeight -
1894                          $( this ).innerHeight() + $( this ).height() ) );
1895                  })
1896                  .css( "overflow", "auto" );
1897          } else if ( heightStyle === "auto" ) {
1898              maxHeight = 0;
1899              this.headers.next()
1900                  .each(function() {
1901                      maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
1902                  })
1903                  .height( maxHeight );
1904          }
1905      },
1906  
1907      _activate: function( index ) {
1908          var active = this._findActive( index )[ 0 ];
1909  
1910          // trying to activate the already active panel
1911          if ( active === this.active[ 0 ] ) {
1912              return;
1913          }
1914  
1915          // trying to collapse, simulate a click on the currently active header
1916          active = active || this.active[ 0 ];
1917  
1918          this._eventHandler({
1919              target: active,
1920              currentTarget: active,
1921              preventDefault: $.noop
1922          });
1923      },
1924  
1925      _findActive: function( selector ) {
1926          return typeof selector === "number" ? this.headers.eq( selector ) : $();
1927      },
1928  
1929      _setupEvents: function( event ) {
1930          var events = {
1931              keydown: "_keydown"
1932          };
1933          if ( event ) {
1934              $.each( event.split( " " ), function( index, eventName ) {
1935                  events[ eventName ] = "_eventHandler";
1936              });
1937          }
1938  
1939          this._off( this.headers.add( this.headers.next() ) );
1940          this._on( this.headers, events );
1941          this._on( this.headers.next(), { keydown: "_panelKeyDown" });
1942          this._hoverable( this.headers );
1943          this._focusable( this.headers );
1944      },
1945  
1946      _eventHandler: function( event ) {
1947          var options = this.options,
1948              active = this.active,
1949              clicked = $( event.currentTarget ),
1950              clickedIsActive = clicked[ 0 ] === active[ 0 ],
1951              collapsing = clickedIsActive && options.collapsible,
1952              toShow = collapsing ? $() : clicked.next(),
1953              toHide = active.next(),
1954              eventData = {
1955                  oldHeader: active,
1956                  oldPanel: toHide,
1957                  newHeader: collapsing ? $() : clicked,
1958                  newPanel: toShow
1959              };
1960  
1961          event.preventDefault();
1962  
1963          if (
1964                  // click on active header, but not collapsible
1965                  ( clickedIsActive && !options.collapsible ) ||
1966                  // allow canceling activation
1967                  ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
1968              return;
1969          }
1970  
1971          options.active = collapsing ? false : this.headers.index( clicked );
1972  
1973          // when the call to ._toggle() comes after the class changes
1974          // it causes a very odd bug in IE 8 (see #6720)
1975          this.active = clickedIsActive ? $() : clicked;
1976          this._toggle( eventData );
1977  
1978          // switch classes
1979          // corner classes on the previously active header stay after the animation
1980          active.removeClass( "ui-accordion-header-active ui-state-active" );
1981          if ( options.icons ) {
1982              active.children( ".ui-accordion-header-icon" )
1983                  .removeClass( options.icons.activeHeader )
1984                  .addClass( options.icons.header );
1985          }
1986  
1987          if ( !clickedIsActive ) {
1988              clicked
1989                  .removeClass( "ui-corner-all" )
1990                  .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
1991              if ( options.icons ) {
1992                  clicked.children( ".ui-accordion-header-icon" )
1993                      .removeClass( options.icons.header )
1994                      .addClass( options.icons.activeHeader );
1995              }
1996  
1997              clicked
1998                  .next()
1999                  .addClass( "ui-accordion-content-active" );
2000          }
2001      },
2002  
2003      _toggle: function( data ) {
2004          var toShow = data.newPanel,
2005              toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
2006  
2007          // handle activating a panel during the animation for another activation
2008          this.prevShow.add( this.prevHide ).stop( true, true );
2009          this.prevShow = toShow;
2010          this.prevHide = toHide;
2011  
2012          if ( this.options.animate ) {
2013              this._animate( toShow, toHide, data );
2014          } else {
2015              toHide.hide();
2016              toShow.show();
2017              this._toggleComplete( data );
2018          }
2019  
2020          toHide.attr({
2021              "aria-hidden": "true"
2022          });
2023          toHide.prev().attr({
2024              "aria-selected": "false",
2025              "aria-expanded": "false"
2026          });
2027          // if we're switching panels, remove the old header from the tab order
2028          // if we're opening from collapsed state, remove the previous header from the tab order
2029          // if we're collapsing, then keep the collapsing header in the tab order
2030          if ( toShow.length && toHide.length ) {
2031              toHide.prev().attr({
2032                  "tabIndex": -1,
2033                  "aria-expanded": "false"
2034              });
2035          } else if ( toShow.length ) {
2036              this.headers.filter(function() {
2037                  return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
2038              })
2039              .attr( "tabIndex", -1 );
2040          }
2041  
2042          toShow
2043              .attr( "aria-hidden", "false" )
2044              .prev()
2045                  .attr({
2046                      "aria-selected": "true",
2047                      "aria-expanded": "true",
2048                      tabIndex: 0
2049                  });
2050      },
2051  
2052      _animate: function( toShow, toHide, data ) {
2053          var total, easing, duration,
2054              that = this,
2055              adjust = 0,
2056              boxSizing = toShow.css( "box-sizing" ),
2057              down = toShow.length &&
2058                  ( !toHide.length || ( toShow.index() < toHide.index() ) ),
2059              animate = this.options.animate || {},
2060              options = down && animate.down || animate,
2061              complete = function() {
2062                  that._toggleComplete( data );
2063              };
2064  
2065          if ( typeof options === "number" ) {
2066              duration = options;
2067          }
2068          if ( typeof options === "string" ) {
2069              easing = options;
2070          }
2071          // fall back from options to animation in case of partial down settings
2072          easing = easing || options.easing || animate.easing;
2073          duration = duration || options.duration || animate.duration;
2074  
2075          if ( !toHide.length ) {
2076              return toShow.animate( this.showProps, duration, easing, complete );
2077          }
2078          if ( !toShow.length ) {
2079              return toHide.animate( this.hideProps, duration, easing, complete );
2080          }
2081  
2082          total = toShow.show().outerHeight();
2083          toHide.animate( this.hideProps, {
2084              duration: duration,
2085              easing: easing,
2086              step: function( now, fx ) {
2087                  fx.now = Math.round( now );
2088              }
2089          });
2090          toShow
2091              .hide()
2092              .animate( this.showProps, {
2093                  duration: duration,
2094                  easing: easing,
2095                  complete: complete,
2096                  step: function( now, fx ) {
2097                      fx.now = Math.round( now );
2098                      if ( fx.prop !== "height" ) {
2099                          if ( boxSizing === "content-box" ) {
2100                              adjust += fx.now;
2101                          }
2102                      } else if ( that.options.heightStyle !== "content" ) {
2103                          fx.now = Math.round( total - toHide.outerHeight() - adjust );
2104                          adjust = 0;
2105                      }
2106                  }
2107              });
2108      },
2109  
2110      _toggleComplete: function( data ) {
2111          var toHide = data.oldPanel;
2112  
2113          toHide
2114              .removeClass( "ui-accordion-content-active" )
2115              .prev()
2116                  .removeClass( "ui-corner-top" )
2117                  .addClass( "ui-corner-all" );
2118  
2119          // Work around for rendering bug in IE (#5421)
2120          if ( toHide.length ) {
2121              toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
2122          }
2123          this._trigger( "activate", null, data );
2124      }
2125  });
2126  
2127  
2128  /*!
2129   * jQuery UI Menu 1.11.4
2130   * http://jqueryui.com
2131   *
2132   * Copyright jQuery Foundation and other contributors
2133   * Released under the MIT license.
2134   * http://jquery.org/license
2135   *
2136   * http://api.jqueryui.com/menu/
2137   */
2138  
2139  
2140  var menu = $.widget( "ui.menu", {
2141      version: "1.11.4",
2142      defaultElement: "<ul>",
2143      delay: 300,
2144      options: {
2145          icons: {
2146              submenu: "ui-icon-carat-1-e"
2147          },
2148          items: "> *",
2149          menus: "ul",
2150          position: {
2151              my: "left-1 top",
2152              at: "right top"
2153          },
2154          role: "menu",
2155  
2156          // callbacks
2157          blur: null,
2158          focus: null,
2159          select: null
2160      },
2161  
2162      _create: function() {
2163          this.activeMenu = this.element;
2164  
2165          // Flag used to prevent firing of the click handler
2166          // as the event bubbles up through nested menus
2167          this.mouseHandled = false;
2168          this.element
2169              .uniqueId()
2170              .addClass( "ui-menu ui-widget ui-widget-content" )
2171              .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
2172              .attr({
2173                  role: this.options.role,
2174                  tabIndex: 0
2175              });
2176  
2177          if ( this.options.disabled ) {
2178              this.element
2179                  .addClass( "ui-state-disabled" )
2180                  .attr( "aria-disabled", "true" );
2181          }
2182  
2183          this._on({
2184              // Prevent focus from sticking to links inside menu after clicking
2185              // them (focus should always stay on UL during navigation).
2186              "mousedown .ui-menu-item": function( event ) {
2187                  event.preventDefault();
2188              },
2189              "click .ui-menu-item": function( event ) {
2190                  var target = $( event.target );
2191                  if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
2192                      this.select( event );
2193  
2194                      // Only set the mouseHandled flag if the event will bubble, see #9469.
2195                      if ( !event.isPropagationStopped() ) {
2196                          this.mouseHandled = true;
2197                      }
2198  
2199                      // Open submenu on click
2200                      if ( target.has( ".ui-menu" ).length ) {
2201                          this.expand( event );
2202                      } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
2203  
2204                          // Redirect focus to the menu
2205                          this.element.trigger( "focus", [ true ] );
2206  
2207                          // If the active item is on the top level, let it stay active.
2208                          // Otherwise, blur the active item since it is no longer visible.
2209                          if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
2210                              clearTimeout( this.timer );
2211                          }
2212                      }
2213                  }
2214              },
2215              "mouseenter .ui-menu-item": function( event ) {
2216                  // Ignore mouse events while typeahead is active, see #10458.
2217                  // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
2218                  // is over an item in the menu
2219                  if ( this.previousFilter ) {
2220                      return;
2221                  }
2222                  var target = $( event.currentTarget );
2223                  // Remove ui-state-active class from siblings of the newly focused menu item
2224                  // to avoid a jump caused by adjacent elements both having a class with a border
2225                  target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
2226                  this.focus( event, target );
2227              },
2228              mouseleave: "collapseAll",
2229              "mouseleave .ui-menu": "collapseAll",
2230              focus: function( event, keepActiveItem ) {
2231                  // If there's already an active item, keep it active
2232                  // If not, activate the first item
2233                  var item = this.active || this.element.find( this.options.items ).eq( 0 );
2234  
2235                  if ( !keepActiveItem ) {
2236                      this.focus( event, item );
2237                  }
2238              },
2239              blur: function( event ) {
2240                  this._delay(function() {
2241                      if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
2242                          this.collapseAll( event );
2243                      }
2244                  });
2245              },
2246              keydown: "_keydown"
2247          });
2248  
2249          this.refresh();
2250  
2251          // Clicks outside of a menu collapse any open menus
2252          this._on( this.document, {
2253              click: function( event ) {
2254                  if ( this._closeOnDocumentClick( event ) ) {
2255                      this.collapseAll( event );
2256                  }
2257  
2258                  // Reset the mouseHandled flag
2259                  this.mouseHandled = false;
2260              }
2261          });
2262      },
2263  
2264      _destroy: function() {
2265          // Destroy (sub)menus
2266          this.element
2267              .removeAttr( "aria-activedescendant" )
2268              .find( ".ui-menu" ).addBack()
2269                  .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
2270                  .removeAttr( "role" )
2271                  .removeAttr( "tabIndex" )
2272                  .removeAttr( "aria-labelledby" )
2273                  .removeAttr( "aria-expanded" )
2274                  .removeAttr( "aria-hidden" )
2275                  .removeAttr( "aria-disabled" )
2276                  .removeUniqueId()
2277                  .show();
2278  
2279          // Destroy menu items
2280          this.element.find( ".ui-menu-item" )
2281              .removeClass( "ui-menu-item" )
2282              .removeAttr( "role" )
2283              .removeAttr( "aria-disabled" )
2284              .removeUniqueId()
2285              .removeClass( "ui-state-hover" )
2286              .removeAttr( "tabIndex" )
2287              .removeAttr( "role" )
2288              .removeAttr( "aria-haspopup" )
2289              .children().each( function() {
2290                  var elem = $( this );
2291                  if ( elem.data( "ui-menu-submenu-carat" ) ) {
2292                      elem.remove();
2293                  }
2294              });
2295  
2296          // Destroy menu dividers
2297          this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
2298      },
2299  
2300      _keydown: function( event ) {
2301          var match, prev, character, skip,
2302              preventDefault = true;
2303  
2304          switch ( event.keyCode ) {
2305          case $.ui.keyCode.PAGE_UP:
2306              this.previousPage( event );
2307              break;
2308          case $.ui.keyCode.PAGE_DOWN:
2309              this.nextPage( event );
2310              break;
2311          case $.ui.keyCode.HOME:
2312              this._move( "first", "first", event );
2313              break;
2314          case $.ui.keyCode.END:
2315              this._move( "last", "last", event );
2316              break;
2317          case $.ui.keyCode.UP:
2318              this.previous( event );
2319              break;
2320          case $.ui.keyCode.DOWN:
2321              this.next( event );
2322              break;
2323          case $.ui.keyCode.LEFT:
2324              this.collapse( event );
2325              break;
2326          case $.ui.keyCode.RIGHT:
2327              if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
2328                  this.expand( event );
2329              }
2330              break;
2331          case $.ui.keyCode.ENTER:
2332          case $.ui.keyCode.SPACE:
2333              this._activate( event );
2334              break;
2335          case $.ui.keyCode.ESCAPE:
2336              this.collapse( event );
2337              break;
2338          default:
2339              preventDefault = false;
2340              prev = this.previousFilter || "";
2341              character = String.fromCharCode( event.keyCode );
2342              skip = false;
2343  
2344              clearTimeout( this.filterTimer );
2345  
2346              if ( character === prev ) {
2347                  skip = true;
2348              } else {
2349                  character = prev + character;
2350              }
2351  
2352              match = this._filterMenuItems( character );
2353              match = skip && match.index( this.active.next() ) !== -1 ?
2354                  this.active.nextAll( ".ui-menu-item" ) :
2355                  match;
2356  
2357              // If no matches on the current filter, reset to the last character pressed
2358              // to move down the menu to the first item that starts with that character
2359              if ( !match.length ) {
2360                  character = String.fromCharCode( event.keyCode );
2361                  match = this._filterMenuItems( character );
2362              }
2363  
2364              if ( match.length ) {
2365                  this.focus( event, match );
2366                  this.previousFilter = character;
2367                  this.filterTimer = this._delay(function() {
2368                      delete this.previousFilter;
2369                  }, 1000 );
2370              } else {
2371                  delete this.previousFilter;
2372              }
2373          }
2374  
2375          if ( preventDefault ) {
2376              event.preventDefault();
2377          }
2378      },
2379  
2380      _activate: function( event ) {
2381          if ( !this.active.is( ".ui-state-disabled" ) ) {
2382              if ( this.active.is( "[aria-haspopup='true']" ) ) {
2383                  this.expand( event );
2384              } else {
2385                  this.select( event );
2386              }
2387          }
2388      },
2389  
2390      refresh: function() {
2391          var menus, items,
2392              that = this,
2393              icon = this.options.icons.submenu,
2394              submenus = this.element.find( this.options.menus );
2395  
2396          this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
2397  
2398          // Initialize nested menus
2399          submenus.filter( ":not(.ui-menu)" )
2400              .addClass( "ui-menu ui-widget ui-widget-content ui-front" )
2401              .hide()
2402              .attr({
2403                  role: this.options.role,
2404                  "aria-hidden": "true",
2405                  "aria-expanded": "false"
2406              })
2407              .each(function() {
2408                  var menu = $( this ),
2409                      item = menu.parent(),
2410                      submenuCarat = $( "<span>" )
2411                          .addClass( "ui-menu-icon ui-icon " + icon )
2412                          .data( "ui-menu-submenu-carat", true );
2413  
2414                  item
2415                      .attr( "aria-haspopup", "true" )
2416                      .prepend( submenuCarat );
2417                  menu.attr( "aria-labelledby", item.attr( "id" ) );
2418              });
2419  
2420          menus = submenus.add( this.element );
2421          items = menus.find( this.options.items );
2422  
2423          // Initialize menu-items containing spaces and/or dashes only as dividers
2424          items.not( ".ui-menu-item" ).each(function() {
2425              var item = $( this );
2426              if ( that._isDivider( item ) ) {
2427                  item.addClass( "ui-widget-content ui-menu-divider" );
2428              }
2429          });
2430  
2431          // Don't refresh list items that are already adapted
2432          items.not( ".ui-menu-item, .ui-menu-divider" )
2433              .addClass( "ui-menu-item" )
2434              .uniqueId()
2435              .attr({
2436                  tabIndex: -1,
2437                  role: this._itemRole()
2438              });
2439  
2440          // Add aria-disabled attribute to any disabled menu item
2441          items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
2442  
2443          // If the active item has been removed, blur the menu
2444          if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
2445              this.blur();
2446          }
2447      },
2448  
2449      _itemRole: function() {
2450          return {
2451              menu: "menuitem",
2452              listbox: "option"
2453          }[ this.options.role ];
2454      },
2455  
2456      _setOption: function( key, value ) {
2457          if ( key === "icons" ) {
2458              this.element.find( ".ui-menu-icon" )
2459                  .removeClass( this.options.icons.submenu )
2460                  .addClass( value.submenu );
2461          }
2462          if ( key === "disabled" ) {
2463              this.element
2464                  .toggleClass( "ui-state-disabled", !!value )
2465                  .attr( "aria-disabled", value );
2466          }
2467          this._super( key, value );
2468      },
2469  
2470      focus: function( event, item ) {
2471          var nested, focused;
2472          this.blur( event, event && event.type === "focus" );
2473  
2474          this._scrollIntoView( item );
2475  
2476          this.active = item.first();
2477          focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
2478          // Only update aria-activedescendant if there's a role
2479          // otherwise we assume focus is managed elsewhere
2480          if ( this.options.role ) {
2481              this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
2482          }
2483  
2484          // Highlight active parent menu item, if any
2485          this.active
2486              .parent()
2487              .closest( ".ui-menu-item" )
2488              .addClass( "ui-state-active" );
2489  
2490          if ( event && event.type === "keydown" ) {
2491              this._close();
2492          } else {
2493              this.timer = this._delay(function() {
2494                  this._close();
2495              }, this.delay );
2496          }
2497  
2498          nested = item.children( ".ui-menu" );
2499          if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
2500              this._startOpening(nested);
2501          }
2502          this.activeMenu = item.parent();
2503  
2504          this._trigger( "focus", event, { item: item } );
2505      },
2506  
2507      _scrollIntoView: function( item ) {
2508          var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
2509          if ( this._hasScroll() ) {
2510              borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
2511              paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
2512              offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
2513              scroll = this.activeMenu.scrollTop();
2514              elementHeight = this.activeMenu.height();
2515              itemHeight = item.outerHeight();
2516  
2517              if ( offset < 0 ) {
2518                  this.activeMenu.scrollTop( scroll + offset );
2519              } else if ( offset + itemHeight > elementHeight ) {
2520                  this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
2521              }
2522          }
2523      },
2524  
2525      blur: function( event, fromFocus ) {
2526          if ( !fromFocus ) {
2527              clearTimeout( this.timer );
2528          }
2529  
2530          if ( !this.active ) {
2531              return;
2532          }
2533  
2534          this.active.removeClass( "ui-state-focus" );
2535          this.active = null;
2536  
2537          this._trigger( "blur", event, { item: this.active } );
2538      },
2539  
2540      _startOpening: function( submenu ) {
2541          clearTimeout( this.timer );
2542  
2543          // Don't open if already open fixes a Firefox bug that caused a .5 pixel
2544          // shift in the submenu position when mousing over the carat icon
2545          if ( submenu.attr( "aria-hidden" ) !== "true" ) {
2546              return;
2547          }
2548  
2549          this.timer = this._delay(function() {
2550              this._close();
2551              this._open( submenu );
2552          }, this.delay );
2553      },
2554  
2555      _open: function( submenu ) {
2556          var position = $.extend({
2557              of: this.active
2558          }, this.options.position );
2559  
2560          clearTimeout( this.timer );
2561          this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
2562              .hide()
2563              .attr( "aria-hidden", "true" );
2564  
2565          submenu
2566              .show()
2567              .removeAttr( "aria-hidden" )
2568              .attr( "aria-expanded", "true" )
2569              .position( position );
2570      },
2571  
2572      collapseAll: function( event, all ) {
2573          clearTimeout( this.timer );
2574          this.timer = this._delay(function() {
2575              // If we were passed an event, look for the submenu that contains the event
2576              var currentMenu = all ? this.element :
2577                  $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
2578  
2579              // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
2580              if ( !currentMenu.length ) {
2581                  currentMenu = this.element;
2582              }
2583  
2584              this._close( currentMenu );
2585  
2586              this.blur( event );
2587              this.activeMenu = currentMenu;
2588          }, this.delay );
2589      },
2590  
2591      // With no arguments, closes the currently active menu - if nothing is active
2592      // it closes all menus.  If passed an argument, it will search for menus BELOW
2593      _close: function( startMenu ) {
2594          if ( !startMenu ) {
2595              startMenu = this.active ? this.active.parent() : this.element;
2596          }
2597  
2598          startMenu
2599              .find( ".ui-menu" )
2600                  .hide()
2601                  .attr( "aria-hidden", "true" )
2602                  .attr( "aria-expanded", "false" )
2603              .end()
2604              .find( ".ui-state-active" ).not( ".ui-state-focus" )
2605                  .removeClass( "ui-state-active" );
2606      },
2607  
2608      _closeOnDocumentClick: function( event ) {
2609          return !$( event.target ).closest( ".ui-menu" ).length;
2610      },
2611  
2612      _isDivider: function( item ) {
2613  
2614          // Match hyphen, em dash, en dash
2615          return !/[^\-\u2014\u2013\s]/.test( item.text() );
2616      },
2617  
2618      collapse: function( event ) {
2619          var newItem = this.active &&
2620              this.active.parent().closest( ".ui-menu-item", this.element );
2621          if ( newItem && newItem.length ) {
2622              this._close();
2623              this.focus( event, newItem );
2624          }
2625      },
2626  
2627      expand: function( event ) {
2628          var newItem = this.active &&
2629              this.active
2630                  .children( ".ui-menu " )
2631                  .find( this.options.items )
2632                  .first();
2633  
2634          if ( newItem && newItem.length ) {
2635              this._open( newItem.parent() );
2636  
2637              // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
2638              this._delay(function() {
2639                  this.focus( event, newItem );
2640              });
2641          }
2642      },
2643  
2644      next: function( event ) {
2645          this._move( "next", "first", event );
2646      },
2647  
2648      previous: function( event ) {
2649          this._move( "prev", "last", event );
2650      },
2651  
2652      isFirstItem: function() {
2653          return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
2654      },
2655  
2656      isLastItem: function() {
2657          return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
2658      },
2659  
2660      _move: function( direction, filter, event ) {
2661          var next;
2662          if ( this.active ) {
2663              if ( direction === "first" || direction === "last" ) {
2664                  next = this.active
2665                      [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
2666                      .eq( -1 );
2667              } else {
2668                  next = this.active
2669                      [ direction + "All" ]( ".ui-menu-item" )
2670                      .eq( 0 );
2671              }
2672          }
2673          if ( !next || !next.length || !this.active ) {
2674              next = this.activeMenu.find( this.options.items )[ filter ]();
2675          }
2676  
2677          this.focus( event, next );
2678      },
2679  
2680      nextPage: function( event ) {
2681          var item, base, height;
2682  
2683          if ( !this.active ) {
2684              this.next( event );
2685              return;
2686          }
2687          if ( this.isLastItem() ) {
2688              return;
2689          }
2690          if ( this._hasScroll() ) {
2691              base = this.active.offset().top;
2692              height = this.element.height();
2693              this.active.nextAll( ".ui-menu-item" ).each(function() {
2694                  item = $( this );
2695                  return item.offset().top - base - height < 0;
2696              });
2697  
2698              this.focus( event, item );
2699          } else {
2700              this.focus( event, this.activeMenu.find( this.options.items )
2701                  [ !this.active ? "first" : "last" ]() );
2702          }
2703      },
2704  
2705      previousPage: function( event ) {
2706          var item, base, height;
2707          if ( !this.active ) {
2708              this.next( event );
2709              return;
2710          }
2711          if ( this.isFirstItem() ) {
2712              return;
2713          }
2714          if ( this._hasScroll() ) {
2715              base = this.active.offset().top;
2716              height = this.element.height();
2717              this.active.prevAll( ".ui-menu-item" ).each(function() {
2718                  item = $( this );
2719                  return item.offset().top - base + height > 0;
2720              });
2721  
2722              this.focus( event, item );
2723          } else {
2724              this.focus( event, this.activeMenu.find( this.options.items ).first() );
2725          }
2726      },
2727  
2728      _hasScroll: function() {
2729          return this.element.outerHeight() < this.element.prop( "scrollHeight" );
2730      },
2731  
2732      select: function( event ) {
2733          // TODO: It should never be possible to not have an active item at this
2734          // point, but the tests don't trigger mouseenter before click.
2735          this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
2736          var ui = { item: this.active };
2737          if ( !this.active.has( ".ui-menu" ).length ) {
2738              this.collapseAll( event, true );
2739          }
2740          this._trigger( "select", event, ui );
2741      },
2742  
2743      _filterMenuItems: function(character) {
2744          var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
2745              regex = new RegExp( "^" + escapedCharacter, "i" );
2746  
2747          return this.activeMenu
2748              .find( this.options.items )
2749  
2750              // Only match on items, not dividers or other content (#10571)
2751              .filter( ".ui-menu-item" )
2752              .filter(function() {
2753                  return regex.test( $.trim( $( this ).text() ) );
2754              });
2755      }
2756  });
2757  
2758  
2759  /*!
2760   * jQuery UI Autocomplete 1.11.4
2761   * http://jqueryui.com
2762   *
2763   * Copyright jQuery Foundation and other contributors
2764   * Released under the MIT license.
2765   * http://jquery.org/license
2766   *
2767   * http://api.jqueryui.com/autocomplete/
2768   */
2769  
2770  
2771  $.widget( "ui.autocomplete", {
2772      version: "1.11.4",
2773      defaultElement: "<input>",
2774      options: {
2775          appendTo: null,
2776          autoFocus: false,
2777          delay: 300,
2778          minLength: 1,
2779          position: {
2780              my: "left top",
2781              at: "left bottom",
2782              collision: "none"
2783          },
2784          source: null,
2785  
2786          // callbacks
2787          change: null,
2788          close: null,
2789          focus: null,
2790          open: null,
2791          response: null,
2792          search: null,
2793          select: null
2794      },
2795  
2796      requestIndex: 0,
2797      pending: 0,
2798  
2799      _create: function() {
2800          // Some browsers only repeat keydown events, not keypress events,
2801          // so we use the suppressKeyPress flag to determine if we've already
2802          // handled the keydown event. #7269
2803          // Unfortunately the code for & in keypress is the same as the up arrow,
2804          // so we use the suppressKeyPressRepeat flag to avoid handling keypress
2805          // events when we know the keydown event was used to modify the
2806          // search term. #7799
2807          var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
2808              nodeName = this.element[ 0 ].nodeName.toLowerCase(),
2809              isTextarea = nodeName === "textarea",
2810              isInput = nodeName === "input";
2811  
2812          this.isMultiLine =
2813              // Textareas are always multi-line
2814              isTextarea ? true :
2815              // Inputs are always single-line, even if inside a contentEditable element
2816              // IE also treats inputs as contentEditable
2817              isInput ? false :
2818              // All other element types are determined by whether or not they're contentEditable
2819              this.element.prop( "isContentEditable" );
2820  
2821          this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
2822          this.isNewMenu = true;
2823  
2824          this.element
2825              .addClass( "ui-autocomplete-input" )
2826              .attr( "autocomplete", "off" );
2827  
2828          this._on( this.element, {
2829              keydown: function( event ) {
2830                  if ( this.element.prop( "readOnly" ) ) {
2831                      suppressKeyPress = true;
2832                      suppressInput = true;
2833                      suppressKeyPressRepeat = true;
2834                      return;
2835                  }
2836  
2837                  suppressKeyPress = false;
2838                  suppressInput = false;
2839                  suppressKeyPressRepeat = false;
2840                  var keyCode = $.ui.keyCode;
2841                  switch ( event.keyCode ) {
2842                  case keyCode.PAGE_UP:
2843                      suppressKeyPress = true;
2844                      this._move( "previousPage", event );
2845                      break;
2846                  case keyCode.PAGE_DOWN:
2847                      suppressKeyPress = true;
2848                      this._move( "nextPage", event );
2849                      break;
2850                  case keyCode.UP:
2851                      suppressKeyPress = true;
2852                      this._keyEvent( "previous", event );
2853                      break;
2854                  case keyCode.DOWN:
2855                      suppressKeyPress = true;
2856                      this._keyEvent( "next", event );
2857                      break;
2858                  case keyCode.ENTER:
2859                      // when menu is open and has focus
2860                      if ( this.menu.active ) {
2861                          // #6055 - Opera still allows the keypress to occur
2862                          // which causes forms to submit
2863                          suppressKeyPress = true;
2864                          event.preventDefault();
2865                          this.menu.select( event );
2866                      }
2867                      break;
2868                  case keyCode.TAB:
2869                      if ( this.menu.active ) {
2870                          this.menu.select( event );
2871                      }
2872                      break;
2873                  case keyCode.ESCAPE:
2874                      if ( this.menu.element.is( ":visible" ) ) {
2875                          if ( !this.isMultiLine ) {
2876                              this._value( this.term );
2877                          }
2878                          this.close( event );
2879                          // Different browsers have different default behavior for escape
2880                          // Single press can mean undo or clear
2881                          // Double press in IE means clear the whole form
2882                          event.preventDefault();
2883                      }
2884                      break;
2885                  default:
2886                      suppressKeyPressRepeat = true;
2887                      // search timeout should be triggered before the input value is changed
2888                      this._searchTimeout( event );
2889                      break;
2890                  }
2891              },
2892              keypress: function( event ) {
2893                  if ( suppressKeyPress ) {
2894                      suppressKeyPress = false;
2895                      if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
2896                          event.preventDefault();
2897                      }
2898                      return;
2899                  }
2900                  if ( suppressKeyPressRepeat ) {
2901                      return;
2902                  }
2903  
2904                  // replicate some key handlers to allow them to repeat in Firefox and Opera
2905                  var keyCode = $.ui.keyCode;
2906                  switch ( event.keyCode ) {
2907                  case keyCode.PAGE_UP:
2908                      this._move( "previousPage", event );
2909                      break;
2910                  case keyCode.PAGE_DOWN:
2911                      this._move( "nextPage", event );
2912                      break;
2913                  case keyCode.UP:
2914                      this._keyEvent( "previous", event );
2915                      break;
2916                  case keyCode.DOWN:
2917                      this._keyEvent( "next", event );
2918                      break;
2919                  }
2920              },
2921              input: function( event ) {
2922                  if ( suppressInput ) {
2923                      suppressInput = false;
2924                      event.preventDefault();
2925                      return;
2926                  }
2927                  this._searchTimeout( event );
2928              },
2929              focus: function() {
2930                  this.selectedItem = null;
2931                  this.previous = this._value();
2932              },
2933              blur: function( event ) {
2934                  if ( this.cancelBlur ) {
2935                      delete this.cancelBlur;
2936                      return;
2937                  }
2938  
2939                  clearTimeout( this.searching );
2940                  this.close( event );
2941                  this._change( event );
2942              }
2943          });
2944  
2945          this._initSource();
2946          this.menu = $( "<ul>" )
2947              .addClass( "ui-autocomplete ui-front" )
2948              .appendTo( this._appendTo() )
2949              .menu({
2950                  // disable ARIA support, the live region takes care of that
2951                  role: null
2952              })
2953              .hide()
2954              .menu( "instance" );
2955  
2956          this._on( this.menu.element, {
2957              mousedown: function( event ) {
2958                  // prevent moving focus out of the text field
2959                  event.preventDefault();
2960  
2961                  // IE doesn't prevent moving focus even with event.preventDefault()
2962                  // so we set a flag to know when we should ignore the blur event
2963                  this.cancelBlur = true;
2964                  this._delay(function() {
2965                      delete this.cancelBlur;
2966                  });
2967  
2968                  // clicking on the scrollbar causes focus to shift to the body
2969                  // but we can't detect a mouseup or a click immediately afterward
2970                  // so we have to track the next mousedown and close the menu if
2971                  // the user clicks somewhere outside of the autocomplete
2972                  var menuElement = this.menu.element[ 0 ];
2973                  if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
2974                      this._delay(function() {
2975                          var that = this;
2976                          this.document.one( "mousedown", function( event ) {
2977                              if ( event.target !== that.element[ 0 ] &&
2978                                      event.target !== menuElement &&
2979                                      !$.contains( menuElement, event.target ) ) {
2980                                  that.close();
2981                              }
2982                          });
2983                      });
2984                  }
2985              },
2986              menufocus: function( event, ui ) {
2987                  var label, item;
2988                  // support: Firefox
2989                  // Prevent accidental activation of menu items in Firefox (#7024 #9118)
2990                  if ( this.isNewMenu ) {
2991                      this.isNewMenu = false;
2992                      if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
2993                          this.menu.blur();
2994  
2995                          this.document.one( "mousemove", function() {
2996                              $( event.target ).trigger( event.originalEvent );
2997                          });
2998  
2999                          return;
3000                      }
3001                  }
3002  
3003                  item = ui.item.data( "ui-autocomplete-item" );
3004                  if ( false !== this._trigger( "focus", event, { item: item } ) ) {
3005                      // use value to match what will end up in the input, if it was a key event
3006                      if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
3007                          this._value( item.value );
3008                      }
3009                  }
3010  
3011                  // Announce the value in the liveRegion
3012                  label = ui.item.attr( "aria-label" ) || item.value;
3013                  if ( label && $.trim( label ).length ) {
3014                      this.liveRegion.children().hide();
3015                      $( "<div>" ).text( label ).appendTo( this.liveRegion );
3016                  }
3017              },
3018              menuselect: function( event, ui ) {
3019                  var item = ui.item.data( "ui-autocomplete-item" ),
3020                      previous = this.previous;
3021  
3022                  // only trigger when focus was lost (click on menu)
3023                  if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
3024                      this.element.focus();
3025                      this.previous = previous;
3026                      // #6109 - IE triggers two focus events and the second
3027                      // is asynchronous, so we need to reset the previous
3028                      // term synchronously and asynchronously :-(
3029                      this._delay(function() {
3030                          this.previous = previous;
3031                          this.selectedItem = item;
3032                      });
3033                  }
3034  
3035                  if ( false !== this._trigger( "select", event, { item: item } ) ) {
3036                      this._value( item.value );
3037                  }
3038                  // reset the term after the select event
3039                  // this allows custom select handling to work properly
3040                  this.term = this._value();
3041  
3042                  this.close( event );
3043                  this.selectedItem = item;
3044              }
3045          });
3046  
3047          this.liveRegion = $( "<span>", {
3048                  role: "status",
3049                  "aria-live": "assertive",
3050                  "aria-relevant": "additions"
3051              })
3052              .addClass( "ui-helper-hidden-accessible" )
3053              .appendTo( this.document[ 0 ].body );
3054  
3055          // turning off autocomplete prevents the browser from remembering the
3056          // value when navigating through history, so we re-enable autocomplete
3057          // if the page is unloaded before the widget is destroyed. #7790
3058          this._on( this.window, {
3059              beforeunload: function() {
3060                  this.element.removeAttr( "autocomplete" );
3061              }
3062          });
3063      },
3064  
3065      _destroy: function() {
3066          clearTimeout( this.searching );
3067          this.element
3068              .removeClass( "ui-autocomplete-input" )
3069              .removeAttr( "autocomplete" );
3070          this.menu.element.remove();
3071          this.liveRegion.remove();
3072      },
3073  
3074      _setOption: function( key, value ) {
3075          this._super( key, value );
3076          if ( key === "source" ) {
3077              this._initSource();
3078          }
3079          if ( key === "appendTo" ) {
3080              this.menu.element.appendTo( this._appendTo() );
3081          }
3082          if ( key === "disabled" && value && this.xhr ) {
3083              this.xhr.abort();
3084          }
3085      },
3086  
3087      _appendTo: function() {
3088          var element = this.options.appendTo;
3089  
3090          if ( element ) {
3091              element = element.jquery || element.nodeType ?
3092                  $( element ) :
3093                  this.document.find( element ).eq( 0 );
3094          }
3095  
3096          if ( !element || !element[ 0 ] ) {
3097              element = this.element.closest( ".ui-front" );
3098          }
3099  
3100          if ( !element.length ) {
3101              element = this.document[ 0 ].body;
3102          }
3103  
3104          return element;
3105      },
3106  
3107      _initSource: function() {
3108          var array, url,
3109              that = this;
3110          if ( $.isArray( this.options.source ) ) {
3111              array = this.options.source;
3112              this.source = function( request, response ) {
3113                  response( $.ui.autocomplete.filter( array, request.term ) );
3114              };
3115          } else if ( typeof this.options.source === "string" ) {
3116              url = this.options.source;
3117              this.source = function( request, response ) {
3118                  if ( that.xhr ) {
3119                      that.xhr.abort();
3120                  }
3121                  that.xhr = $.ajax({
3122                      url: url,
3123                      data: request,
3124                      dataType: "json",
3125                      success: function( data ) {
3126                          response( data );
3127                      },
3128                      error: function() {
3129                          response([]);
3130                      }
3131                  });
3132              };
3133          } else {
3134              this.source = this.options.source;
3135          }
3136      },
3137  
3138      _searchTimeout: function( event ) {
3139          clearTimeout( this.searching );
3140          this.searching = this._delay(function() {
3141  
3142              // Search if the value has changed, or if the user retypes the same value (see #7434)
3143              var equalValues = this.term === this._value(),
3144                  menuVisible = this.menu.element.is( ":visible" ),
3145                  modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
3146  
3147              if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
3148                  this.selectedItem = null;
3149                  this.search( null, event );
3150              }
3151          }, this.options.delay );
3152      },
3153  
3154      search: function( value, event ) {
3155          value = value != null ? value : this._value();
3156  
3157          // always save the actual value, not the one passed as an argument
3158          this.term = this._value();
3159  
3160          if ( value.length < this.options.minLength ) {
3161              return this.close( event );
3162          }
3163  
3164          if ( this._trigger( "search", event ) === false ) {
3165              return;
3166          }
3167  
3168          return this._search( value );
3169      },
3170  
3171      _search: function( value ) {
3172          this.pending++;
3173          this.element.addClass( "ui-autocomplete-loading" );
3174          this.cancelSearch = false;
3175  
3176          this.source( { term: value }, this._response() );
3177      },
3178  
3179      _response: function() {
3180          var index = ++this.requestIndex;
3181  
3182          return $.proxy(function( content ) {
3183              if ( index === this.requestIndex ) {
3184                  this.__response( content );
3185              }
3186  
3187              this.pending--;
3188              if ( !this.pending ) {
3189                  this.element.removeClass( "ui-autocomplete-loading" );
3190              }
3191          }, this );
3192      },
3193  
3194      __response: function( content ) {
3195          if ( content ) {
3196              content = this._normalize( content );
3197          }
3198          this._trigger( "response", null, { content: content } );
3199          if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
3200              this._suggest( content );
3201              this._trigger( "open" );
3202          } else {
3203              // use ._close() instead of .close() so we don't cancel future searches
3204              this._close();
3205          }
3206      },
3207  
3208      close: function( event ) {
3209          this.cancelSearch = true;
3210          this._close( event );
3211      },
3212  
3213      _close: function( event ) {
3214          if ( this.menu.element.is( ":visible" ) ) {
3215              this.menu.element.hide();
3216              this.menu.blur();
3217              this.isNewMenu = true;
3218              this._trigger( "close", event );
3219          }
3220      },
3221  
3222      _change: function( event ) {
3223          if ( this.previous !== this._value() ) {
3224              this._trigger( "change", event, { item: this.selectedItem } );
3225          }
3226      },
3227  
3228      _normalize: function( items ) {
3229          // assume all items have the right format when the first item is complete
3230          if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
3231              return items;
3232          }
3233          return $.map( items, function( item ) {
3234              if ( typeof item === "string" ) {
3235                  return {
3236                      label: item,
3237                      value: item
3238                  };
3239              }
3240              return $.extend( {}, item, {
3241                  label: item.label || item.value,
3242                  value: item.value || item.label
3243              });
3244          });
3245      },
3246  
3247      _suggest: function( items ) {
3248          var ul = this.menu.element.empty();
3249          this._renderMenu( ul, items );
3250          this.isNewMenu = true;
3251          this.menu.refresh();
3252  
3253          // size and position menu
3254          ul.show();
3255          this._resizeMenu();
3256          ul.position( $.extend({
3257              of: this.element
3258          }, this.options.position ) );
3259  
3260          if ( this.options.autoFocus ) {
3261              this.menu.next();
3262          }
3263      },
3264  
3265      _resizeMenu: function() {
3266          var ul = this.menu.element;
3267          ul.outerWidth( Math.max(
3268              // Firefox wraps long text (possibly a rounding bug)
3269              // so we add 1px to avoid the wrapping (#7513)
3270              ul.width( "" ).outerWidth() + 1,
3271              this.element.outerWidth()
3272          ) );
3273      },
3274  
3275      _renderMenu: function( ul, items ) {
3276          var that = this;
3277          $.each( items, function( index, item ) {
3278              that._renderItemData( ul, item );
3279          });
3280      },
3281  
3282      _renderItemData: function( ul, item ) {
3283          return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
3284      },
3285  
3286      _renderItem: function( ul, item ) {
3287          return $( "<li>" ).text( item.label ).appendTo( ul );
3288      },
3289  
3290      _move: function( direction, event ) {
3291          if ( !this.menu.element.is( ":visible" ) ) {
3292              this.search( null, event );
3293              return;
3294          }
3295          if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
3296                  this.menu.isLastItem() && /^next/.test( direction ) ) {
3297  
3298              if ( !this.isMultiLine ) {
3299                  this._value( this.term );
3300              }
3301  
3302              this.menu.blur();
3303              return;
3304          }
3305          this.menu[ direction ]( event );
3306      },
3307  
3308      widget: function() {
3309          return this.menu.element;
3310      },
3311  
3312      _value: function() {
3313          return this.valueMethod.apply( this.element, arguments );
3314      },
3315  
3316      _keyEvent: function( keyEvent, event ) {
3317          if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
3318              this._move( keyEvent, event );
3319  
3320              // prevents moving cursor to beginning/end of the text field in some browsers
3321              event.preventDefault();
3322          }
3323      }
3324  });
3325  
3326  $.extend( $.ui.autocomplete, {
3327      escapeRegex: function( value ) {
3328          return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
3329      },
3330      filter: function( array, term ) {
3331          var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
3332          return $.grep( array, function( value ) {
3333              return matcher.test( value.label || value.value || value );
3334          });
3335      }
3336  });
3337  
3338  // live region extension, adding a `messages` option
3339  // NOTE: This is an experimental API. We are still investigating
3340  // a full solution for string manipulation and internationalization.
3341  $.widget( "ui.autocomplete", $.ui.autocomplete, {
3342      options: {
3343          messages: {
3344              noResults: "No search results.",
3345              results: function( amount ) {
3346                  return amount + ( amount > 1 ? " results are" : " result is" ) +
3347                      " available, use up and down arrow keys to navigate.";
3348              }
3349          }
3350      },
3351  
3352      __response: function( content ) {
3353          var message;
3354          this._superApply( arguments );
3355          if ( this.options.disabled || this.cancelSearch ) {
3356              return;
3357          }
3358          if ( content && content.length ) {
3359              message = this.options.messages.results( content.length );
3360          } else {
3361              message = this.options.messages.noResults;
3362          }
3363          this.liveRegion.children().hide();
3364          $( "<div>" ).text( message ).appendTo( this.liveRegion );
3365      }
3366  });
3367  
3368  var autocomplete = $.ui.autocomplete;
3369  
3370  
3371  /*!
3372   * jQuery UI Button 1.11.4
3373   * http://jqueryui.com
3374   *
3375   * Copyright jQuery Foundation and other contributors
3376   * Released under the MIT license.
3377   * http://jquery.org/license
3378   *
3379   * http://api.jqueryui.com/button/
3380   */
3381  
3382  
3383  var lastActive,
3384      baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
3385      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",
3386      formResetHandler = function() {
3387          var form = $( this );
3388          setTimeout(function() {
3389              form.find( ":ui-button" ).button( "refresh" );
3390          }, 1 );
3391      },
3392      radioGroup = function( radio ) {
3393          var name = radio.name,
3394              form = radio.form,
3395              radios = $( [] );
3396          if ( name ) {
3397              name = name.replace( /'/g, "\\'" );
3398              if ( form ) {
3399                  radios = $( form ).find( "[name='" + name + "'][type=radio]" );
3400              } else {
3401                  radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
3402                      .filter(function() {
3403                          return !this.form;
3404                      });
3405              }
3406          }
3407          return radios;
3408      };
3409  
3410  $.widget( "ui.button", {
3411      version: "1.11.4",
3412      defaultElement: "<button>",
3413      options: {
3414          disabled: null,
3415          text: true,
3416          label: null,
3417          icons: {
3418              primary: null,
3419              secondary: null
3420          }
3421      },
3422      _create: function() {
3423          this.element.closest( "form" )
3424              .unbind( "reset" + this.eventNamespace )
3425              .bind( "reset" + this.eventNamespace, formResetHandler );
3426  
3427          if ( typeof this.options.disabled !== "boolean" ) {
3428              this.options.disabled = !!this.element.prop( "disabled" );
3429          } else {
3430              this.element.prop( "disabled", this.options.disabled );
3431          }
3432  
3433          this._determineButtonType();
3434          this.hasTitle = !!this.buttonElement.attr( "title" );
3435  
3436          var that = this,
3437              options = this.options,
3438              toggleButton = this.type === "checkbox" || this.type === "radio",
3439              activeClass = !toggleButton ? "ui-state-active" : "";
3440  
3441          if ( options.label === null ) {
3442              options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
3443          }
3444  
3445          this._hoverable( this.buttonElement );
3446  
3447          this.buttonElement
3448              .addClass( baseClasses )
3449              .attr( "role", "button" )
3450              .bind( "mouseenter" + this.eventNamespace, function() {
3451                  if ( options.disabled ) {
3452                      return;
3453                  }
3454                  if ( this === lastActive ) {
3455                      $( this ).addClass( "ui-state-active" );
3456                  }
3457              })
3458              .bind( "mouseleave" + this.eventNamespace, function() {
3459                  if ( options.disabled ) {
3460                      return;
3461                  }
3462                  $( this ).removeClass( activeClass );
3463              })
3464              .bind( "click" + this.eventNamespace, function( event ) {
3465                  if ( options.disabled ) {
3466                      event.preventDefault();
3467                      event.stopImmediatePropagation();
3468                  }
3469              });
3470  
3471          // Can't use _focusable() because the element that receives focus
3472          // and the element that gets the ui-state-focus class are different
3473          this._on({
3474              focus: function() {
3475                  this.buttonElement.addClass( "ui-state-focus" );
3476              },
3477              blur: function() {
3478                  this.buttonElement.removeClass( "ui-state-focus" );
3479              }
3480          });
3481  
3482          if ( toggleButton ) {
3483              this.element.bind( "change" + this.eventNamespace, function() {
3484                  that.refresh();
3485              });
3486          }
3487  
3488          if ( this.type === "checkbox" ) {
3489              this.buttonElement.bind( "click" + this.eventNamespace, function() {
3490                  if ( options.disabled ) {
3491                      return false;
3492                  }
3493              });
3494          } else if ( this.type === "radio" ) {
3495              this.buttonElement.bind( "click" + this.eventNamespace, function() {
3496                  if ( options.disabled ) {
3497                      return false;
3498                  }
3499                  $( this ).addClass( "ui-state-active" );
3500                  that.buttonElement.attr( "aria-pressed", "true" );
3501  
3502                  var radio = that.element[ 0 ];
3503                  radioGroup( radio )
3504                      .not( radio )
3505                      .map(function() {
3506                          return $( this ).button( "widget" )[ 0 ];
3507                      })
3508                      .removeClass( "ui-state-active" )
3509                      .attr( "aria-pressed", "false" );
3510              });
3511          } else {
3512              this.buttonElement
3513                  .bind( "mousedown" + this.eventNamespace, function() {
3514                      if ( options.disabled ) {
3515                          return false;
3516                      }
3517                      $( this ).addClass( "ui-state-active" );
3518                      lastActive = this;
3519                      that.document.one( "mouseup", function() {
3520                          lastActive = null;
3521                      });
3522                  })
3523                  .bind( "mouseup" + this.eventNamespace, function() {
3524                      if ( options.disabled ) {
3525                          return false;
3526                      }
3527                      $( this ).removeClass( "ui-state-active" );
3528                  })
3529                  .bind( "keydown" + this.eventNamespace, function(event) {
3530                      if ( options.disabled ) {
3531                          return false;
3532                      }
3533                      if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
3534                          $( this ).addClass( "ui-state-active" );
3535                      }
3536                  })
3537                  // see #8559, we bind to blur here in case the button element loses
3538                  // focus between keydown and keyup, it would be left in an "active" state
3539                  .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
3540                      $( this ).removeClass( "ui-state-active" );
3541                  });
3542  
3543              if ( this.buttonElement.is("a") ) {
3544                  this.buttonElement.keyup(function(event) {
3545                      if ( event.keyCode === $.ui.keyCode.SPACE ) {
3546                          // TODO pass through original event correctly (just as 2nd argument doesn't work)
3547                          $( this ).click();
3548                      }
3549                  });
3550              }
3551          }
3552  
3553          this._setOption( "disabled", options.disabled );
3554          this._resetButton();
3555      },
3556  
3557      _determineButtonType: function() {
3558          var ancestor, labelSelector, checked;
3559  
3560          if ( this.element.is("[type=checkbox]") ) {
3561              this.type = "checkbox";
3562          } else if ( this.element.is("[type=radio]") ) {
3563              this.type = "radio";
3564          } else if ( this.element.is("input") ) {
3565              this.type = "input";
3566          } else {
3567              this.type = "button";
3568          }
3569  
3570          if ( this.type === "checkbox" || this.type === "radio" ) {
3571              // we don't search against the document in case the element
3572              // is disconnected from the DOM
3573              ancestor = this.element.parents().last();
3574              labelSelector = "label[for='" + this.element.attr("id") + "']";
3575              this.buttonElement = ancestor.find( labelSelector );
3576              if ( !this.buttonElement.length ) {
3577                  ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
3578                  this.buttonElement = ancestor.filter( labelSelector );
3579                  if ( !this.buttonElement.length ) {
3580                      this.buttonElement = ancestor.find( labelSelector );
3581                  }
3582              }
3583              this.element.addClass( "ui-helper-hidden-accessible" );
3584  
3585              checked = this.element.is( ":checked" );
3586              if ( checked ) {
3587                  this.buttonElement.addClass( "ui-state-active" );
3588              }
3589              this.buttonElement.prop( "aria-pressed", checked );
3590          } else {
3591              this.buttonElement = this.element;
3592          }
3593      },
3594  
3595      widget: function() {
3596          return this.buttonElement;
3597      },
3598  
3599      _destroy: function() {
3600          this.element
3601              .removeClass( "ui-helper-hidden-accessible" );
3602          this.buttonElement
3603              .removeClass( baseClasses + " ui-state-active " + typeClasses )
3604              .removeAttr( "role" )
3605              .removeAttr( "aria-pressed" )
3606              .html( this.buttonElement.find(".ui-button-text").html() );
3607  
3608          if ( !this.hasTitle ) {
3609              this.buttonElement.removeAttr( "title" );
3610          }
3611      },
3612  
3613      _setOption: function( key, value ) {
3614          this._super( key, value );
3615          if ( key === "disabled" ) {
3616              this.widget().toggleClass( "ui-state-disabled", !!value );
3617              this.element.prop( "disabled", !!value );
3618              if ( value ) {
3619                  if ( this.type === "checkbox" || this.type === "radio" ) {
3620                      this.buttonElement.removeClass( "ui-state-focus" );
3621                  } else {
3622                      this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
3623                  }
3624              }
3625              return;
3626          }
3627          this._resetButton();
3628      },
3629  
3630      refresh: function() {
3631          //See #8237 & #8828
3632          var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
3633  
3634          if ( isDisabled !== this.options.disabled ) {
3635              this._setOption( "disabled", isDisabled );
3636          }
3637          if ( this.type === "radio" ) {
3638              radioGroup( this.element[0] ).each(function() {
3639                  if ( $( this ).is( ":checked" ) ) {
3640                      $( this ).button( "widget" )
3641                          .addClass( "ui-state-active" )
3642                          .attr( "aria-pressed", "true" );
3643                  } else {
3644                      $( this ).button( "widget" )
3645                          .removeClass( "ui-state-active" )
3646                          .attr( "aria-pressed", "false" );
3647                  }
3648              });
3649          } else if ( this.type === "checkbox" ) {
3650              if ( this.element.is( ":checked" ) ) {
3651                  this.buttonElement
3652                      .addClass( "ui-state-active" )
3653                      .attr( "aria-pressed", "true" );
3654              } else {
3655                  this.buttonElement
3656                      .removeClass( "ui-state-active" )
3657                      .attr( "aria-pressed", "false" );
3658              }
3659          }
3660      },
3661  
3662      _resetButton: function() {
3663          if ( this.type === "input" ) {
3664              if ( this.options.label ) {
3665                  this.element.val( this.options.label );
3666              }
3667              return;
3668          }
3669          var buttonElement = this.buttonElement.removeClass( typeClasses ),
3670              buttonText = $( "<span></span>", this.document[0] )
3671                  .addClass( "ui-button-text" )
3672                  .html( this.options.label )
3673                  .appendTo( buttonElement.empty() )
3674                  .text(),
3675              icons = this.options.icons,
3676              multipleIcons = icons.primary && icons.secondary,
3677              buttonClasses = [];
3678  
3679          if ( icons.primary || icons.secondary ) {
3680              if ( this.options.text ) {
3681                  buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
3682              }
3683  
3684              if ( icons.primary ) {
3685                  buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
3686              }
3687  
3688              if ( icons.secondary ) {
3689                  buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
3690              }
3691  
3692              if ( !this.options.text ) {
3693                  buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
3694  
3695                  if ( !this.hasTitle ) {
3696                      buttonElement.attr( "title", $.trim( buttonText ) );
3697                  }
3698              }
3699          } else {
3700              buttonClasses.push( "ui-button-text-only" );
3701          }
3702          buttonElement.addClass( buttonClasses.join( " " ) );
3703      }
3704  });
3705  
3706  $.widget( "ui.buttonset", {
3707      version: "1.11.4",
3708      options: {
3709          items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
3710      },
3711  
3712      _create: function() {
3713          this.element.addClass( "ui-buttonset" );
3714      },
3715  
3716      _init: function() {
3717          this.refresh();
3718      },
3719  
3720      _setOption: function( key, value ) {
3721          if ( key === "disabled" ) {
3722              this.buttons.button( "option", key, value );
3723          }
3724  
3725          this._super( key, value );
3726      },
3727  
3728      refresh: function() {
3729          var rtl = this.element.css( "direction" ) === "rtl",
3730              allButtons = this.element.find( this.options.items ),
3731              existingButtons = allButtons.filter( ":ui-button" );
3732  
3733          // Initialize new buttons
3734          allButtons.not( ":ui-button" ).button();
3735  
3736          // Refresh existing buttons
3737          existingButtons.button( "refresh" );
3738  
3739          this.buttons = allButtons
3740              .map(function() {
3741                  return $( this ).button( "widget" )[ 0 ];
3742              })
3743                  .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
3744                  .filter( ":first" )
3745                      .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
3746                  .end()
3747                  .filter( ":last" )
3748                      .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
3749                  .end()
3750              .end();
3751      },
3752  
3753      _destroy: function() {
3754          this.element.removeClass( "ui-buttonset" );
3755          this.buttons
3756              .map(function() {
3757                  return $( this ).button( "widget" )[ 0 ];
3758              })
3759                  .removeClass( "ui-corner-left ui-corner-right" )
3760              .end()
3761              .button( "destroy" );
3762      }
3763  });
3764  
3765  var button = $.ui.button;
3766  
3767  
3768  /*!
3769   * jQuery UI Datepicker 1.11.4
3770   * http://jqueryui.com
3771   *
3772   * Copyright jQuery Foundation and other contributors
3773   * Released under the MIT license.
3774   * http://jquery.org/license
3775   *
3776   * http://api.jqueryui.com/datepicker/
3777   */
3778  
3779  
3780  $.extend($.ui, { datepicker: { version: "1.11.4" } });
3781  
3782  var datepicker_instActive;
3783  
3784  function datepicker_getZindex( elem ) {
3785      var position, value;
3786      while ( elem.length && elem[ 0 ] !== document ) {
3787          // Ignore z-index if position is set to a value where z-index is ignored by the browser
3788          // This makes behavior of this function consistent across browsers
3789          // WebKit always returns auto if the element is positioned
3790          position = elem.css( "position" );
3791          if ( position === "absolute" || position === "relative" || position === "fixed" ) {
3792              // IE returns 0 when zIndex is not specified
3793              // other browsers return a string
3794              // we ignore the case of nested elements with an explicit value of 0
3795              // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
3796              value = parseInt( elem.css( "zIndex" ), 10 );
3797              if ( !isNaN( value ) && value !== 0 ) {
3798                  return value;
3799              }
3800          }
3801          elem = elem.parent();
3802      }
3803  
3804      return 0;
3805  }
3806  /* Date picker manager.
3807     Use the singleton instance of this class, $.datepicker, to interact with the date picker.
3808     Settings for (groups of) date pickers are maintained in an instance object,
3809     allowing multiple different settings on the same page. */
3810  
3811  function Datepicker() {
3812      this._curInst = null; // The current instance in use
3813      this._keyEvent = false; // If the last event was a key event
3814      this._disabledInputs = []; // List of date picker inputs that have been disabled
3815      this._datepickerShowing = false; // True if the popup picker is showing , false if not
3816      this._inDialog = false; // True if showing within a "dialog", false if not
3817      this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
3818      this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
3819      this._appendClass = "ui-datepicker-append"; // The name of the append marker class
3820      this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
3821      this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
3822      this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
3823      this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
3824      this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
3825      this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
3826      this.regional = []; // Available regional settings, indexed by language code
3827      this.regional[""] = { // Default regional settings
3828          closeText: "Done", // Display text for close link
3829          prevText: "Prev", // Display text for previous month link
3830          nextText: "Next", // Display text for next month link
3831          currentText: "Today", // Display text for current month link
3832          monthNames: ["January","February","March","April","May","June",
3833              "July","August","September","October","November","December"], // Names of months for drop-down and formatting
3834          monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
3835          dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
3836          dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
3837          dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
3838          weekHeader: "Wk", // Column header for week of the year
3839          dateFormat: "mm/dd/yy", // See format options on parseDate
3840          firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
3841          isRTL: false, // True if right-to-left language, false if left-to-right
3842          showMonthAfterYear: false, // True if the year select precedes month, false for month then year
3843          yearSuffix: "" // Additional text to append to the year in the month headers
3844      };
3845      this._defaults = { // Global defaults for all the date picker instances
3846          showOn: "focus", // "focus" for popup on focus,
3847              // "button" for trigger button, or "both" for either
3848          showAnim: "fadeIn", // Name of jQuery animation for popup
3849          showOptions: {}, // Options for enhanced animations
3850          defaultDate: null, // Used when field is blank: actual date,
3851              // +/-number for offset from today, null for today
3852          appendText: "", // Display text following the input box, e.g. showing the format
3853          buttonText: "...", // Text for trigger button
3854          buttonImage: "", // URL for trigger button image
3855          buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
3856          hideIfNoPrevNext: false, // True to hide next/previous month links
3857              // if not applicable, false to just disable them
3858          navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
3859          gotoCurrent: false, // True if today link goes back to current selection instead
3860          changeMonth: false, // True if month can be selected directly, false if only prev/next
3861          changeYear: false, // True if year can be selected directly, false if only prev/next
3862          yearRange: "c-10:c+10", // Range of years to display in drop-down,
3863              // either relative to today's year (-nn:+nn), relative to currently displayed year
3864              // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
3865          showOtherMonths: false, // True to show dates in other months, false to leave blank
3866          selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
3867          showWeek: false, // True to show week of the year, false to not show it
3868          calculateWeek: this.iso8601Week, // How to calculate the week of the year,
3869              // takes a Date and returns the number of the week for it
3870          shortYearCutoff: "+10", // Short year values < this are in the current century,
3871              // > this are in the previous century,
3872              // string value starting with "+" for current year + value
3873          minDate: null, // The earliest selectable date, or null for no limit
3874          maxDate: null, // The latest selectable date, or null for no limit
3875          duration: "fast", // Duration of display/closure
3876          beforeShowDay: null, // Function that takes a date and returns an array with
3877              // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
3878              // [2] = cell title (optional), e.g. $.datepicker.noWeekends
3879          beforeShow: null, // Function that takes an input field and
3880              // returns a set of custom settings for the date picker
3881          onSelect: null, // Define a callback function when a date is selected
3882          onChangeMonthYear: null, // Define a callback function when the month or year is changed
3883          onClose: null, // Define a callback function when the datepicker is closed
3884          numberOfMonths: 1, // Number of months to show at a time
3885          showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
3886          stepMonths: 1, // Number of months to step back/forward
3887          stepBigMonths: 12, // Number of months to step back/forward for the big links
3888          altField: "", // Selector for an alternate field to store selected dates into
3889          altFormat: "", // The date format to use for the alternate field
3890          constrainInput: true, // The input is constrained by the current date format
3891          showButtonPanel: false, // True to show button panel, false to not show it
3892          autoSize: false, // True to size the input for the date format, false to leave as is
3893          disabled: false // The initial disabled state
3894      };
3895      $.extend(this._defaults, this.regional[""]);
3896      this.regional.en = $.extend( true, {}, this.regional[ "" ]);
3897      this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
3898      this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
3899  }
3900  
3901  $.extend(Datepicker.prototype, {
3902      /* Class name added to elements to indicate already configured with a date picker. */
3903      markerClassName: "hasDatepicker",
3904  
3905      //Keep track of the maximum number of rows displayed (see #7043)
3906      maxRows: 4,
3907  
3908      // TODO rename to "widget" when switching to widget factory
3909      _widgetDatepicker: function() {
3910          return this.dpDiv;
3911      },
3912  
3913      /* Override the default settings for all instances of the date picker.
3914       * @param  settings  object - the new settings to use as defaults (anonymous object)
3915       * @return the manager object
3916       */
3917      setDefaults: function(settings) {
3918          datepicker_extendRemove(this._defaults, settings || {});
3919          return this;
3920      },
3921  
3922      /* Attach the date picker to a jQuery selection.
3923       * @param  target    element - the target input field or division or span
3924       * @param  settings  object - the new settings to use for this date picker instance (anonymous)
3925       */
3926      _attachDatepicker: function(target, settings) {
3927          var nodeName, inline, inst;
3928          nodeName = target.nodeName.toLowerCase();
3929          inline = (nodeName === "div" || nodeName === "span");
3930          if (!target.id) {
3931              this.uuid += 1;
3932              target.id = "dp" + this.uuid;
3933          }
3934          inst = this._newInst($(target), inline);
3935          inst.settings = $.extend({}, settings || {});
3936          if (nodeName === "input") {
3937              this._connectDatepicker(target, inst);
3938          } else if (inline) {
3939              this._inlineDatepicker(target, inst);
3940          }
3941      },
3942  
3943      /* Create a new instance object. */
3944      _newInst: function(target, inline) {
3945          var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
3946          return {id: id, input: target, // associated target
3947              selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
3948              drawMonth: 0, drawYear: 0, // month being drawn
3949              inline: inline, // is datepicker inline or not
3950              dpDiv: (!inline ? this.dpDiv : // presentation div
3951              datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
3952      },
3953  
3954      /* Attach the date picker to an input field. */
3955      _connectDatepicker: function(target, inst) {
3956          var input = $(target);
3957          inst.append = $([]);
3958          inst.trigger = $([]);
3959          if (input.hasClass(this.markerClassName)) {
3960              return;
3961          }
3962          this._attachments(input, inst);
3963          input.addClass(this.markerClassName).keydown(this._doKeyDown).
3964              keypress(this._doKeyPress).keyup(this._doKeyUp);
3965          this._autoSize(inst);
3966          $.data(target, "datepicker", inst);
3967          //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
3968          if( inst.settings.disabled ) {
3969              this._disableDatepicker( target );
3970          }
3971      },
3972  
3973      /* Make attachments based on settings. */
3974      _attachments: function(input, inst) {
3975          var showOn, buttonText, buttonImage,
3976              appendText = this._get(inst, "appendText"),
3977              isRTL = this._get(inst, "isRTL");
3978  
3979          if (inst.append) {
3980              inst.append.remove();
3981          }
3982          if (appendText) {
3983              inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
3984              input[isRTL ? "before" : "after"](inst.append);
3985          }
3986  
3987          input.unbind("focus", this._showDatepicker);
3988  
3989          if (inst.trigger) {
3990              inst.trigger.remove();
3991          }
3992  
3993          showOn = this._get(inst, "showOn");
3994          if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
3995              input.focus(this._showDatepicker);
3996          }
3997          if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
3998              buttonText = this._get(inst, "buttonText");
3999              buttonImage = this._get(inst, "buttonImage");
4000              inst.trigger = $(this._get(inst, "buttonImageOnly") ?
4001                  $("<img/>").addClass(this._triggerClass).
4002                      attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
4003                  $("<button type='button'></button>").addClass(this._triggerClass).
4004                      html(!buttonImage ? buttonText : $("<img/>").attr(
4005                      { src:buttonImage, alt:buttonText, title:buttonText })));
4006              input[isRTL ? "before" : "after"](inst.trigger);
4007              inst.trigger.click(function() {
4008                  if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
4009                      $.datepicker._hideDatepicker();
4010                  } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
4011                      $.datepicker._hideDatepicker();
4012                      $.datepicker._showDatepicker(input[0]);
4013                  } else {
4014                      $.datepicker._showDatepicker(input[0]);
4015                  }
4016                  return false;
4017              });
4018          }
4019      },
4020  
4021      /* Apply the maximum length for the date format. */
4022      _autoSize: function(inst) {
4023          if (this._get(inst, "autoSize") && !inst.inline) {
4024              var findMax, max, maxI, i,
4025                  date = new Date(2009, 12 - 1, 20), // Ensure double digits
4026                  dateFormat = this._get(inst, "dateFormat");
4027  
4028              if (dateFormat.match(/[DM]/)) {
4029                  findMax = function(names) {
4030                      max = 0;
4031                      maxI = 0;
4032                      for (i = 0; i < names.length; i++) {
4033                          if (names[i].length > max) {
4034                              max = names[i].length;
4035                              maxI = i;
4036                          }
4037                      }
4038                      return maxI;
4039                  };
4040                  date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
4041                      "monthNames" : "monthNamesShort"))));
4042                  date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
4043                      "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
4044              }
4045              inst.input.attr("size", this._formatDate(inst, date).length);
4046          }
4047      },
4048  
4049      /* Attach an inline date picker to a div. */
4050      _inlineDatepicker: function(target, inst) {
4051          var divSpan = $(target);
4052          if (divSpan.hasClass(this.markerClassName)) {
4053              return;
4054          }
4055          divSpan.addClass(this.markerClassName).append(inst.dpDiv);
4056          $.data(target, "datepicker", inst);
4057          this._setDate(inst, this._getDefaultDate(inst), true);
4058          this._updateDatepicker(inst);
4059          this._updateAlternate(inst);
4060          //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
4061          if( inst.settings.disabled ) {
4062              this._disableDatepicker( target );
4063          }
4064          // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
4065          // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
4066          inst.dpDiv.css( "display", "block" );
4067      },
4068  
4069      /* Pop-up the date picker in a "dialog" box.
4070       * @param  input element - ignored
4071       * @param  date    string or Date - the initial date to display
4072       * @param  onSelect  function - the function to call when a date is selected
4073       * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
4074       * @param  pos int[2] - coordinates for the dialog's position within the screen or
4075       *                    event - with x/y coordinates or
4076       *                    leave empty for default (screen centre)
4077       * @return the manager object
4078       */
4079      _dialogDatepicker: function(input, date, onSelect, settings, pos) {
4080          var id, browserWidth, browserHeight, scrollX, scrollY,
4081              inst = this._dialogInst; // internal instance
4082  
4083          if (!inst) {
4084              this.uuid += 1;
4085              id = "dp" + this.uuid;
4086              this._dialogInput = $("<input type='text' id='" + id +
4087                  "' style='position: absolute; top: -100px; width: 0px;'/>");
4088              this._dialogInput.keydown(this._doKeyDown);
4089              $("body").append(this._dialogInput);
4090              inst = this._dialogInst = this._newInst(this._dialogInput, false);
4091              inst.settings = {};
4092              $.data(this._dialogInput[0], "datepicker", inst);
4093          }
4094          datepicker_extendRemove(inst.settings, settings || {});
4095          date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
4096          this._dialogInput.val(date);
4097  
4098          this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
4099          if (!this._pos) {
4100              browserWidth = document.documentElement.clientWidth;
4101              browserHeight = document.documentElement.clientHeight;
4102              scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
4103              scrollY = document.documentElement.scrollTop || document.body.scrollTop;
4104              this._pos = // should use actual width/height below
4105                  [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
4106          }
4107  
4108          // move input on screen for focus, but hidden behind dialog
4109          this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
4110          inst.settings.onSelect = onSelect;
4111          this._inDialog = true;
4112          this.dpDiv.addClass(this._dialogClass);
4113          this._showDatepicker(this._dialogInput[0]);
4114          if ($.blockUI) {
4115              $.blockUI(this.dpDiv);
4116          }
4117          $.data(this._dialogInput[0], "datepicker", inst);
4118          return this;
4119      },
4120  
4121      /* Detach a datepicker from its control.
4122       * @param  target    element - the target input field or division or span
4123       */
4124      _destroyDatepicker: function(target) {
4125          var nodeName,
4126              $target = $(target),
4127              inst = $.data(target, "datepicker");
4128  
4129          if (!$target.hasClass(this.markerClassName)) {
4130              return;
4131          }
4132  
4133          nodeName = target.nodeName.toLowerCase();
4134          $.removeData(target, "datepicker");
4135          if (nodeName === "input") {
4136              inst.append.remove();
4137              inst.trigger.remove();
4138              $target.removeClass(this.markerClassName).
4139                  unbind("focus", this._showDatepicker).
4140                  unbind("keydown", this._doKeyDown).
4141                  unbind("keypress", this._doKeyPress).
4142                  unbind("keyup", this._doKeyUp);
4143          } else if (nodeName === "div" || nodeName === "span") {
4144              $target.removeClass(this.markerClassName).empty();
4145          }
4146  
4147          if ( datepicker_instActive === inst ) {
4148              datepicker_instActive = null;
4149          }
4150      },
4151  
4152      /* Enable the date picker to a jQuery selection.
4153       * @param  target    element - the target input field or division or span
4154       */
4155      _enableDatepicker: function(target) {
4156          var nodeName, inline,
4157              $target = $(target),
4158              inst = $.data(target, "datepicker");
4159  
4160          if (!$target.hasClass(this.markerClassName)) {
4161              return;
4162          }
4163  
4164          nodeName = target.nodeName.toLowerCase();
4165          if (nodeName === "input") {
4166              target.disabled = false;
4167              inst.trigger.filter("button").
4168                  each(function() { this.disabled = false; }).end().
4169                  filter("img").css({opacity: "1.0", cursor: ""});
4170          } else if (nodeName === "div" || nodeName === "span") {
4171              inline = $target.children("." + this._inlineClass);
4172              inline.children().removeClass("ui-state-disabled");
4173              inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
4174                  prop("disabled", false);
4175          }
4176          this._disabledInputs = $.map(this._disabledInputs,
4177              function(value) { return (value === target ? null : value); }); // delete entry
4178      },
4179  
4180      /* Disable the date picker to a jQuery selection.
4181       * @param  target    element - the target input field or division or span
4182       */
4183      _disableDatepicker: function(target) {
4184          var nodeName, inline,
4185              $target = $(target),
4186              inst = $.data(target, "datepicker");
4187  
4188          if (!$target.hasClass(this.markerClassName)) {
4189              return;
4190          }
4191  
4192          nodeName = target.nodeName.toLowerCase();
4193          if (nodeName === "input") {
4194              target.disabled = true;
4195              inst.trigger.filter("button").
4196                  each(function() { this.disabled = true; }).end().
4197                  filter("img").css({opacity: "0.5", cursor: "default"});
4198          } else if (nodeName === "div" || nodeName === "span") {
4199              inline = $target.children("." + this._inlineClass);
4200              inline.children().addClass("ui-state-disabled");
4201              inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
4202                  prop("disabled", true);
4203          }
4204          this._disabledInputs = $.map(this._disabledInputs,
4205              function(value) { return (value === target ? null : value); }); // delete entry
4206          this._disabledInputs[this._disabledInputs.length] = target;
4207      },
4208  
4209      /* Is the first field in a jQuery collection disabled as a datepicker?
4210       * @param  target    element - the target input field or division or span
4211       * @return boolean - true if disabled, false if enabled
4212       */
4213      _isDisabledDatepicker: function(target) {
4214          if (!target) {
4215              return false;
4216          }
4217          for (var i = 0; i < this._disabledInputs.length; i++) {
4218              if (this._disabledInputs[i] === target) {
4219                  return true;
4220              }
4221          }
4222          return false;
4223      },
4224  
4225      /* Retrieve the instance data for the target control.
4226       * @param  target  element - the target input field or division or span
4227       * @return  object - the associated instance data
4228       * @throws  error if a jQuery problem getting data
4229       */
4230      _getInst: function(target) {
4231          try {
4232              return $.data(target, "datepicker");
4233          }
4234          catch (err) {
4235              throw "Missing instance data for this datepicker";
4236          }
4237      },
4238  
4239      /* Update or retrieve the settings for a date picker attached to an input field or division.
4240       * @param  target  element - the target input field or division or span
4241       * @param  name    object - the new settings to update or
4242       *                string - the name of the setting to change or retrieve,
4243       *                when retrieving also "all" for all instance settings or
4244       *                "defaults" for all global defaults
4245       * @param  value   any - the new value for the setting
4246       *                (omit if above is an object or to retrieve a value)
4247       */
4248      _optionDatepicker: function(target, name, value) {
4249          var settings, date, minDate, maxDate,
4250              inst = this._getInst(target);
4251  
4252          if (arguments.length === 2 && typeof name === "string") {
4253              return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
4254                  (inst ? (name === "all" ? $.extend({}, inst.settings) :
4255                  this._get(inst, name)) : null));
4256          }
4257  
4258          settings = name || {};
4259          if (typeof name === "string") {
4260              settings = {};
4261              settings[name] = value;
4262          }
4263  
4264          if (inst) {
4265              if (this._curInst === inst) {
4266                  this._hideDatepicker();
4267              }
4268  
4269              date = this._getDateDatepicker(target, true);
4270              minDate = this._getMinMaxDate(inst, "min");
4271              maxDate = this._getMinMaxDate(inst, "max");
4272              datepicker_extendRemove(inst.settings, settings);
4273              // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
4274              if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
4275                  inst.settings.minDate = this._formatDate(inst, minDate);
4276              }
4277              if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
4278                  inst.settings.maxDate = this._formatDate(inst, maxDate);
4279              }
4280              if ( "disabled" in settings ) {
4281                  if ( settings.disabled ) {
4282                      this._disableDatepicker(target);
4283                  } else {
4284                      this._enableDatepicker(target);
4285                  }
4286              }
4287              this._attachments($(target), inst);
4288              this._autoSize(inst);
4289              this._setDate(inst, date);
4290              this._updateAlternate(inst);
4291              this._updateDatepicker(inst);
4292          }
4293      },
4294  
4295      // change method deprecated
4296      _changeDatepicker: function(target, name, value) {
4297          this._optionDatepicker(target, name, value);
4298      },
4299  
4300      /* Redraw the date picker attached to an input field or division.
4301       * @param  target  element - the target input field or division or span
4302       */
4303      _refreshDatepicker: function(target) {
4304          var inst = this._getInst(target);
4305          if (inst) {
4306              this._updateDatepicker(inst);
4307          }
4308      },
4309  
4310      /* Set the dates for a jQuery selection.
4311       * @param  target element - the target input field or division or span
4312       * @param  date    Date - the new date
4313       */
4314      _setDateDatepicker: function(target, date) {
4315          var inst = this._getInst(target);
4316          if (inst) {
4317              this._setDate(inst, date);
4318              this._updateDatepicker(inst);
4319              this._updateAlternate(inst);
4320          }
4321      },
4322  
4323      /* Get the date(s) for the first entry in a jQuery selection.
4324       * @param  target element - the target input field or division or span
4325       * @param  noDefault boolean - true if no default date is to be used
4326       * @return Date - the current date
4327       */
4328      _getDateDatepicker: function(target, noDefault) {
4329          var inst = this._getInst(target);
4330          if (inst && !inst.inline) {
4331              this._setDateFromField(inst, noDefault);
4332          }
4333          return (inst ? this._getDate(inst) : null);
4334      },
4335  
4336      /* Handle keystrokes. */
4337      _doKeyDown: function(event) {
4338          var onSelect, dateStr, sel,
4339              inst = $.datepicker._getInst(event.target),
4340              handled = true,
4341              isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
4342  
4343          inst._keyEvent = true;
4344          if ($.datepicker._datepickerShowing) {
4345              switch (event.keyCode) {
4346                  case 9: $.datepicker._hideDatepicker();
4347                          handled = false;
4348                          break; // hide on tab out
4349                  case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
4350                                      $.datepicker._currentClass + ")", inst.dpDiv);
4351                          if (sel[0]) {
4352                              $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
4353                          }
4354  
4355                          onSelect = $.datepicker._get(inst, "onSelect");
4356                          if (onSelect) {
4357                              dateStr = $.datepicker._formatDate(inst);
4358  
4359                              // trigger custom callback
4360                              onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
4361                          } else {
4362                              $.datepicker._hideDatepicker();
4363                          }
4364  
4365                          return false; // don't submit the form
4366                  case 27: $.datepicker._hideDatepicker();
4367                          break; // hide on escape
4368                  case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4369                              -$.datepicker._get(inst, "stepBigMonths") :
4370                              -$.datepicker._get(inst, "stepMonths")), "M");
4371                          break; // previous month/year on page up/+ ctrl
4372                  case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4373                              +$.datepicker._get(inst, "stepBigMonths") :
4374                              +$.datepicker._get(inst, "stepMonths")), "M");
4375                          break; // next month/year on page down/+ ctrl
4376                  case 35: if (event.ctrlKey || event.metaKey) {
4377                              $.datepicker._clearDate(event.target);
4378                          }
4379                          handled = event.ctrlKey || event.metaKey;
4380                          break; // clear on ctrl or command +end
4381                  case 36: if (event.ctrlKey || event.metaKey) {
4382                              $.datepicker._gotoToday(event.target);
4383                          }
4384                          handled = event.ctrlKey || event.metaKey;
4385                          break; // current on ctrl or command +home
4386                  case 37: if (event.ctrlKey || event.metaKey) {
4387                              $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
4388                          }
4389                          handled = event.ctrlKey || event.metaKey;
4390                          // -1 day on ctrl or command +left
4391                          if (event.originalEvent.altKey) {
4392                              $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4393                                  -$.datepicker._get(inst, "stepBigMonths") :
4394                                  -$.datepicker._get(inst, "stepMonths")), "M");
4395                          }
4396                          // next month/year on alt +left on Mac
4397                          break;
4398                  case 38: if (event.ctrlKey || event.metaKey) {
4399                              $.datepicker._adjustDate(event.target, -7, "D");
4400                          }
4401                          handled = event.ctrlKey || event.metaKey;
4402                          break; // -1 week on ctrl or command +up
4403                  case 39: if (event.ctrlKey || event.metaKey) {
4404                              $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
4405                          }
4406                          handled = event.ctrlKey || event.metaKey;
4407                          // +1 day on ctrl or command +right
4408                          if (event.originalEvent.altKey) {
4409                              $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4410                                  +$.datepicker._get(inst, "stepBigMonths") :
4411                                  +$.datepicker._get(inst, "stepMonths")), "M");
4412                          }
4413                          // next month/year on alt +right
4414                          break;
4415                  case 40: if (event.ctrlKey || event.metaKey) {
4416                              $.datepicker._adjustDate(event.target, +7, "D");
4417                          }
4418                          handled = event.ctrlKey || event.metaKey;
4419                          break; // +1 week on ctrl or command +down
4420                  default: handled = false;
4421              }
4422          } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
4423              $.datepicker._showDatepicker(this);
4424          } else {
4425              handled = false;
4426          }
4427  
4428          if (handled) {
4429              event.preventDefault();
4430              event.stopPropagation();
4431          }
4432      },
4433  
4434      /* Filter entered characters - based on date format. */
4435      _doKeyPress: function(event) {
4436          var chars, chr,
4437              inst = $.datepicker._getInst(event.target);
4438  
4439          if ($.datepicker._get(inst, "constrainInput")) {
4440              chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
4441              chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
4442              return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
4443          }
4444      },
4445  
4446      /* Synchronise manual entry and field/alternate field. */
4447      _doKeyUp: function(event) {
4448          var date,
4449              inst = $.datepicker._getInst(event.target);
4450  
4451          if (inst.input.val() !== inst.lastVal) {
4452              try {
4453                  date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
4454                      (inst.input ? inst.input.val() : null),
4455                      $.datepicker._getFormatConfig(inst));
4456  
4457                  if (date) { // only if valid
4458                      $.datepicker._setDateFromField(inst);
4459                      $.datepicker._updateAlternate(inst);
4460                      $.datepicker._updateDatepicker(inst);
4461                  }
4462              }
4463              catch (err) {
4464              }
4465          }
4466          return true;
4467      },
4468  
4469      /* Pop-up the date picker for a given input field.
4470       * If false returned from beforeShow event handler do not show.
4471       * @param  input  element - the input field attached to the date picker or
4472       *                    event - if triggered by focus
4473       */
4474      _showDatepicker: function(input) {
4475          input = input.target || input;
4476          if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
4477              input = $("input", input.parentNode)[0];
4478          }
4479  
4480          if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
4481              return;
4482          }
4483  
4484          var inst, beforeShow, beforeShowSettings, isFixed,
4485              offset, showAnim, duration;
4486  
4487          inst = $.datepicker._getInst(input);
4488          if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
4489              $.datepicker._curInst.dpDiv.stop(true, true);
4490              if ( inst && $.datepicker._datepickerShowing ) {
4491                  $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
4492              }
4493          }
4494  
4495          beforeShow = $.datepicker._get(inst, "beforeShow");
4496          beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
4497          if(beforeShowSettings === false){
4498              return;
4499          }
4500          datepicker_extendRemove(inst.settings, beforeShowSettings);
4501  
4502          inst.lastVal = null;
4503          $.datepicker._lastInput = input;
4504          $.datepicker._setDateFromField(inst);
4505  
4506          if ($.datepicker._inDialog) { // hide cursor
4507              input.value = "";
4508          }
4509          if (!$.datepicker._pos) { // position below input
4510              $.datepicker._pos = $.datepicker._findPos(input);
4511              $.datepicker._pos[1] += input.offsetHeight; // add the height
4512          }
4513  
4514          isFixed = false;
4515          $(input).parents().each(function() {
4516              isFixed |= $(this).css("position") === "fixed";
4517              return !isFixed;
4518          });
4519  
4520          offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
4521          $.datepicker._pos = null;
4522          //to avoid flashes on Firefox
4523          inst.dpDiv.empty();
4524          // determine sizing offscreen
4525          inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
4526          $.datepicker._updateDatepicker(inst);
4527          // fix width for dynamic number of date pickers
4528          // and adjust position before showing
4529          offset = $.datepicker._checkOffset(inst, offset, isFixed);
4530          inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
4531              "static" : (isFixed ? "fixed" : "absolute")), display: "none",
4532              left: offset.left + "px", top: offset.top + "px"});
4533  
4534          if (!inst.inline) {
4535              showAnim = $.datepicker._get(inst, "showAnim");
4536              duration = $.datepicker._get(inst, "duration");
4537              inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
4538              $.datepicker._datepickerShowing = true;
4539  
4540              if ( $.effects && $.effects.effect[ showAnim ] ) {
4541                  inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
4542              } else {
4543                  inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
4544              }
4545  
4546              if ( $.datepicker._shouldFocusInput( inst ) ) {
4547                  inst.input.focus();
4548              }
4549  
4550              $.datepicker._curInst = inst;
4551          }
4552      },
4553  
4554      /* Generate the date picker content. */
4555      _updateDatepicker: function(inst) {
4556          this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
4557          datepicker_instActive = inst; // for delegate hover events
4558          inst.dpDiv.empty().append(this._generateHTML(inst));
4559          this._attachHandlers(inst);
4560  
4561          var origyearshtml,
4562              numMonths = this._getNumberOfMonths(inst),
4563              cols = numMonths[1],
4564              width = 17,
4565              activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
4566  
4567          if ( activeCell.length > 0 ) {
4568              datepicker_handleMouseover.apply( activeCell.get( 0 ) );
4569          }
4570  
4571          inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
4572          if (cols > 1) {
4573              inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
4574          }
4575          inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
4576              "Class"]("ui-datepicker-multi");
4577          inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
4578              "Class"]("ui-datepicker-rtl");
4579  
4580          if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
4581              inst.input.focus();
4582          }
4583  
4584          // deffered render of the years select (to avoid flashes on Firefox)
4585          if( inst.yearshtml ){
4586              origyearshtml = inst.yearshtml;
4587              setTimeout(function(){
4588                  //assure that inst.yearshtml didn't change.
4589                  if( origyearshtml === inst.yearshtml && inst.yearshtml ){
4590                      inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
4591                  }
4592                  origyearshtml = inst.yearshtml = null;
4593              }, 0);
4594          }
4595      },
4596  
4597      // #6694 - don't focus the input if it's already focused
4598      // this breaks the change event in IE
4599      // Support: IE and jQuery <1.9
4600      _shouldFocusInput: function( inst ) {
4601          return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
4602      },
4603  
4604      /* Check positioning to remain on screen. */
4605      _checkOffset: function(inst, offset, isFixed) {
4606          var dpWidth = inst.dpDiv.outerWidth(),
4607              dpHeight = inst.dpDiv.outerHeight(),
4608              inputWidth = inst.input ? inst.input.outerWidth() : 0,
4609              inputHeight = inst.input ? inst.input.outerHeight() : 0,
4610              viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
4611              viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
4612  
4613          offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
4614          offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
4615          offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
4616  
4617          // now check if datepicker is showing outside window viewport - move to a better place if so.
4618          offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
4619              Math.abs(offset.left + dpWidth - viewWidth) : 0);
4620          offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
4621              Math.abs(dpHeight + inputHeight) : 0);
4622  
4623          return offset;
4624      },
4625  
4626      /* Find an object's position on the screen. */
4627      _findPos: function(obj) {
4628          var position,
4629              inst = this._getInst(obj),
4630              isRTL = this._get(inst, "isRTL");
4631  
4632          while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
4633              obj = obj[isRTL ? "previousSibling" : "nextSibling"];
4634          }
4635  
4636          position = $(obj).offset();
4637          return [position.left, position.top];
4638      },
4639  
4640      /* Hide the date picker from view.
4641       * @param  input  element - the input field attached to the date picker
4642       */
4643      _hideDatepicker: function(input) {
4644          var showAnim, duration, postProcess, onClose,
4645              inst = this._curInst;
4646  
4647          if (!inst || (input && inst !== $.data(input, "datepicker"))) {
4648              return;
4649          }
4650  
4651          if (this._datepickerShowing) {
4652              showAnim = this._get(inst, "showAnim");
4653              duration = this._get(inst, "duration");
4654              postProcess = function() {
4655                  $.datepicker._tidyDialog(inst);
4656              };
4657  
4658              // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
4659              if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
4660                  inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
4661              } else {
4662                  inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
4663                      (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
4664              }
4665  
4666              if (!showAnim) {
4667                  postProcess();
4668              }
4669              this._datepickerShowing = false;
4670  
4671              onClose = this._get(inst, "onClose");
4672              if (onClose) {
4673                  onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
4674              }
4675  
4676              this._lastInput = null;
4677              if (this._inDialog) {
4678                  this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
4679                  if ($.blockUI) {
4680                      $.unblockUI();
4681                      $("body").append(this.dpDiv);
4682                  }
4683              }
4684              this._inDialog = false;
4685          }
4686      },
4687  
4688      /* Tidy up after a dialog display. */
4689      _tidyDialog: function(inst) {
4690          inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
4691      },
4692  
4693      /* Close date picker if clicked elsewhere. */
4694      _checkExternalClick: function(event) {
4695          if (!$.datepicker._curInst) {
4696              return;
4697          }
4698  
4699          var $target = $(event.target),
4700              inst = $.datepicker._getInst($target[0]);
4701  
4702          if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
4703                  $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
4704                  !$target.hasClass($.datepicker.markerClassName) &&
4705                  !$target.closest("." + $.datepicker._triggerClass).length &&
4706                  $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
4707              ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
4708                  $.datepicker._hideDatepicker();
4709          }
4710      },
4711  
4712      /* Adjust one of the date sub-fields. */
4713      _adjustDate: function(id, offset, period) {
4714          var target = $(id),
4715              inst = this._getInst(target[0]);
4716  
4717          if (this._isDisabledDatepicker(target[0])) {
4718              return;
4719          }
4720          this._adjustInstDate(inst, offset +
4721              (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
4722              period);
4723          this._updateDatepicker(inst);
4724      },
4725  
4726      /* Action for current link. */
4727      _gotoToday: function(id) {
4728          var date,
4729              target = $(id),
4730              inst = this._getInst(target[0]);
4731  
4732          if (this._get(inst, "gotoCurrent") && inst.currentDay) {
4733              inst.selectedDay = inst.currentDay;
4734              inst.drawMonth = inst.selectedMonth = inst.currentMonth;
4735              inst.drawYear = inst.selectedYear = inst.currentYear;
4736          } else {
4737              date = new Date();
4738              inst.selectedDay = date.getDate();
4739              inst.drawMonth = inst.selectedMonth = date.getMonth();
4740              inst.drawYear = inst.selectedYear = date.getFullYear();
4741          }
4742          this._notifyChange(inst);
4743          this._adjustDate(target);
4744      },
4745  
4746      /* Action for selecting a new month/year. */
4747      _selectMonthYear: function(id, select, period) {
4748          var target = $(id),
4749              inst = this._getInst(target[0]);
4750  
4751          inst["selected" + (period === "M" ? "Month" : "Year")] =
4752          inst["draw" + (period === "M" ? "Month" : "Year")] =
4753              parseInt(select.options[select.selectedIndex].value,10);
4754  
4755          this._notifyChange(inst);
4756          this._adjustDate(target);
4757      },
4758  
4759      /* Action for selecting a day. */
4760      _selectDay: function(id, month, year, td) {
4761          var inst,
4762              target = $(id);
4763  
4764          if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
4765              return;
4766          }
4767  
4768          inst = this._getInst(target[0]);
4769          inst.selectedDay = inst.currentDay = $("a", td).html();
4770          inst.selectedMonth = inst.currentMonth = month;
4771          inst.selectedYear = inst.currentYear = year;
4772          this._selectDate(id, this._formatDate(inst,
4773              inst.currentDay, inst.currentMonth, inst.currentYear));
4774      },
4775  
4776      /* Erase the input field and hide the date picker. */
4777      _clearDate: function(id) {
4778          var target = $(id);
4779          this._selectDate(target, "");
4780      },
4781  
4782      /* Update the input field with the selected date. */
4783      _selectDate: function(id, dateStr) {
4784          var onSelect,
4785              target = $(id),
4786              inst = this._getInst(target[0]);
4787  
4788          dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
4789          if (inst.input) {
4790              inst.input.val(dateStr);
4791          }
4792          this._updateAlternate(inst);
4793  
4794          onSelect = this._get(inst, "onSelect");
4795          if (onSelect) {
4796              onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
4797          } else if (inst.input) {
4798              inst.input.trigger("change"); // fire the change event
4799          }
4800  
4801          if (inst.inline){
4802              this._updateDatepicker(inst);
4803          } else {
4804              this._hideDatepicker();
4805              this._lastInput = inst.input[0];
4806              if (typeof(inst.input[0]) !== "object") {
4807                  inst.input.focus(); // restore focus
4808              }
4809              this._lastInput = null;
4810          }
4811      },
4812  
4813      /* Update any alternate field to synchronise with the main field. */
4814      _updateAlternate: function(inst) {
4815          var altFormat, date, dateStr,
4816              altField = this._get(inst, "altField");
4817  
4818          if (altField) { // update alternate field too
4819              altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
4820              date = this._getDate(inst);
4821              dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
4822              $(altField).each(function() { $(this).val(dateStr); });
4823          }
4824      },
4825  
4826      /* Set as beforeShowDay function to prevent selection of weekends.
4827       * @param  date  Date - the date to customise
4828       * @return [boolean, string] - is this date selectable?, what is its CSS class?
4829       */
4830      noWeekends: function(date) {
4831          var day = date.getDay();
4832          return [(day > 0 && day < 6), ""];
4833      },
4834  
4835      /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
4836       * @param  date  Date - the date to get the week for
4837       * @return  number - the number of the week within the year that contains this date
4838       */
4839      iso8601Week: function(date) {
4840          var time,
4841              checkDate = new Date(date.getTime());
4842  
4843          // Find Thursday of this week starting on Monday
4844          checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
4845  
4846          time = checkDate.getTime();
4847          checkDate.setMonth(0); // Compare with Jan 1
4848          checkDate.setDate(1);
4849          return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
4850      },
4851  
4852      /* Parse a string value into a date object.
4853       * See formatDate below for the possible formats.
4854       *
4855       * @param  format string - the expected format of the date
4856       * @param  value string - the date in the above format
4857       * @param  settings Object - attributes include:
4858       *                    shortYearCutoff  number - the cutoff year for determining the century (optional)
4859       *                    dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
4860       *                    dayNames        string[7] - names of the days from Sunday (optional)
4861       *                    monthNamesShort string[12] - abbreviated names of the months (optional)
4862       *                    monthNames        string[12] - names of the months (optional)
4863       * @return  Date - the extracted date value or null if value is blank
4864       */
4865      parseDate: function (format, value, settings) {
4866          if (format == null || value == null) {
4867              throw "Invalid arguments";
4868          }
4869  
4870          value = (typeof value === "object" ? value.toString() : value + "");
4871          if (value === "") {
4872              return null;
4873          }
4874  
4875          var iFormat, dim, extra,
4876              iValue = 0,
4877              shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
4878              shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
4879                  new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
4880              dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
4881              dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
4882              monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
4883              monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
4884              year = -1,
4885              month = -1,
4886              day = -1,
4887              doy = -1,
4888              literal = false,
4889              date,
4890              // Check whether a format character is doubled
4891              lookAhead = function(match) {
4892                  var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
4893                  if (matches) {
4894                      iFormat++;
4895                  }
4896                  return matches;
4897              },
4898              // Extract a number from the string value
4899              getNumber = function(match) {
4900                  var isDoubled = lookAhead(match),
4901                      size = (match === "@" ? 14 : (match === "!" ? 20 :
4902                      (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
4903                      minSize = (match === "y" ? size : 1),
4904                      digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
4905                      num = value.substring(iValue).match(digits);
4906                  if (!num) {
4907                      throw "Missing number at position " + iValue;
4908                  }
4909                  iValue += num[0].length;
4910                  return parseInt(num[0], 10);
4911              },
4912              // Extract a name from the string value and convert to an index
4913              getName = function(match, shortNames, longNames) {
4914                  var index = -1,
4915                      names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
4916                          return [ [k, v] ];
4917                      }).sort(function (a, b) {
4918                          return -(a[1].length - b[1].length);
4919                      });
4920  
4921                  $.each(names, function (i, pair) {
4922                      var name = pair[1];
4923                      if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
4924                          index = pair[0];
4925                          iValue += name.length;
4926                          return false;
4927                      }
4928                  });
4929                  if (index !== -1) {
4930                      return index + 1;
4931                  } else {
4932                      throw "Unknown name at position " + iValue;
4933                  }
4934              },
4935              // Confirm that a literal character matches the string value
4936              checkLiteral = function() {
4937                  if (value.charAt(iValue) !== format.charAt(iFormat)) {
4938                      throw "Unexpected literal at position " + iValue;
4939                  }
4940                  iValue++;
4941              };
4942  
4943          for (iFormat = 0; iFormat < format.length; iFormat++) {
4944              if (literal) {
4945                  if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
4946                      literal = false;
4947                  } else {
4948                      checkLiteral();
4949                  }
4950              } else {
4951                  switch (format.charAt(iFormat)) {
4952                      case "d":
4953                          day = getNumber("d");
4954                          break;
4955                      case "D":
4956                          getName("D", dayNamesShort, dayNames);
4957                          break;
4958                      case "o":
4959                          doy = getNumber("o");
4960                          break;
4961                      case "m":
4962                          month = getNumber("m");
4963                          break;
4964                      case "M":
4965                          month = getName("M", monthNamesShort, monthNames);
4966                          break;
4967                      case "y":
4968                          year = getNumber("y");
4969                          break;
4970                      case "@":
4971                          date = new Date(getNumber("@"));
4972                          year = date.getFullYear();
4973                          month = date.getMonth() + 1;
4974                          day = date.getDate();
4975                          break;
4976                      case "!":
4977                          date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
4978                          year = date.getFullYear();
4979                          month = date.getMonth() + 1;
4980                          day = date.getDate();
4981                          break;
4982                      case "'":
4983                          if (lookAhead("'")){
4984                              checkLiteral();
4985                          } else {
4986                              literal = true;
4987                          }
4988                          break;
4989                      default:
4990                          checkLiteral();
4991                  }
4992              }
4993          }
4994  
4995          if (iValue < value.length){
4996              extra = value.substr(iValue);
4997              if (!/^\s+/.test(extra)) {
4998                  throw "Extra/unparsed characters found in date: " + extra;
4999              }
5000          }
5001  
5002          if (year === -1) {
5003              year = new Date().getFullYear();
5004          } else if (year < 100) {
5005              year += new Date().getFullYear() - new Date().getFullYear() % 100 +
5006                  (year <= shortYearCutoff ? 0 : -100);
5007          }
5008  
5009          if (doy > -1) {
5010              month = 1;
5011              day = doy;
5012              do {
5013                  dim = this._getDaysInMonth(year, month - 1);
5014                  if (day <= dim) {
5015                      break;
5016                  }
5017                  month++;
5018                  day -= dim;
5019              } while (true);
5020          }
5021  
5022          date = this._daylightSavingAdjust(new Date(year, month - 1, day));
5023          if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
5024              throw "Invalid date"; // E.g. 31/02/00
5025          }
5026          return date;
5027      },
5028  
5029      /* Standard date formats. */
5030      ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
5031      COOKIE: "D, dd M yy",
5032      ISO_8601: "yy-mm-dd",
5033      RFC_822: "D, d M y",
5034      RFC_850: "DD, dd-M-y",
5035      RFC_1036: "D, d M y",
5036      RFC_1123: "D, d M yy",
5037      RFC_2822: "D, d M yy",
5038      RSS: "D, d M y", // RFC 822
5039      TICKS: "!",
5040      TIMESTAMP: "@",
5041      W3C: "yy-mm-dd", // ISO 8601
5042  
5043      _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
5044          Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
5045  
5046      /* Format a date object into a string value.
5047       * The format can be combinations of the following:
5048       * d  - day of month (no leading zero)
5049       * dd - day of month (two digit)
5050       * o  - day of year (no leading zeros)
5051       * oo - day of year (three digit)
5052       * D  - day name short
5053       * DD - day name long
5054       * m  - month of year (no leading zero)
5055       * mm - month of year (two digit)
5056       * M  - month name short
5057       * MM - month name long
5058       * y  - year (two digit)
5059       * yy - year (four digit)
5060       * @ - Unix timestamp (ms since 01/01/1970)
5061       * ! - Windows ticks (100ns since 01/01/0001)
5062       * "..." - literal text
5063       * '' - single quote
5064       *
5065       * @param  format string - the desired format of the date
5066       * @param  date Date - the date value to format
5067       * @param  settings Object - attributes include:
5068       *                    dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
5069       *                    dayNames        string[7] - names of the days from Sunday (optional)
5070       *                    monthNamesShort string[12] - abbreviated names of the months (optional)
5071       *                    monthNames        string[12] - names of the months (optional)
5072       * @return  string - the date in the above format
5073       */
5074      formatDate: function (format, date, settings) {
5075          if (!date) {
5076              return "";
5077          }
5078  
5079          var iFormat,
5080              dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
5081              dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
5082              monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
5083              monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
5084              // Check whether a format character is doubled
5085              lookAhead = function(match) {
5086                  var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
5087                  if (matches) {
5088                      iFormat++;
5089                  }
5090                  return matches;
5091              },
5092              // Format a number, with leading zero if necessary
5093              formatNumber = function(match, value, len) {
5094                  var num = "" + value;
5095                  if (lookAhead(match)) {
5096                      while (num.length < len) {
5097                          num = "0" + num;
5098                      }
5099                  }
5100                  return num;
5101              },
5102              // Format a name, short or long as requested
5103              formatName = function(match, value, shortNames, longNames) {
5104                  return (lookAhead(match) ? longNames[value] : shortNames[value]);
5105              },
5106              output = "",
5107              literal = false;
5108  
5109          if (date) {
5110              for (iFormat = 0; iFormat < format.length; iFormat++) {
5111                  if (literal) {
5112                      if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
5113                          literal = false;
5114                      } else {
5115                          output += format.charAt(iFormat);
5116                      }
5117                  } else {
5118                      switch (format.charAt(iFormat)) {
5119                          case "d":
5120                              output += formatNumber("d", date.getDate(), 2);
5121                              break;
5122                          case "D":
5123                              output += formatName("D", date.getDay(), dayNamesShort, dayNames);
5124                              break;
5125                          case "o":
5126                              output += formatNumber("o",
5127                                  Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
5128                              break;
5129                          case "m":
5130                              output += formatNumber("m", date.getMonth() + 1, 2);
5131                              break;
5132                          case "M":
5133                              output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
5134                              break;
5135                          case "y":
5136                              output += (lookAhead("y") ? date.getFullYear() :
5137                                  (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
5138                              break;
5139                          case "@":
5140                              output += date.getTime();
5141                              break;
5142                          case "!":
5143                              output += date.getTime() * 10000 + this._ticksTo1970;
5144                              break;
5145                          case "'":
5146                              if (lookAhead("'")) {
5147                                  output += "'";
5148                              } else {
5149                                  literal = true;
5150                              }
5151                              break;
5152                          default:
5153                              output += format.charAt(iFormat);
5154                      }
5155                  }
5156              }
5157          }
5158          return output;
5159      },
5160  
5161      /* Extract all possible characters from the date format. */
5162      _possibleChars: function (format) {
5163          var iFormat,
5164              chars = "",
5165              literal = false,
5166              // Check whether a format character is doubled
5167              lookAhead = function(match) {
5168                  var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
5169                  if (matches) {
5170                      iFormat++;
5171                  }
5172                  return matches;
5173              };
5174  
5175          for (iFormat = 0; iFormat < format.length; iFormat++) {
5176              if (literal) {
5177                  if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
5178                      literal = false;
5179                  } else {
5180                      chars += format.charAt(iFormat);
5181                  }
5182              } else {
5183                  switch (format.charAt(iFormat)) {
5184                      case "d": case "m": case "y": case "@":
5185                          chars += "0123456789";
5186                          break;
5187                      case "D": case "M":
5188                          return null; // Accept anything
5189                      case "'":
5190                          if (lookAhead("'")) {
5191                              chars += "'";
5192                          } else {
5193                              literal = true;
5194                          }
5195                          break;
5196                      default:
5197                          chars += format.charAt(iFormat);
5198                  }
5199              }
5200          }
5201          return chars;
5202      },
5203  
5204      /* Get a setting value, defaulting if necessary. */
5205      _get: function(inst, name) {
5206          return inst.settings[name] !== undefined ?
5207              inst.settings[name] : this._defaults[name];
5208      },
5209  
5210      /* Parse existing date and initialise date picker. */
5211      _setDateFromField: function(inst, noDefault) {
5212          if (inst.input.val() === inst.lastVal) {
5213              return;
5214          }
5215  
5216          var dateFormat = this._get(inst, "dateFormat"),
5217              dates = inst.lastVal = inst.input ? inst.input.val() : null,
5218              defaultDate = this._getDefaultDate(inst),
5219              date = defaultDate,
5220              settings = this._getFormatConfig(inst);
5221  
5222          try {
5223              date = this.parseDate(dateFormat, dates, settings) || defaultDate;
5224          } catch (event) {
5225              dates = (noDefault ? "" : dates);
5226          }
5227          inst.selectedDay = date.getDate();
5228          inst.drawMonth = inst.selectedMonth = date.getMonth();
5229          inst.drawYear = inst.selectedYear = date.getFullYear();
5230          inst.currentDay = (dates ? date.getDate() : 0);
5231          inst.currentMonth = (dates ? date.getMonth() : 0);
5232          inst.currentYear = (dates ? date.getFullYear() : 0);
5233          this._adjustInstDate(inst);
5234      },
5235  
5236      /* Retrieve the default date shown on opening. */
5237      _getDefaultDate: function(inst) {
5238          return this._restrictMinMax(inst,
5239              this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
5240      },
5241  
5242      /* A date may be specified as an exact value or a relative one. */
5243      _determineDate: function(inst, date, defaultDate) {
5244          var offsetNumeric = function(offset) {
5245                  var date = new Date();
5246                  date.setDate(date.getDate() + offset);
5247                  return date;
5248              },
5249              offsetString = function(offset) {
5250                  try {
5251                      return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
5252                          offset, $.datepicker._getFormatConfig(inst));
5253                  }
5254                  catch (e) {
5255                      // Ignore
5256                  }
5257  
5258                  var date = (offset.toLowerCase().match(/^c/) ?
5259                      $.datepicker._getDate(inst) : null) || new Date(),
5260                      year = date.getFullYear(),
5261                      month = date.getMonth(),
5262                      day = date.getDate(),
5263                      pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
5264                      matches = pattern.exec(offset);
5265  
5266                  while (matches) {
5267                      switch (matches[2] || "d") {
5268                          case "d" : case "D" :
5269                              day += parseInt(matches[1],10); break;
5270                          case "w" : case "W" :
5271                              day += parseInt(matches[1],10) * 7; break;
5272                          case "m" : case "M" :
5273                              month += parseInt(matches[1],10);
5274                              day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
5275                              break;
5276                          case "y": case "Y" :
5277                              year += parseInt(matches[1],10);
5278                              day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
5279                              break;
5280                      }
5281                      matches = pattern.exec(offset);
5282                  }
5283                  return new Date(year, month, day);
5284              },
5285              newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
5286                  (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
5287  
5288          newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
5289          if (newDate) {
5290              newDate.setHours(0);
5291              newDate.setMinutes(0);
5292              newDate.setSeconds(0);
5293              newDate.setMilliseconds(0);
5294          }
5295          return this._daylightSavingAdjust(newDate);
5296      },
5297  
5298      /* Handle switch to/from daylight saving.
5299       * Hours may be non-zero on daylight saving cut-over:
5300       * > 12 when midnight changeover, but then cannot generate
5301       * midnight datetime, so jump to 1AM, otherwise reset.
5302       * @param  date  (Date) the date to check
5303       * @return  (Date) the corrected date
5304       */
5305      _daylightSavingAdjust: function(date) {
5306          if (!date) {
5307              return null;
5308          }
5309          date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
5310          return date;
5311      },
5312  
5313      /* Set the date(s) directly. */
5314      _setDate: function(inst, date, noChange) {
5315          var clear = !date,
5316              origMonth = inst.selectedMonth,
5317              origYear = inst.selectedYear,
5318              newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
5319  
5320          inst.selectedDay = inst.currentDay = newDate.getDate();
5321          inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
5322          inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
5323          if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
5324              this._notifyChange(inst);
5325          }
5326          this._adjustInstDate(inst);
5327          if (inst.input) {
5328              inst.input.val(clear ? "" : this._formatDate(inst));
5329          }
5330      },
5331  
5332      /* Retrieve the date(s) directly. */
5333      _getDate: function(inst) {
5334          var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
5335              this._daylightSavingAdjust(new Date(
5336              inst.currentYear, inst.currentMonth, inst.currentDay)));
5337              return startDate;
5338      },
5339  
5340      /* Attach the onxxx handlers.  These are declared statically so
5341       * they work with static code transformers like Caja.
5342       */
5343      _attachHandlers: function(inst) {
5344          var stepMonths = this._get(inst, "stepMonths"),
5345              id = "#" + inst.id.replace( /\\\\/g, "\\" );
5346          inst.dpDiv.find("[data-handler]").map(function () {
5347              var handler = {
5348                  prev: function () {
5349                      $.datepicker._adjustDate(id, -stepMonths, "M");
5350                  },
5351                  next: function () {
5352                      $.datepicker._adjustDate(id, +stepMonths, "M");
5353                  },
5354                  hide: function () {
5355                      $.datepicker._hideDatepicker();
5356                  },
5357                  today: function () {
5358                      $.datepicker._gotoToday(id);
5359                  },
5360                  selectDay: function () {
5361                      $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
5362                      return false;
5363                  },
5364                  selectMonth: function () {
5365                      $.datepicker._selectMonthYear(id, this, "M");
5366                      return false;
5367                  },
5368                  selectYear: function () {
5369                      $.datepicker._selectMonthYear(id, this, "Y");
5370                      return false;
5371                  }
5372              };
5373              $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
5374          });
5375      },
5376  
5377      /* Generate the HTML for the current state of the date picker. */
5378      _generateHTML: function(inst) {
5379          var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
5380              controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
5381              monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
5382              selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
5383              cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
5384              printDate, dRow, tbody, daySettings, otherMonth, unselectable,
5385              tempDate = new Date(),
5386              today = this._daylightSavingAdjust(
5387                  new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
5388              isRTL = this._get(inst, "isRTL"),
5389              showButtonPanel = this._get(inst, "showButtonPanel"),
5390              hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
5391              navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
5392              numMonths = this._getNumberOfMonths(inst),
5393              showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
5394              stepMonths = this._get(inst, "stepMonths"),
5395              isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
5396              currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
5397                  new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
5398              minDate = this._getMinMaxDate(inst, "min"),
5399              maxDate = this._getMinMaxDate(inst, "max"),
5400              drawMonth = inst.drawMonth - showCurrentAtPos,
5401              drawYear = inst.drawYear;
5402  
5403          if (drawMonth < 0) {
5404              drawMonth += 12;
5405              drawYear--;
5406          }
5407          if (maxDate) {
5408              maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
5409                  maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
5410              maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
5411              while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
5412                  drawMonth--;
5413                  if (drawMonth < 0) {
5414                      drawMonth = 11;
5415                      drawYear--;
5416                  }
5417              }
5418          }
5419          inst.drawMonth = drawMonth;
5420          inst.drawYear = drawYear;
5421  
5422          prevText = this._get(inst, "prevText");
5423          prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
5424              this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
5425              this._getFormatConfig(inst)));
5426  
5427          prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
5428              "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
5429              " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
5430              (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>"));
5431  
5432          nextText = this._get(inst, "nextText");
5433          nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
5434              this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
5435              this._getFormatConfig(inst)));
5436  
5437          next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
5438              "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
5439              " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
5440              (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>"));
5441  
5442          currentText = this._get(inst, "currentText");
5443          gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
5444          currentText = (!navigationAsDateFormat ? currentText :
5445              this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
5446  
5447          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'>" +
5448              this._get(inst, "closeText") + "</button>" : "");
5449  
5450          buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
5451              (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'" +
5452              ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
5453  
5454          firstDay = parseInt(this._get(inst, "firstDay"),10);
5455          firstDay = (isNaN(firstDay) ? 0 : firstDay);
5456  
5457          showWeek = this._get(inst, "showWeek");
5458          dayNames = this._get(inst, "dayNames");
5459          dayNamesMin = this._get(inst, "dayNamesMin");
5460          monthNames = this._get(inst, "monthNames");
5461          monthNamesShort = this._get(inst, "monthNamesShort");
5462          beforeShowDay = this._get(inst, "beforeShowDay");
5463          showOtherMonths = this._get(inst, "showOtherMonths");
5464          selectOtherMonths = this._get(inst, "selectOtherMonths");
5465          defaultDate = this._getDefaultDate(inst);
5466          html = "";
5467          dow;
5468          for (row = 0; row < numMonths[0]; row++) {
5469              group = "";
5470              this.maxRows = 4;
5471              for (col = 0; col < numMonths[1]; col++) {
5472                  selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
5473                  cornerClass = " ui-corner-all";
5474                  calender = "";
5475                  if (isMultiMonth) {
5476                      calender += "<div class='ui-datepicker-group";
5477                      if (numMonths[1] > 1) {
5478                          switch (col) {
5479                              case 0: calender += " ui-datepicker-group-first";
5480                                  cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
5481                              case numMonths[1]-1: calender += " ui-datepicker-group-last";
5482                                  cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
5483                              default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
5484                          }
5485                      }
5486                      calender += "'>";
5487                  }
5488                  calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
5489                      (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
5490                      (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
5491                      this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
5492                      row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
5493                      "</div><table class='ui-datepicker-calendar'><thead>" +
5494                      "<tr>";
5495                  thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
5496                  for (dow = 0; dow < 7; dow++) { // days of the week
5497                      day = (dow + firstDay) % 7;
5498                      thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
5499                          "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
5500                  }
5501                  calender += thead + "</tr></thead><tbody>";
5502                  daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
5503                  if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
5504                      inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
5505                  }
5506                  leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
5507                  curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
5508                  numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
5509                  this.maxRows = numRows;
5510                  printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
5511                  for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
5512                      calender += "<tr>";
5513                      tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
5514                          this._get(inst, "calculateWeek")(printDate) + "</td>");
5515                      for (dow = 0; dow < 7; dow++) { // create date picker days
5516                          daySettings = (beforeShowDay ?
5517                              beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
5518                          otherMonth = (printDate.getMonth() !== drawMonth);
5519                          unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
5520                              (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
5521                          tbody += "<td class='" +
5522                              ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
5523                              (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
5524                              ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
5525                              (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
5526                              // or defaultDate is current printedDate and defaultDate is selectedDate
5527                              " " + this._dayOverClass : "") + // highlight selected day
5528                              (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
5529                              (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
5530                              (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
5531                              (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
5532                              ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
5533                              (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
5534                              (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
5535                              (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
5536                              (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
5537                              (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
5538                              (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
5539                              "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
5540                          printDate.setDate(printDate.getDate() + 1);
5541                          printDate = this._daylightSavingAdjust(printDate);
5542                      }
5543                      calender += tbody + "</tr>";
5544                  }
5545                  drawMonth++;
5546                  if (drawMonth > 11) {
5547                      drawMonth = 0;
5548                      drawYear++;
5549                  }
5550                  calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
5551                              ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
5552                  group += calender;
5553              }
5554              html += group;
5555          }
5556          html += buttonPanel;
5557          inst._keyEvent = false;
5558          return html;
5559      },
5560  
5561      /* Generate the month and year header. */
5562      _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
5563              secondary, monthNames, monthNamesShort) {
5564  
5565          var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
5566              changeMonth = this._get(inst, "changeMonth"),
5567              changeYear = this._get(inst, "changeYear"),
5568              showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
5569              html = "<div class='ui-datepicker-title'>",
5570              monthHtml = "";
5571  
5572          // month selection
5573          if (secondary || !changeMonth) {
5574              monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
5575          } else {
5576              inMinYear = (minDate && minDate.getFullYear() === drawYear);
5577              inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
5578              monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
5579              for ( month = 0; month < 12; month++) {
5580                  if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
5581                      monthHtml += "<option value='" + month + "'" +
5582                          (month === drawMonth ? " selected='selected'" : "") +
5583                          ">" + monthNamesShort[month] + "</option>";
5584                  }
5585              }
5586              monthHtml += "</select>";
5587          }
5588  
5589          if (!showMonthAfterYear) {
5590              html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
5591          }
5592  
5593          // year selection
5594          if ( !inst.yearshtml ) {
5595              inst.yearshtml = "";
5596              if (secondary || !changeYear) {
5597                  html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
5598              } else {
5599                  // determine range of years to display
5600                  years = this._get(inst, "yearRange").split(":");
5601                  thisYear = new Date().getFullYear();
5602                  determineYear = function(value) {
5603                      var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
5604                          (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
5605                          parseInt(value, 10)));
5606                      return (isNaN(year) ? thisYear : year);
5607                  };
5608                  year = determineYear(years[0]);
5609                  endYear = Math.max(year, determineYear(years[1] || ""));
5610                  year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
5611                  endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
5612                  inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
5613                  for (; year <= endYear; year++) {
5614                      inst.yearshtml += "<option value='" + year + "'" +
5615                          (year === drawYear ? " selected='selected'" : "") +
5616                          ">" + year + "</option>";
5617                  }
5618                  inst.yearshtml += "</select>";
5619  
5620                  html += inst.yearshtml;
5621                  inst.yearshtml = null;
5622              }
5623          }
5624  
5625          html += this._get(inst, "yearSuffix");
5626          if (showMonthAfterYear) {
5627              html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
5628          }
5629          html += "</div>"; // Close datepicker_header
5630          return html;
5631      },
5632  
5633      /* Adjust one of the date sub-fields. */
5634      _adjustInstDate: function(inst, offset, period) {
5635          var year = inst.drawYear + (period === "Y" ? offset : 0),
5636              month = inst.drawMonth + (period === "M" ? offset : 0),
5637              day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
5638              date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
5639  
5640          inst.selectedDay = date.getDate();
5641          inst.drawMonth = inst.selectedMonth = date.getMonth();
5642          inst.drawYear = inst.selectedYear = date.getFullYear();
5643          if (period === "M" || period === "Y") {
5644              this._notifyChange(inst);
5645          }
5646      },
5647  
5648      /* Ensure a date is within any min/max bounds. */
5649      _restrictMinMax: function(inst, date) {
5650          var minDate = this._getMinMaxDate(inst, "min"),
5651              maxDate = this._getMinMaxDate(inst, "max"),
5652              newDate = (minDate && date < minDate ? minDate : date);
5653          return (maxDate && newDate > maxDate ? maxDate : newDate);
5654      },
5655  
5656      /* Notify change of month/year. */
5657      _notifyChange: function(inst) {
5658          var onChange = this._get(inst, "onChangeMonthYear");
5659          if (onChange) {
5660              onChange.apply((inst.input ? inst.input[0] : null),
5661                  [inst.selectedYear, inst.selectedMonth + 1, inst]);
5662          }
5663      },
5664  
5665      /* Determine the number of months to show. */
5666      _getNumberOfMonths: function(inst) {
5667          var numMonths = this._get(inst, "numberOfMonths");
5668          return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
5669      },
5670  
5671      /* Determine the current maximum date - ensure no time components are set. */
5672      _getMinMaxDate: function(inst, minMax) {
5673          return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
5674      },
5675  
5676      /* Find the number of days in a given month. */
5677      _getDaysInMonth: function(year, month) {
5678          return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
5679      },
5680  
5681      /* Find the day of the week of the first of a month. */
5682      _getFirstDayOfMonth: function(year, month) {
5683          return new Date(year, month, 1).getDay();
5684      },
5685  
5686      /* Determines if we should allow a "next/prev" month display change. */
5687      _canAdjustMonth: function(inst, offset, curYear, curMonth) {
5688          var numMonths = this._getNumberOfMonths(inst),
5689              date = this._daylightSavingAdjust(new Date(curYear,
5690              curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
5691  
5692          if (offset < 0) {
5693              date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
5694          }
5695          return this._isInRange(inst, date);
5696      },
5697  
5698      /* Is the given date in the accepted range? */
5699      _isInRange: function(inst, date) {
5700          var yearSplit, currentYear,
5701              minDate = this._getMinMaxDate(inst, "min"),
5702              maxDate = this._getMinMaxDate(inst, "max"),
5703              minYear = null,
5704              maxYear = null,
5705              years = this._get(inst, "yearRange");
5706              if (years){
5707                  yearSplit = years.split(":");
5708                  currentYear = new Date().getFullYear();
5709                  minYear = parseInt(yearSplit[0], 10);
5710                  maxYear = parseInt(yearSplit[1], 10);
5711                  if ( yearSplit[0].match(/[+\-].*/) ) {
5712                      minYear += currentYear;
5713                  }
5714                  if ( yearSplit[1].match(/[+\-].*/) ) {
5715                      maxYear += currentYear;
5716                  }
5717              }
5718  
5719          return ((!minDate || date.getTime() >= minDate.getTime()) &&
5720              (!maxDate || date.getTime() <= maxDate.getTime()) &&
5721              (!minYear || date.getFullYear() >= minYear) &&
5722              (!maxYear || date.getFullYear() <= maxYear));
5723      },
5724  
5725      /* Provide the configuration settings for formatting/parsing. */
5726      _getFormatConfig: function(inst) {
5727          var shortYearCutoff = this._get(inst, "shortYearCutoff");
5728          shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
5729              new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
5730          return {shortYearCutoff: shortYearCutoff,
5731              dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
5732              monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
5733      },
5734  
5735      /* Format the given date for display. */
5736      _formatDate: function(inst, day, month, year) {
5737          if (!day) {
5738              inst.currentDay = inst.selectedDay;
5739              inst.currentMonth = inst.selectedMonth;
5740              inst.currentYear = inst.selectedYear;
5741          }
5742          var date = (day ? (typeof day === "object" ? day :
5743              this._daylightSavingAdjust(new Date(year, month, day))) :
5744              this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
5745          return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
5746      }
5747  });
5748  
5749  /*
5750   * Bind hover events for datepicker elements.
5751   * Done via delegate so the binding only occurs once in the lifetime of the parent div.
5752   * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
5753   */
5754  function datepicker_bindHover(dpDiv) {
5755      var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
5756      return dpDiv.delegate(selector, "mouseout", function() {
5757              $(this).removeClass("ui-state-hover");
5758              if (this.className.indexOf("ui-datepicker-prev") !== -1) {
5759                  $(this).removeClass("ui-datepicker-prev-hover");
5760              }
5761              if (this.className.indexOf("ui-datepicker-next") !== -1) {
5762                  $(this).removeClass("ui-datepicker-next-hover");
5763              }
5764          })
5765          .delegate( selector, "mouseover", datepicker_handleMouseover );
5766  }
5767  
5768  function datepicker_handleMouseover() {
5769      if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
5770          $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
5771          $(this).addClass("ui-state-hover");
5772          if (this.className.indexOf("ui-datepicker-prev") !== -1) {
5773              $(this).addClass("ui-datepicker-prev-hover");
5774          }
5775          if (this.className.indexOf("ui-datepicker-next") !== -1) {
5776              $(this).addClass("ui-datepicker-next-hover");
5777          }
5778      }
5779  }
5780  
5781  /* jQuery extend now ignores nulls! */
5782  function datepicker_extendRemove(target, props) {
5783      $.extend(target, props);
5784      for (var name in props) {
5785          if (props[name] == null) {
5786              target[name] = props[name];
5787          }
5788      }
5789      return target;
5790  }
5791  
5792  /* Invoke the datepicker functionality.
5793     @param  options  string - a command, optionally followed by additional parameters or
5794                      Object - settings for attaching new datepicker functionality
5795     @return  jQuery object */
5796  $.fn.datepicker = function(options){
5797  
5798      /* Verify an empty collection wasn't passed - Fixes #6976 */
5799      if ( !this.length ) {
5800          return this;
5801      }
5802  
5803      /* Initialise the date picker. */
5804      if (!$.datepicker.initialized) {
5805          $(document).mousedown($.datepicker._checkExternalClick);
5806          $.datepicker.initialized = true;
5807      }
5808  
5809      /* Append datepicker main container to body if not exist. */
5810      if ($("#"+$.datepicker._mainDivId).length === 0) {
5811          $("body").append($.datepicker.dpDiv);
5812      }
5813  
5814      var otherArgs = Array.prototype.slice.call(arguments, 1);
5815      if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
5816          return $.datepicker["_" + options + "Datepicker"].
5817              apply($.datepicker, [this[0]].concat(otherArgs));
5818      }
5819      if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
5820          return $.datepicker["_" + options + "Datepicker"].
5821              apply($.datepicker, [this[0]].concat(otherArgs));
5822      }
5823      return this.each(function() {
5824          typeof options === "string" ?
5825              $.datepicker["_" + options + "Datepicker"].
5826                  apply($.datepicker, [this].concat(otherArgs)) :
5827              $.datepicker._attachDatepicker(this, options);
5828      });
5829  };
5830  
5831  $.datepicker = new Datepicker(); // singleton instance
5832  $.datepicker.initialized = false;
5833  $.datepicker.uuid = new Date().getTime();
5834  $.datepicker.version = "1.11.4";
5835  
5836  var datepicker = $.datepicker;
5837  
5838  
5839  /*!
5840   * jQuery UI Draggable 1.11.4
5841   * http://jqueryui.com
5842   *
5843   * Copyright jQuery Foundation and other contributors
5844   * Released under the MIT license.
5845   * http://jquery.org/license
5846   *
5847   * http://api.jqueryui.com/draggable/
5848   */
5849  
5850  
5851  $.widget("ui.draggable", $.ui.mouse, {
5852      version: "1.11.4",
5853      widgetEventPrefix: "drag",
5854      options: {
5855          addClasses: true,
5856          appendTo: "parent",
5857          axis: false,
5858          connectToSortable: false,
5859          containment: false,
5860          cursor: "auto",
5861          cursorAt: false,
5862          grid: false,
5863          handle: false,
5864          helper: "original",
5865          iframeFix: false,
5866          opacity: false,
5867          refreshPositions: false,
5868          revert: false,
5869          revertDuration: 500,
5870          scope: "default",
5871          scroll: true,
5872          scrollSensitivity: 20,
5873          scrollSpeed: 20,
5874          snap: false,
5875          snapMode: "both",
5876          snapTolerance: 20,
5877          stack: false,
5878          zIndex: false,
5879  
5880          // callbacks
5881          drag: null,
5882          start: null,
5883          stop: null
5884      },
5885      _create: function() {
5886  
5887          if ( this.options.helper === "original" ) {
5888              this._setPositionRelative();
5889          }
5890          if (this.options.addClasses){
5891              this.element.addClass("ui-draggable");
5892          }
5893          if (this.options.disabled){
5894              this.element.addClass("ui-draggable-disabled");
5895          }
5896          this._setHandleClassName();
5897  
5898          this._mouseInit();
5899      },
5900  
5901      _setOption: function( key, value ) {
5902          this._super( key, value );
5903          if ( key === "handle" ) {
5904              this._removeHandleClassName();
5905              this._setHandleClassName();
5906          }
5907      },
5908  
5909      _destroy: function() {
5910          if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
5911              this.destroyOnClear = true;
5912              return;
5913          }
5914          this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
5915          this._removeHandleClassName();
5916          this._mouseDestroy();
5917      },
5918  
5919      _mouseCapture: function(event) {
5920          var o = this.options;
5921  
5922          this._blurActiveElement( event );
5923  
5924          // among others, prevent a drag on a resizable-handle
5925          if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
5926              return false;
5927          }
5928  
5929          //Quit if we're not on a valid handle
5930          this.handle = this._getHandle(event);
5931          if (!this.handle) {
5932              return false;
5933          }
5934  
5935          this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
5936  
5937          return true;
5938  
5939      },
5940  
5941      _blockFrames: function( selector ) {
5942          this.iframeBlocks = this.document.find( selector ).map(function() {
5943              var iframe = $( this );
5944  
5945              return $( "<div>" )
5946                  .css( "position", "absolute" )
5947                  .appendTo( iframe.parent() )
5948                  .outerWidth( iframe.outerWidth() )
5949                  .outerHeight( iframe.outerHeight() )
5950                  .offset( iframe.offset() )[ 0 ];
5951          });
5952      },
5953  
5954      _unblockFrames: function() {
5955          if ( this.iframeBlocks ) {
5956              this.iframeBlocks.remove();
5957              delete this.iframeBlocks;
5958          }
5959      },
5960  
5961      _blurActiveElement: function( event ) {
5962          var document = this.document[ 0 ];
5963  
5964          // Only need to blur if the event occurred on the draggable itself, see #10527
5965          if ( !this.handleElement.is( event.target ) ) {
5966              return;
5967          }
5968  
5969          // support: IE9
5970          // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
5971          try {
5972  
5973              // Support: IE9, IE10
5974              // If the <body> is blurred, IE will switch windows, see #9520
5975              if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
5976  
5977                  // Blur any element that currently has focus, see #4261
5978                  $( document.activeElement ).blur();
5979              }
5980          } catch ( error ) {}
5981      },
5982  
5983      _mouseStart: function(event) {
5984  
5985          var o = this.options;
5986  
5987          //Create and append the visible helper
5988          this.helper = this._createHelper(event);
5989  
5990          this.helper.addClass("ui-draggable-dragging");
5991  
5992          //Cache the helper size
5993          this._cacheHelperProportions();
5994  
5995          //If ddmanager is used for droppables, set the global draggable
5996          if ($.ui.ddmanager) {
5997              $.ui.ddmanager.current = this;
5998          }
5999  
6000          /*
6001           * - Position generation -
6002           * This block generates everything position related - it's the core of draggables.
6003           */
6004  
6005          //Cache the margins of the original element
6006          this._cacheMargins();
6007  
6008          //Store the helper's css position
6009          this.cssPosition = this.helper.css( "position" );
6010          this.scrollParent = this.helper.scrollParent( true );
6011          this.offsetParent = this.helper.offsetParent();
6012          this.hasFixedAncestor = this.helper.parents().filter(function() {
6013                  return $( this ).css( "position" ) === "fixed";
6014              }).length > 0;
6015  
6016          //The element's absolute position on the page minus margins
6017          this.positionAbs = this.element.offset();
6018          this._refreshOffsets( event );
6019  
6020          //Generate the original position
6021          this.originalPosition = this.position = this._generatePosition( event, false );
6022          this.originalPageX = event.pageX;
6023          this.originalPageY = event.pageY;
6024  
6025          //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
6026          (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
6027  
6028          //Set a containment if given in the options
6029          this._setContainment();
6030  
6031          //Trigger event + callbacks
6032          if (this._trigger("start", event) === false) {
6033              this._clear();
6034              return false;
6035          }
6036  
6037          //Recache the helper size
6038          this._cacheHelperProportions();
6039  
6040          //Prepare the droppable offsets
6041          if ($.ui.ddmanager && !o.dropBehaviour) {
6042              $.ui.ddmanager.prepareOffsets(this, event);
6043          }
6044  
6045          // Reset helper's right/bottom css if they're set and set explicit width/height instead
6046          // as this prevents resizing of elements with right/bottom set (see #7772)
6047          this._normalizeRightBottom();
6048  
6049          this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
6050  
6051          //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
6052          if ( $.ui.ddmanager ) {
6053              $.ui.ddmanager.dragStart(this, event);
6054          }
6055  
6056          return true;
6057      },
6058  
6059      _refreshOffsets: function( event ) {
6060          this.offset = {
6061              top: this.positionAbs.top - this.margins.top,
6062              left: this.positionAbs.left - this.margins.left,
6063              scroll: false,
6064              parent: this._getParentOffset(),
6065              relative: this._getRelativeOffset()
6066          };
6067  
6068          this.offset.click = {
6069              left: event.pageX - this.offset.left,
6070              top: event.pageY - this.offset.top
6071          };
6072      },
6073  
6074      _mouseDrag: function(event, noPropagation) {
6075          // reset any necessary cached properties (see #5009)
6076          if ( this.hasFixedAncestor ) {
6077              this.offset.parent = this._getParentOffset();
6078          }
6079  
6080          //Compute the helpers position
6081          this.position = this._generatePosition( event, true );
6082          this.positionAbs = this._convertPositionTo("absolute");
6083  
6084          //Call plugins and callbacks and use the resulting position if something is returned
6085          if (!noPropagation) {
6086              var ui = this._uiHash();
6087              if (this._trigger("drag", event, ui) === false) {
6088                  this._mouseUp({});
6089                  return false;
6090              }
6091              this.position = ui.position;
6092          }
6093  
6094          this.helper[ 0 ].style.left = this.position.left + "px";
6095          this.helper[ 0 ].style.top = this.position.top + "px";
6096  
6097          if ($.ui.ddmanager) {
6098              $.ui.ddmanager.drag(this, event);
6099          }
6100  
6101          return false;
6102      },
6103  
6104      _mouseStop: function(event) {
6105  
6106          //If we are using droppables, inform the manager about the drop
6107          var that = this,
6108              dropped = false;
6109          if ($.ui.ddmanager && !this.options.dropBehaviour) {
6110              dropped = $.ui.ddmanager.drop(this, event);
6111          }
6112  
6113          //if a drop comes from outside (a sortable)
6114          if (this.dropped) {
6115              dropped = this.dropped;
6116              this.dropped = false;
6117          }
6118  
6119          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))) {
6120              $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
6121                  if (that._trigger("stop", event) !== false) {
6122                      that._clear();
6123                  }
6124              });
6125          } else {
6126              if (this._trigger("stop", event) !== false) {
6127                  this._clear();
6128              }
6129          }
6130  
6131          return false;
6132      },
6133  
6134      _mouseUp: function( event ) {
6135          this._unblockFrames();
6136  
6137          //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
6138          if ( $.ui.ddmanager ) {
6139              $.ui.ddmanager.dragStop(this, event);
6140          }
6141  
6142          // Only need to focus if the event occurred on the draggable itself, see #10527
6143          if ( this.handleElement.is( event.target ) ) {
6144              // The interaction is over; whether or not the click resulted in a drag, focus the element
6145              this.element.focus();
6146          }
6147  
6148          return $.ui.mouse.prototype._mouseUp.call(this, event);
6149      },
6150  
6151      cancel: function() {
6152  
6153          if (this.helper.is(".ui-draggable-dragging")) {
6154              this._mouseUp({});
6155          } else {
6156              this._clear();
6157          }
6158  
6159          return this;
6160  
6161      },
6162  
6163      _getHandle: function(event) {
6164          return this.options.handle ?
6165              !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
6166              true;
6167      },
6168  
6169      _setHandleClassName: function() {
6170          this.handleElement = this.options.handle ?
6171              this.element.find( this.options.handle ) : this.element;
6172          this.handleElement.addClass( "ui-draggable-handle" );
6173      },
6174  
6175      _removeHandleClassName: function() {
6176          this.handleElement.removeClass( "ui-draggable-handle" );
6177      },
6178  
6179      _createHelper: function(event) {
6180  
6181          var o = this.options,
6182              helperIsFunction = $.isFunction( o.helper ),
6183              helper = helperIsFunction ?
6184                  $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
6185                  ( o.helper === "clone" ?
6186                      this.element.clone().removeAttr( "id" ) :
6187                      this.element );
6188  
6189          if (!helper.parents("body").length) {
6190              helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
6191          }
6192  
6193          // http://bugs.jqueryui.com/ticket/9446
6194          // a helper function can return the original element
6195          // which wouldn't have been set to relative in _create
6196          if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
6197              this._setPositionRelative();
6198          }
6199  
6200          if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
6201              helper.css("position", "absolute");
6202          }
6203  
6204          return helper;
6205  
6206      },
6207  
6208      _setPositionRelative: function() {
6209          if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
6210              this.element[ 0 ].style.position = "relative";
6211          }
6212      },
6213  
6214      _adjustOffsetFromHelper: function(obj) {
6215          if (typeof obj === "string") {
6216              obj = obj.split(" ");
6217          }
6218          if ($.isArray(obj)) {
6219              obj = { left: +obj[0], top: +obj[1] || 0 };
6220          }
6221          if ("left" in obj) {
6222              this.offset.click.left = obj.left + this.margins.left;
6223          }
6224          if ("right" in obj) {
6225              this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
6226          }
6227          if ("top" in obj) {
6228              this.offset.click.top = obj.top + this.margins.top;
6229          }
6230          if ("bottom" in obj) {
6231              this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
6232          }
6233      },
6234  
6235      _isRootNode: function( element ) {
6236          return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
6237      },
6238  
6239      _getParentOffset: function() {
6240  
6241          //Get the offsetParent and cache its position
6242          var po = this.offsetParent.offset(),
6243              document = this.document[ 0 ];
6244  
6245          // This is a special case where we need to modify a offset calculated on start, since the following happened:
6246          // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
6247          // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
6248          //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
6249          if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
6250              po.left += this.scrollParent.scrollLeft();
6251              po.top += this.scrollParent.scrollTop();
6252          }
6253  
6254          if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
6255              po = { top: 0, left: 0 };
6256          }
6257  
6258          return {
6259              top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
6260              left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
6261          };
6262  
6263      },
6264  
6265      _getRelativeOffset: function() {
6266          if ( this.cssPosition !== "relative" ) {
6267              return { top: 0, left: 0 };
6268          }
6269  
6270          var p = this.element.position(),
6271              scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
6272  
6273          return {
6274              top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
6275              left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
6276          };
6277  
6278      },
6279  
6280      _cacheMargins: function() {
6281          this.margins = {
6282              left: (parseInt(this.element.css("marginLeft"), 10) || 0),
6283              top: (parseInt(this.element.css("marginTop"), 10) || 0),
6284              right: (parseInt(this.element.css("marginRight"), 10) || 0),
6285              bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
6286          };
6287      },
6288  
6289      _cacheHelperProportions: function() {
6290          this.helperProportions = {
6291              width: this.helper.outerWidth(),
6292              height: this.helper.outerHeight()
6293          };
6294      },
6295  
6296      _setContainment: function() {
6297  
6298          var isUserScrollable, c, ce,
6299              o = this.options,
6300              document = this.document[ 0 ];
6301  
6302          this.relativeContainer = null;
6303  
6304          if ( !o.containment ) {
6305              this.containment = null;
6306              return;
6307          }
6308  
6309          if ( o.containment === "window" ) {
6310              this.containment = [
6311                  $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
6312                  $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
6313                  $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
6314                  $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
6315              ];
6316              return;
6317          }
6318  
6319          if ( o.containment === "document") {
6320              this.containment = [
6321                  0,
6322                  0,
6323                  $( document ).width() - this.helperProportions.width - this.margins.left,
6324                  ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
6325              ];
6326              return;
6327          }
6328  
6329          if ( o.containment.constructor === Array ) {
6330              this.containment = o.containment;
6331              return;
6332          }
6333  
6334          if ( o.containment === "parent" ) {
6335              o.containment = this.helper[ 0 ].parentNode;
6336          }
6337  
6338          c = $( o.containment );
6339          ce = c[ 0 ];
6340  
6341          if ( !ce ) {
6342              return;
6343          }
6344  
6345          isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
6346  
6347          this.containment = [
6348              ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
6349              ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
6350              ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
6351                  ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
6352                  ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
6353                  this.helperProportions.width -
6354                  this.margins.left -
6355                  this.margins.right,
6356              ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
6357                  ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
6358                  ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
6359                  this.helperProportions.height -
6360                  this.margins.top -
6361                  this.margins.bottom
6362          ];
6363          this.relativeContainer = c;
6364      },
6365  
6366      _convertPositionTo: function(d, pos) {
6367  
6368          if (!pos) {
6369              pos = this.position;
6370          }
6371  
6372          var mod = d === "absolute" ? 1 : -1,
6373              scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
6374  
6375          return {
6376              top: (
6377                  pos.top    +                                                                // The absolute mouse position
6378                  this.offset.relative.top * mod +                                        // Only for relative positioned nodes: Relative offset from element to offset parent
6379                  this.offset.parent.top * mod -                                        // The offsetParent's offset without borders (offset + border)
6380                  ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
6381              ),
6382              left: (
6383                  pos.left +                                                                // The absolute mouse position
6384                  this.offset.relative.left * mod +                                        // Only for relative positioned nodes: Relative offset from element to offset parent
6385                  this.offset.parent.left * mod    -                                        // The offsetParent's offset without borders (offset + border)
6386                  ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
6387              )
6388          };
6389  
6390      },
6391  
6392      _generatePosition: function( event, constrainPosition ) {
6393  
6394          var containment, co, top, left,
6395              o = this.options,
6396              scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
6397              pageX = event.pageX,
6398              pageY = event.pageY;
6399  
6400          // Cache the scroll
6401          if ( !scrollIsRootNode || !this.offset.scroll ) {
6402              this.offset.scroll = {
6403                  top: this.scrollParent.scrollTop(),
6404                  left: this.scrollParent.scrollLeft()
6405              };
6406          }
6407  
6408          /*
6409           * - Position constraining -
6410           * Constrain the position to a mix of grid, containment.
6411           */
6412  
6413          // If we are not dragging yet, we won't check for options
6414          if ( constrainPosition ) {
6415              if ( this.containment ) {
6416                  if ( this.relativeContainer ){
6417                      co = this.relativeContainer.offset();
6418                      containment = [
6419                          this.containment[ 0 ] + co.left,
6420                          this.containment[ 1 ] + co.top,
6421                          this.containment[ 2 ] + co.left,
6422                          this.containment[ 3 ] + co.top
6423                      ];
6424                  } else {
6425                      containment = this.containment;
6426                  }
6427  
6428                  if (event.pageX - this.offset.click.left < containment[0]) {
6429                      pageX = containment[0] + this.offset.click.left;
6430                  }
6431                  if (event.pageY - this.offset.click.top < containment[1]) {
6432                      pageY = containment[1] + this.offset.click.top;
6433                  }
6434                  if (event.pageX - this.offset.click.left > containment[2]) {
6435                      pageX = containment[2] + this.offset.click.left;
6436                  }
6437                  if (event.pageY - this.offset.click.top > containment[3]) {
6438                      pageY = containment[3] + this.offset.click.top;
6439                  }
6440              }
6441  
6442              if (o.grid) {
6443                  //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
6444                  top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
6445                  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;
6446  
6447                  left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
6448                  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;
6449              }
6450  
6451              if ( o.axis === "y" ) {
6452                  pageX = this.originalPageX;
6453              }
6454  
6455              if ( o.axis === "x" ) {
6456                  pageY = this.originalPageY;
6457              }
6458          }
6459  
6460          return {
6461              top: (
6462                  pageY -                                                                    // The absolute mouse position
6463                  this.offset.click.top    -                                                // Click offset (relative to the element)
6464                  this.offset.relative.top -                                                // Only for relative positioned nodes: Relative offset from element to offset parent
6465                  this.offset.parent.top +                                                // The offsetParent's offset without borders (offset + border)
6466                  ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
6467              ),
6468              left: (
6469                  pageX -                                                                    // The absolute mouse position
6470                  this.offset.click.left -                                                // Click offset (relative to the element)
6471                  this.offset.relative.left -                                                // Only for relative positioned nodes: Relative offset from element to offset parent
6472                  this.offset.parent.left +                                                // The offsetParent's offset without borders (offset + border)
6473                  ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
6474              )
6475          };
6476  
6477      },
6478  
6479      _clear: function() {
6480          this.helper.removeClass("ui-draggable-dragging");
6481          if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
6482              this.helper.remove();
6483          }
6484          this.helper = null;
6485          this.cancelHelperRemoval = false;
6486          if ( this.destroyOnClear ) {
6487              this.destroy();
6488          }
6489      },
6490  
6491      _normalizeRightBottom: function() {
6492          if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
6493              this.helper.width( this.helper.width() );
6494              this.helper.css( "right", "auto" );
6495          }
6496          if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
6497              this.helper.height( this.helper.height() );
6498              this.helper.css( "bottom", "auto" );
6499          }
6500      },
6501  
6502      // From now on bulk stuff - mainly helpers
6503  
6504      _trigger: function( type, event, ui ) {
6505          ui = ui || this._uiHash();
6506          $.ui.plugin.call( this, type, [ event, ui, this ], true );
6507  
6508          // Absolute position and offset (see #6884 ) have to be recalculated after plugins
6509          if ( /^(drag|start|stop)/.test( type ) ) {
6510              this.positionAbs = this._convertPositionTo( "absolute" );
6511              ui.offset = this.positionAbs;
6512          }
6513          return $.Widget.prototype._trigger.call( this, type, event, ui );
6514      },
6515  
6516      plugins: {},
6517  
6518      _uiHash: function() {
6519          return {
6520              helper: this.helper,
6521              position: this.position,
6522              originalPosition: this.originalPosition,
6523              offset: this.positionAbs
6524          };
6525      }
6526  
6527  });
6528  
6529  $.ui.plugin.add( "draggable", "connectToSortable", {
6530      start: function( event, ui, draggable ) {
6531          var uiSortable = $.extend( {}, ui, {
6532              item: draggable.element
6533          });
6534  
6535          draggable.sortables = [];
6536          $( draggable.options.connectToSortable ).each(function() {
6537              var sortable = $( this ).sortable( "instance" );
6538  
6539              if ( sortable && !sortable.options.disabled ) {
6540                  draggable.sortables.push( sortable );
6541  
6542                  // refreshPositions is called at drag start to refresh the containerCache
6543                  // which is used in drag. This ensures it's initialized and synchronized
6544                  // with any changes that might have happened on the page since initialization.
6545                  sortable.refreshPositions();
6546                  sortable._trigger("activate", event, uiSortable);
6547              }
6548          });
6549      },
6550      stop: function( event, ui, draggable ) {
6551          var uiSortable = $.extend( {}, ui, {
6552              item: draggable.element
6553          });
6554  
6555          draggable.cancelHelperRemoval = false;
6556  
6557          $.each( draggable.sortables, function() {
6558              var sortable = this;
6559  
6560              if ( sortable.isOver ) {
6561                  sortable.isOver = 0;
6562  
6563                  // Allow this sortable to handle removing the helper
6564                  draggable.cancelHelperRemoval = true;
6565                  sortable.cancelHelperRemoval = false;
6566  
6567                  // Use _storedCSS To restore properties in the sortable,
6568                  // as this also handles revert (#9675) since the draggable
6569                  // may have modified them in unexpected ways (#8809)
6570                  sortable._storedCSS = {
6571                      position: sortable.placeholder.css( "position" ),
6572                      top: sortable.placeholder.css( "top" ),
6573                      left: sortable.placeholder.css( "left" )
6574                  };
6575  
6576                  sortable._mouseStop(event);
6577  
6578                  // Once drag has ended, the sortable should return to using
6579                  // its original helper, not the shared helper from draggable
6580                  sortable.options.helper = sortable.options._helper;
6581              } else {
6582                  // Prevent this Sortable from removing the helper.
6583                  // However, don't set the draggable to remove the helper
6584                  // either as another connected Sortable may yet handle the removal.
6585                  sortable.cancelHelperRemoval = true;
6586  
6587                  sortable._trigger( "deactivate", event, uiSortable );
6588              }
6589          });
6590      },
6591      drag: function( event, ui, draggable ) {
6592          $.each( draggable.sortables, function() {
6593              var innermostIntersecting = false,
6594                  sortable = this;
6595  
6596              // Copy over variables that sortable's _intersectsWith uses
6597              sortable.positionAbs = draggable.positionAbs;
6598              sortable.helperProportions = draggable.helperProportions;
6599              sortable.offset.click = draggable.offset.click;
6600  
6601              if ( sortable._intersectsWith( sortable.containerCache ) ) {
6602                  innermostIntersecting = true;
6603  
6604                  $.each( draggable.sortables, function() {
6605                      // Copy over variables that sortable's _intersectsWith uses
6606                      this.positionAbs = draggable.positionAbs;
6607                      this.helperProportions = draggable.helperProportions;
6608                      this.offset.click = draggable.offset.click;
6609  
6610                      if ( this !== sortable &&
6611                              this._intersectsWith( this.containerCache ) &&
6612                              $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
6613                          innermostIntersecting = false;
6614                      }
6615  
6616                      return innermostIntersecting;
6617                  });
6618              }
6619  
6620              if ( innermostIntersecting ) {
6621                  // If it intersects, we use a little isOver variable and set it once,
6622                  // so that the move-in stuff gets fired only once.
6623                  if ( !sortable.isOver ) {
6624                      sortable.isOver = 1;
6625  
6626                      // Store draggable's parent in case we need to reappend to it later.
6627                      draggable._parent = ui.helper.parent();
6628  
6629                      sortable.currentItem = ui.helper
6630                          .appendTo( sortable.element )
6631                          .data( "ui-sortable-item", true );
6632  
6633                      // Store helper option to later restore it
6634                      sortable.options._helper = sortable.options.helper;
6635  
6636                      sortable.options.helper = function() {
6637                          return ui.helper[ 0 ];
6638                      };
6639  
6640                      // Fire the start events of the sortable with our passed browser event,
6641                      // and our own helper (so it doesn't create a new one)
6642                      event.target = sortable.currentItem[ 0 ];
6643                      sortable._mouseCapture( event, true );
6644                      sortable._mouseStart( event, true, true );
6645  
6646                      // Because the browser event is way off the new appended portlet,
6647                      // modify necessary variables to reflect the changes
6648                      sortable.offset.click.top = draggable.offset.click.top;
6649                      sortable.offset.click.left = draggable.offset.click.left;
6650                      sortable.offset.parent.left -= draggable.offset.parent.left -
6651                          sortable.offset.parent.left;
6652                      sortable.offset.parent.top -= draggable.offset.parent.top -
6653                          sortable.offset.parent.top;
6654  
6655                      draggable._trigger( "toSortable", event );
6656  
6657                      // Inform draggable that the helper is in a valid drop zone,
6658                      // used solely in the revert option to handle "valid/invalid".
6659                      draggable.dropped = sortable.element;
6660  
6661                      // Need to refreshPositions of all sortables in the case that
6662                      // adding to one sortable changes the location of the other sortables (#9675)
6663                      $.each( draggable.sortables, function() {
6664                          this.refreshPositions();
6665                      });
6666  
6667                      // hack so receive/update callbacks work (mostly)
6668                      draggable.currentItem = draggable.element;
6669                      sortable.fromOutside = draggable;
6670                  }
6671  
6672                  if ( sortable.currentItem ) {
6673                      sortable._mouseDrag( event );
6674                      // Copy the sortable's position because the draggable's can potentially reflect
6675                      // a relative position, while sortable is always absolute, which the dragged
6676                      // element has now become. (#8809)
6677                      ui.position = sortable.position;
6678                  }
6679              } else {
6680                  // If it doesn't intersect with the sortable, and it intersected before,
6681                  // we fake the drag stop of the sortable, but make sure it doesn't remove
6682                  // the helper by using cancelHelperRemoval.
6683                  if ( sortable.isOver ) {
6684  
6685                      sortable.isOver = 0;
6686                      sortable.cancelHelperRemoval = true;
6687  
6688                      // Calling sortable's mouseStop would trigger a revert,
6689                      // so revert must be temporarily false until after mouseStop is called.
6690                      sortable.options._revert = sortable.options.revert;
6691                      sortable.options.revert = false;
6692  
6693                      sortable._trigger( "out", event, sortable._uiHash( sortable ) );
6694                      sortable._mouseStop( event, true );
6695  
6696                      // restore sortable behaviors that were modfied
6697                      // when the draggable entered the sortable area (#9481)
6698                      sortable.options.revert = sortable.options._revert;
6699                      sortable.options.helper = sortable.options._helper;
6700  
6701                      if ( sortable.placeholder ) {
6702                          sortable.placeholder.remove();
6703                      }
6704  
6705                      // Restore and recalculate the draggable's offset considering the sortable
6706                      // may have modified them in unexpected ways. (#8809, #10669)
6707                      ui.helper.appendTo( draggable._parent );
6708                      draggable._refreshOffsets( event );
6709                      ui.position = draggable._generatePosition( event, true );
6710  
6711                      draggable._trigger( "fromSortable", event );
6712  
6713                      // Inform draggable that the helper is no longer in a valid drop zone
6714                      draggable.dropped = false;
6715  
6716                      // Need to refreshPositions of all sortables just in case removing
6717                      // from one sortable changes the location of other sortables (#9675)
6718                      $.each( draggable.sortables, function() {
6719                          this.refreshPositions();
6720                      });
6721                  }
6722              }
6723          });
6724      }
6725  });
6726  
6727  $.ui.plugin.add("draggable", "cursor", {
6728      start: function( event, ui, instance ) {
6729          var t = $( "body" ),
6730              o = instance.options;
6731  
6732          if (t.css("cursor")) {
6733              o._cursor = t.css("cursor");
6734          }
6735          t.css("cursor", o.cursor);
6736      },
6737      stop: function( event, ui, instance ) {
6738          var o = instance.options;
6739          if (o._cursor) {
6740              $("body").css("cursor", o._cursor);
6741          }
6742      }
6743  });
6744  
6745  $.ui.plugin.add("draggable", "opacity", {
6746      start: function( event, ui, instance ) {
6747          var t = $( ui.helper ),
6748              o = instance.options;
6749          if (t.css("opacity")) {
6750              o._opacity = t.css("opacity");
6751          }
6752          t.css("opacity", o.opacity);
6753      },
6754      stop: function( event, ui, instance ) {
6755          var o = instance.options;
6756          if (o._opacity) {
6757              $(ui.helper).css("opacity", o._opacity);
6758          }
6759      }
6760  });
6761  
6762  $.ui.plugin.add("draggable", "scroll", {
6763      start: function( event, ui, i ) {
6764          if ( !i.scrollParentNotHidden ) {
6765              i.scrollParentNotHidden = i.helper.scrollParent( false );
6766          }
6767  
6768          if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
6769              i.overflowOffset = i.scrollParentNotHidden.offset();
6770          }
6771      },
6772      drag: function( event, ui, i  ) {
6773  
6774          var o = i.options,
6775              scrolled = false,
6776              scrollParent = i.scrollParentNotHidden[ 0 ],
6777              document = i.document[ 0 ];
6778  
6779          if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
6780              if ( !o.axis || o.axis !== "x" ) {
6781                  if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
6782                      scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
6783                  } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
6784                      scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
6785                  }
6786              }
6787  
6788              if ( !o.axis || o.axis !== "y" ) {
6789                  if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
6790                      scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
6791                  } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
6792                      scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
6793                  }
6794              }
6795  
6796          } else {
6797  
6798              if (!o.axis || o.axis !== "x") {
6799                  if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
6800                      scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
6801                  } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
6802                      scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
6803                  }
6804              }
6805  
6806              if (!o.axis || o.axis !== "y") {
6807                  if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
6808                      scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
6809                  } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
6810                      scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
6811                  }
6812              }
6813  
6814          }
6815  
6816          if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
6817              $.ui.ddmanager.prepareOffsets(i, event);
6818          }
6819  
6820      }
6821  });
6822  
6823  $.ui.plugin.add("draggable", "snap", {
6824      start: function( event, ui, i ) {
6825  
6826          var o = i.options;
6827  
6828          i.snapElements = [];
6829  
6830          $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
6831              var $t = $(this),
6832                  $o = $t.offset();
6833              if (this !== i.element[0]) {
6834                  i.snapElements.push({
6835                      item: this,
6836                      width: $t.outerWidth(), height: $t.outerHeight(),
6837                      top: $o.top, left: $o.left
6838                  });
6839              }
6840          });
6841  
6842      },
6843      drag: function( event, ui, inst ) {
6844  
6845          var ts, bs, ls, rs, l, r, t, b, i, first,
6846              o = inst.options,
6847              d = o.snapTolerance,
6848              x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
6849              y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
6850  
6851          for (i = inst.snapElements.length - 1; i >= 0; i--){
6852  
6853              l = inst.snapElements[i].left - inst.margins.left;
6854              r = l + inst.snapElements[i].width;
6855              t = inst.snapElements[i].top - inst.margins.top;
6856              b = t + inst.snapElements[i].height;
6857  
6858              if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
6859                  if (inst.snapElements[i].snapping) {
6860                      (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
6861                  }
6862                  inst.snapElements[i].snapping = false;
6863                  continue;
6864              }
6865  
6866              if (o.snapMode !== "inner") {
6867                  ts = Math.abs(t - y2) <= d;
6868                  bs = Math.abs(b - y1) <= d;
6869                  ls = Math.abs(l - x2) <= d;
6870                  rs = Math.abs(r - x1) <= d;
6871                  if (ts) {
6872                      ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
6873                  }
6874                  if (bs) {
6875                      ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
6876                  }
6877                  if (ls) {
6878                      ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
6879                  }
6880                  if (rs) {
6881                      ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
6882                  }
6883              }
6884  
6885              first = (ts || bs || ls || rs);
6886  
6887              if (o.snapMode !== "outer") {
6888                  ts = Math.abs(t - y1) <= d;
6889                  bs = Math.abs(b - y2) <= d;
6890                  ls = Math.abs(l - x1) <= d;
6891                  rs = Math.abs(r - x2) <= d;
6892                  if (ts) {
6893                      ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
6894                  }
6895                  if (bs) {
6896                      ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
6897                  }
6898                  if (ls) {
6899                      ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
6900                  }
6901                  if (rs) {
6902                      ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
6903                  }
6904              }
6905  
6906              if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
6907                  (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
6908              }
6909              inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
6910  
6911          }
6912  
6913      }
6914  });
6915  
6916  $.ui.plugin.add("draggable", "stack", {
6917      start: function( event, ui, instance ) {
6918          var min,
6919              o = instance.options,
6920              group = $.makeArray($(o.stack)).sort(function(a, b) {
6921                  return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
6922              });
6923  
6924          if (!group.length) { return; }
6925  
6926          min = parseInt($(group[0]).css("zIndex"), 10) || 0;
6927          $(group).each(function(i) {
6928              $(this).css("zIndex", min + i);
6929          });
6930          this.css("zIndex", (min + group.length));
6931      }
6932  });
6933  
6934  $.ui.plugin.add("draggable", "zIndex", {
6935      start: function( event, ui, instance ) {
6936          var t = $( ui.helper ),
6937              o = instance.options;
6938  
6939          if (t.css("zIndex")) {
6940              o._zIndex = t.css("zIndex");
6941          }
6942          t.css("zIndex", o.zIndex);
6943      },
6944      stop: function( event, ui, instance ) {
6945          var o = instance.options;
6946  
6947          if (o._zIndex) {
6948              $(ui.helper).css("zIndex", o._zIndex);
6949          }
6950      }
6951  });
6952  
6953  var draggable = $.ui.draggable;
6954  
6955  
6956  /*!
6957   * jQuery UI Resizable 1.11.4
6958   * http://jqueryui.com
6959   *
6960   * Copyright jQuery Foundation and other contributors
6961   * Released under the MIT license.
6962   * http://jquery.org/license
6963   *
6964   * http://api.jqueryui.com/resizable/
6965   */
6966  
6967  
6968  $.widget("ui.resizable", $.ui.mouse, {
6969      version: "1.11.4",
6970      widgetEventPrefix: "resize",
6971      options: {
6972          alsoResize: false,
6973          animate: false,
6974          animateDuration: "slow",
6975          animateEasing: "swing",
6976          aspectRatio: false,
6977          autoHide: false,
6978          containment: false,
6979          ghost: false,
6980          grid: false,
6981          handles: "e,s,se",
6982          helper: false,
6983          maxHeight: null,
6984          maxWidth: null,
6985          minHeight: 10,
6986          minWidth: 10,
6987          // See #7960
6988          zIndex: 90,
6989  
6990          // callbacks
6991          resize: null,
6992          start: null,
6993          stop: null
6994      },
6995  
6996      _num: function( value ) {
6997          return parseInt( value, 10 ) || 0;
6998      },
6999  
7000      _isNumber: function( value ) {
7001          return !isNaN( parseInt( value, 10 ) );
7002      },
7003  
7004      _hasScroll: function( el, a ) {
7005  
7006          if ( $( el ).css( "overflow" ) === "hidden") {
7007              return false;
7008          }
7009  
7010          var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
7011              has = false;
7012  
7013          if ( el[ scroll ] > 0 ) {
7014              return true;
7015          }
7016  
7017          // TODO: determine which cases actually cause this to happen
7018          // if the element doesn't have the scroll set, see if it's possible to
7019          // set the scroll
7020          el[ scroll ] = 1;
7021          has = ( el[ scroll ] > 0 );
7022          el[ scroll ] = 0;
7023          return has;
7024      },
7025  
7026      _create: function() {
7027  
7028          var n, i, handle, axis, hname,
7029              that = this,
7030              o = this.options;
7031          this.element.addClass("ui-resizable");
7032  
7033          $.extend(this, {
7034              _aspectRatio: !!(o.aspectRatio),
7035              aspectRatio: o.aspectRatio,
7036              originalElement: this.element,
7037              _proportionallyResizeElements: [],
7038              _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
7039          });
7040  
7041          // Wrap the element if it cannot hold child nodes
7042          if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) {
7043  
7044              this.element.wrap(
7045                  $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
7046                      position: this.element.css("position"),
7047                      width: this.element.outerWidth(),
7048                      height: this.element.outerHeight(),
7049                      top: this.element.css("top"),
7050                      left: this.element.css("left")
7051                  })
7052              );
7053  
7054              this.element = this.element.parent().data(
7055                  "ui-resizable", this.element.resizable( "instance" )
7056              );
7057  
7058              this.elementIsWrapper = true;
7059  
7060              this.element.css({
7061                  marginLeft: this.originalElement.css("marginLeft"),
7062                  marginTop: this.originalElement.css("marginTop"),
7063                  marginRight: this.originalElement.css("marginRight"),
7064                  marginBottom: this.originalElement.css("marginBottom")
7065              });
7066              this.originalElement.css({
7067                  marginLeft: 0,
7068                  marginTop: 0,
7069                  marginRight: 0,
7070                  marginBottom: 0
7071              });
7072              // support: Safari
7073              // Prevent Safari textarea resize
7074              this.originalResizeStyle = this.originalElement.css("resize");
7075              this.originalElement.css("resize", "none");
7076  
7077              this._proportionallyResizeElements.push( this.originalElement.css({
7078                  position: "static",
7079                  zoom: 1,
7080                  display: "block"
7081              }) );
7082  
7083              // support: IE9
7084              // avoid IE jump (hard set the margin)
7085              this.originalElement.css({ margin: this.originalElement.css("margin") });
7086  
7087              this._proportionallyResize();
7088          }
7089  
7090          this.handles = o.handles ||
7091              ( !$(".ui-resizable-handle", this.element).length ?
7092                  "e,s,se" : {
7093                      n: ".ui-resizable-n",
7094                      e: ".ui-resizable-e",
7095                      s: ".ui-resizable-s",
7096                      w: ".ui-resizable-w",
7097                      se: ".ui-resizable-se",
7098                      sw: ".ui-resizable-sw",
7099                      ne: ".ui-resizable-ne",
7100                      nw: ".ui-resizable-nw"
7101                  } );
7102  
7103          this._handles = $();
7104          if ( this.handles.constructor === String ) {
7105  
7106              if ( this.handles === "all") {
7107                  this.handles = "n,e,s,w,se,sw,ne,nw";
7108              }
7109  
7110              n = this.handles.split(",");
7111              this.handles = {};
7112  
7113              for (i = 0; i < n.length; i++) {
7114  
7115                  handle = $.trim(n[i]);
7116                  hname = "ui-resizable-" + handle;
7117                  axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
7118  
7119                  axis.css({ zIndex: o.zIndex });
7120  
7121                  // TODO : What's going on here?
7122                  if ("se" === handle) {
7123                      axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
7124                  }
7125  
7126                  this.handles[handle] = ".ui-resizable-" + handle;
7127                  this.element.append(axis);
7128              }
7129  
7130          }
7131  
7132          this._renderAxis = function(target) {
7133  
7134              var i, axis, padPos, padWrapper;
7135  
7136              target = target || this.element;
7137  
7138              for (i in this.handles) {
7139  
7140                  if (this.handles[i].constructor === String) {
7141                      this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
7142                  } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
7143                      this.handles[ i ] = $( this.handles[ i ] );
7144                      this._on( this.handles[ i ], { "mousedown": that._mouseDown });
7145                  }
7146  
7147                  if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) {
7148  
7149                      axis = $(this.handles[i], this.element);
7150  
7151                      padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
7152  
7153                      padPos = [ "padding",
7154                          /ne|nw|n/.test(i) ? "Top" :
7155                          /se|sw|s/.test(i) ? "Bottom" :
7156                          /^e$/.test(i) ? "Right" : "Left" ].join("");
7157  
7158                      target.css(padPos, padWrapper);
7159  
7160                      this._proportionallyResize();
7161                  }
7162  
7163                  this._handles = this._handles.add( this.handles[ i ] );
7164              }
7165          };
7166  
7167          // TODO: make renderAxis a prototype function
7168          this._renderAxis(this.element);
7169  
7170          this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
7171          this._handles.disableSelection();
7172  
7173          this._handles.mouseover(function() {
7174              if (!that.resizing) {
7175                  if (this.className) {
7176                      axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
7177                  }
7178                  that.axis = axis && axis[1] ? axis[1] : "se";
7179              }
7180          });
7181  
7182          if (o.autoHide) {
7183              this._handles.hide();
7184              $(this.element)
7185                  .addClass("ui-resizable-autohide")
7186                  .mouseenter(function() {
7187                      if (o.disabled) {
7188                          return;
7189                      }
7190                      $(this).removeClass("ui-resizable-autohide");
7191                      that._handles.show();
7192                  })
7193                  .mouseleave(function() {
7194                      if (o.disabled) {
7195                          return;
7196                      }
7197                      if (!that.resizing) {
7198                          $(this).addClass("ui-resizable-autohide");
7199                          that._handles.hide();
7200                      }
7201                  });
7202          }
7203  
7204          this._mouseInit();
7205      },
7206  
7207      _destroy: function() {
7208  
7209          this._mouseDestroy();
7210  
7211          var wrapper,
7212              _destroy = function(exp) {
7213                  $(exp)
7214                      .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
7215                      .removeData("resizable")
7216                      .removeData("ui-resizable")
7217                      .unbind(".resizable")
7218                      .find(".ui-resizable-handle")
7219                          .remove();
7220              };
7221  
7222          // TODO: Unwrap at same DOM position
7223          if (this.elementIsWrapper) {
7224              _destroy(this.element);
7225              wrapper = this.element;
7226              this.originalElement.css({
7227                  position: wrapper.css("position"),
7228                  width: wrapper.outerWidth(),
7229                  height: wrapper.outerHeight(),
7230                  top: wrapper.css("top"),
7231                  left: wrapper.css("left")
7232              }).insertAfter( wrapper );
7233              wrapper.remove();
7234          }
7235  
7236          this.originalElement.css("resize", this.originalResizeStyle);
7237          _destroy(this.originalElement);
7238  
7239          return this;
7240      },
7241  
7242      _mouseCapture: function(event) {
7243          var i, handle,
7244              capture = false;
7245  
7246          for (i in this.handles) {
7247              handle = $(this.handles[i])[0];
7248              if (handle === event.target || $.contains(handle, event.target)) {
7249                  capture = true;
7250              }
7251          }
7252  
7253          return !this.options.disabled && capture;
7254      },
7255  
7256      _mouseStart: function(event) {
7257  
7258          var curleft, curtop, cursor,
7259              o = this.options,
7260              el = this.element;
7261  
7262          this.resizing = true;
7263  
7264          this._renderProxy();
7265  
7266          curleft = this._num(this.helper.css("left"));
7267          curtop = this._num(this.helper.css("top"));
7268  
7269          if (o.containment) {
7270              curleft += $(o.containment).scrollLeft() || 0;
7271              curtop += $(o.containment).scrollTop() || 0;
7272          }
7273  
7274          this.offset = this.helper.offset();
7275          this.position = { left: curleft, top: curtop };
7276  
7277          this.size = this._helper ? {
7278                  width: this.helper.width(),
7279                  height: this.helper.height()
7280              } : {
7281                  width: el.width(),
7282                  height: el.height()
7283              };
7284  
7285          this.originalSize = this._helper ? {
7286                  width: el.outerWidth(),
7287                  height: el.outerHeight()
7288              } : {
7289                  width: el.width(),
7290                  height: el.height()
7291              };
7292  
7293          this.sizeDiff = {
7294              width: el.outerWidth() - el.width(),
7295              height: el.outerHeight() - el.height()
7296          };
7297  
7298          this.originalPosition = { left: curleft, top: curtop };
7299          this.originalMousePosition = { left: event.pageX, top: event.pageY };
7300  
7301          this.aspectRatio = (typeof o.aspectRatio === "number") ?
7302              o.aspectRatio :
7303              ((this.originalSize.width / this.originalSize.height) || 1);
7304  
7305          cursor = $(".ui-resizable-" + this.axis).css("cursor");
7306          $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
7307  
7308          el.addClass("ui-resizable-resizing");
7309          this._propagate("start", event);
7310          return true;
7311      },
7312  
7313      _mouseDrag: function(event) {
7314  
7315          var data, props,
7316              smp = this.originalMousePosition,
7317              a = this.axis,
7318              dx = (event.pageX - smp.left) || 0,
7319              dy = (event.pageY - smp.top) || 0,
7320              trigger = this._change[a];
7321  
7322          this._updatePrevProperties();
7323  
7324          if (!trigger) {
7325              return false;
7326          }
7327  
7328          data = trigger.apply(this, [ event, dx, dy ]);
7329  
7330          this._updateVirtualBoundaries(event.shiftKey);
7331          if (this._aspectRatio || event.shiftKey) {
7332              data = this._updateRatio(data, event);
7333          }
7334  
7335          data = this._respectSize(data, event);
7336  
7337          this._updateCache(data);
7338  
7339          this._propagate("resize", event);
7340  
7341          props = this._applyChanges();
7342  
7343          if ( !this._helper && this._proportionallyResizeElements.length ) {
7344              this._proportionallyResize();
7345          }
7346  
7347          if ( !$.isEmptyObject( props ) ) {
7348              this._updatePrevProperties();
7349              this._trigger( "resize", event, this.ui() );
7350              this._applyChanges();
7351          }
7352  
7353          return false;
7354      },
7355  
7356      _mouseStop: function(event) {
7357  
7358          this.resizing = false;
7359          var pr, ista, soffseth, soffsetw, s, left, top,
7360              o = this.options, that = this;
7361  
7362          if (this._helper) {
7363  
7364              pr = this._proportionallyResizeElements;
7365              ista = pr.length && (/textarea/i).test(pr[0].nodeName);
7366              soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
7367              soffsetw = ista ? 0 : that.sizeDiff.width;
7368  
7369              s = {
7370                  width: (that.helper.width()  - soffsetw),
7371                  height: (that.helper.height() - soffseth)
7372              };
7373              left = (parseInt(that.element.css("left"), 10) +
7374                  (that.position.left - that.originalPosition.left)) || null;
7375              top = (parseInt(that.element.css("top"), 10) +
7376                  (that.position.top - that.originalPosition.top)) || null;
7377  
7378              if (!o.animate) {
7379                  this.element.css($.extend(s, { top: top, left: left }));
7380              }
7381  
7382              that.helper.height(that.size.height);
7383              that.helper.width(that.size.width);
7384  
7385              if (this._helper && !o.animate) {
7386                  this._proportionallyResize();
7387              }
7388          }
7389  
7390          $("body").css("cursor", "auto");
7391  
7392          this.element.removeClass("ui-resizable-resizing");
7393  
7394          this._propagate("stop", event);
7395  
7396          if (this._helper) {
7397              this.helper.remove();
7398          }
7399  
7400          return false;
7401  
7402      },
7403  
7404      _updatePrevProperties: function() {
7405          this.prevPosition = {
7406              top: this.position.top,
7407              left: this.position.left
7408          };
7409          this.prevSize = {
7410              width: this.size.width,
7411              height: this.size.height
7412          };
7413      },
7414  
7415      _applyChanges: function() {
7416          var props = {};
7417  
7418          if ( this.position.top !== this.prevPosition.top ) {
7419              props.top = this.position.top + "px";
7420          }
7421          if ( this.position.left !== this.prevPosition.left ) {
7422              props.left = this.position.left + "px";
7423          }
7424          if ( this.size.width !== this.prevSize.width ) {
7425              props.width = this.size.width + "px";
7426          }
7427          if ( this.size.height !== this.prevSize.height ) {
7428              props.height = this.size.height + "px";
7429          }
7430  
7431          this.helper.css( props );
7432  
7433          return props;
7434      },
7435  
7436      _updateVirtualBoundaries: function(forceAspectRatio) {
7437          var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
7438              o = this.options;
7439  
7440          b = {
7441              minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
7442              maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
7443              minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
7444              maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
7445          };
7446  
7447          if (this._aspectRatio || forceAspectRatio) {
7448              pMinWidth = b.minHeight * this.aspectRatio;
7449              pMinHeight = b.minWidth / this.aspectRatio;
7450              pMaxWidth = b.maxHeight * this.aspectRatio;
7451              pMaxHeight = b.maxWidth / this.aspectRatio;
7452  
7453              if (pMinWidth > b.minWidth) {
7454                  b.minWidth = pMinWidth;
7455              }
7456              if (pMinHeight > b.minHeight) {
7457                  b.minHeight = pMinHeight;
7458              }
7459              if (pMaxWidth < b.maxWidth) {
7460                  b.maxWidth = pMaxWidth;
7461              }
7462              if (pMaxHeight < b.maxHeight) {
7463                  b.maxHeight = pMaxHeight;
7464              }
7465          }
7466          this._vBoundaries = b;
7467      },
7468  
7469      _updateCache: function(data) {
7470          this.offset = this.helper.offset();
7471          if (this._isNumber(data.left)) {
7472              this.position.left = data.left;
7473          }
7474          if (this._isNumber(data.top)) {
7475              this.position.top = data.top;
7476          }
7477          if (this._isNumber(data.height)) {
7478              this.size.height = data.height;
7479          }
7480          if (this._isNumber(data.width)) {
7481              this.size.width = data.width;
7482          }
7483      },
7484  
7485      _updateRatio: function( data ) {
7486  
7487          var cpos = this.position,
7488              csize = this.size,
7489              a = this.axis;
7490  
7491          if (this._isNumber(data.height)) {
7492              data.width = (data.height * this.aspectRatio);
7493          } else if (this._isNumber(data.width)) {
7494              data.height = (data.width / this.aspectRatio);
7495          }
7496  
7497          if (a === "sw") {
7498              data.left = cpos.left + (csize.width - data.width);
7499              data.top = null;
7500          }
7501          if (a === "nw") {
7502              data.top = cpos.top + (csize.height - data.height);
7503              data.left = cpos.left + (csize.width - data.width);
7504          }
7505  
7506          return data;
7507      },
7508  
7509      _respectSize: function( data ) {
7510  
7511          var o = this._vBoundaries,
7512              a = this.axis,
7513              ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
7514              ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
7515              isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
7516              isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
7517              dw = this.originalPosition.left + this.originalSize.width,
7518              dh = this.position.top + this.size.height,
7519              cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
7520          if (isminw) {
7521              data.width = o.minWidth;
7522          }
7523          if (isminh) {
7524              data.height = o.minHeight;
7525          }
7526          if (ismaxw) {
7527              data.width = o.maxWidth;
7528          }
7529          if (ismaxh) {
7530              data.height = o.maxHeight;
7531          }
7532  
7533          if (isminw && cw) {
7534              data.left = dw - o.minWidth;
7535          }
7536          if (ismaxw && cw) {
7537              data.left = dw - o.maxWidth;
7538          }
7539          if (isminh && ch) {
7540              data.top = dh - o.minHeight;
7541          }
7542          if (ismaxh && ch) {
7543              data.top = dh - o.maxHeight;
7544          }
7545  
7546          // Fixing jump error on top/left - bug #2330
7547          if (!data.width && !data.height && !data.left && data.top) {
7548              data.top = null;
7549          } else if (!data.width && !data.height && !data.top && data.left) {
7550              data.left = null;
7551          }
7552  
7553          return data;
7554      },
7555  
7556      _getPaddingPlusBorderDimensions: function( element ) {
7557          var i = 0,
7558              widths = [],
7559              borders = [
7560                  element.css( "borderTopWidth" ),
7561                  element.css( "borderRightWidth" ),
7562                  element.css( "borderBottomWidth" ),
7563                  element.css( "borderLeftWidth" )
7564              ],
7565              paddings = [
7566                  element.css( "paddingTop" ),
7567                  element.css( "paddingRight" ),
7568                  element.css( "paddingBottom" ),
7569                  element.css( "paddingLeft" )
7570              ];
7571  
7572          for ( ; i < 4; i++ ) {
7573              widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );
7574              widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );
7575          }
7576  
7577          return {
7578              height: widths[ 0 ] + widths[ 2 ],
7579              width: widths[ 1 ] + widths[ 3 ]
7580          };
7581      },
7582  
7583      _proportionallyResize: function() {
7584  
7585          if (!this._proportionallyResizeElements.length) {
7586              return;
7587          }
7588  
7589          var prel,
7590              i = 0,
7591              element = this.helper || this.element;
7592  
7593          for ( ; i < this._proportionallyResizeElements.length; i++) {
7594  
7595              prel = this._proportionallyResizeElements[i];
7596  
7597              // TODO: Seems like a bug to cache this.outerDimensions
7598              // considering that we are in a loop.
7599              if (!this.outerDimensions) {
7600                  this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
7601              }
7602  
7603              prel.css({
7604                  height: (element.height() - this.outerDimensions.height) || 0,
7605                  width: (element.width() - this.outerDimensions.width) || 0
7606              });
7607  
7608          }
7609  
7610      },
7611  
7612      _renderProxy: function() {
7613  
7614          var el = this.element, o = this.options;
7615          this.elementOffset = el.offset();
7616  
7617          if (this._helper) {
7618  
7619              this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
7620  
7621              this.helper.addClass(this._helper).css({
7622                  width: this.element.outerWidth() - 1,
7623                  height: this.element.outerHeight() - 1,
7624                  position: "absolute",
7625                  left: this.elementOffset.left + "px",
7626                  top: this.elementOffset.top + "px",
7627                  zIndex: ++o.zIndex //TODO: Don't modify option
7628              });
7629  
7630              this.helper
7631                  .appendTo("body")
7632                  .disableSelection();
7633  
7634          } else {
7635              this.helper = this.element;
7636          }
7637  
7638      },
7639  
7640      _change: {
7641          e: function(event, dx) {
7642              return { width: this.originalSize.width + dx };
7643          },
7644          w: function(event, dx) {
7645              var cs = this.originalSize, sp = this.originalPosition;
7646              return { left: sp.left + dx, width: cs.width - dx };
7647          },
7648          n: function(event, dx, dy) {
7649              var cs = this.originalSize, sp = this.originalPosition;
7650              return { top: sp.top + dy, height: cs.height - dy };
7651          },
7652          s: function(event, dx, dy) {
7653              return { height: this.originalSize.height + dy };
7654          },
7655          se: function(event, dx, dy) {
7656              return $.extend(this._change.s.apply(this, arguments),
7657                  this._change.e.apply(this, [ event, dx, dy ]));
7658          },
7659          sw: function(event, dx, dy) {
7660              return $.extend(this._change.s.apply(this, arguments),
7661                  this._change.w.apply(this, [ event, dx, dy ]));
7662          },
7663          ne: function(event, dx, dy) {
7664              return $.extend(this._change.n.apply(this, arguments),
7665                  this._change.e.apply(this, [ event, dx, dy ]));
7666          },
7667          nw: function(event, dx, dy) {
7668              return $.extend(this._change.n.apply(this, arguments),
7669                  this._change.w.apply(this, [ event, dx, dy ]));
7670          }
7671      },
7672  
7673      _propagate: function(n, event) {
7674          $.ui.plugin.call(this, n, [ event, this.ui() ]);
7675          (n !== "resize" && this._trigger(n, event, this.ui()));
7676      },
7677  
7678      plugins: {},
7679  
7680      ui: function() {
7681          return {
7682              originalElement: this.originalElement,
7683              element: this.element,
7684              helper: this.helper,
7685              position: this.position,
7686              size: this.size,
7687              originalSize: this.originalSize,
7688              originalPosition: this.originalPosition
7689          };
7690      }
7691  
7692  });
7693  
7694  /*
7695   * Resizable Extensions
7696   */
7697  
7698  $.ui.plugin.add("resizable", "animate", {
7699  
7700      stop: function( event ) {
7701          var that = $(this).resizable( "instance" ),
7702              o = that.options,
7703              pr = that._proportionallyResizeElements,
7704              ista = pr.length && (/textarea/i).test(pr[0].nodeName),
7705              soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
7706              soffsetw = ista ? 0 : that.sizeDiff.width,
7707              style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
7708              left = (parseInt(that.element.css("left"), 10) +
7709                  (that.position.left - that.originalPosition.left)) || null,
7710              top = (parseInt(that.element.css("top"), 10) +
7711                  (that.position.top - that.originalPosition.top)) || null;
7712  
7713          that.element.animate(
7714              $.extend(style, top && left ? { top: top, left: left } : {}), {
7715                  duration: o.animateDuration,
7716                  easing: o.animateEasing,
7717                  step: function() {
7718  
7719                      var data = {
7720                          width: parseInt(that.element.css("width"), 10),
7721                          height: parseInt(that.element.css("height"), 10),
7722                          top: parseInt(that.element.css("top"), 10),
7723                          left: parseInt(that.element.css("left"), 10)
7724                      };
7725  
7726                      if (pr && pr.length) {
7727                          $(pr[0]).css({ width: data.width, height: data.height });
7728                      }
7729  
7730                      // propagating resize, and updating values for each animation step
7731                      that._updateCache(data);
7732                      that._propagate("resize", event);
7733  
7734                  }
7735              }
7736          );
7737      }
7738  
7739  });
7740  
7741  $.ui.plugin.add( "resizable", "containment", {
7742  
7743      start: function() {
7744          var element, p, co, ch, cw, width, height,
7745              that = $( this ).resizable( "instance" ),
7746              o = that.options,
7747              el = that.element,
7748              oc = o.containment,
7749              ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
7750  
7751          if ( !ce ) {
7752              return;
7753          }
7754  
7755          that.containerElement = $( ce );
7756  
7757          if ( /document/.test( oc ) || oc === document ) {
7758              that.containerOffset = {
7759                  left: 0,
7760                  top: 0
7761              };
7762              that.containerPosition = {
7763                  left: 0,
7764                  top: 0
7765              };
7766  
7767              that.parentData = {
7768                  element: $( document ),
7769                  left: 0,
7770                  top: 0,
7771                  width: $( document ).width(),
7772                  height: $( document ).height() || document.body.parentNode.scrollHeight
7773              };
7774          } else {
7775              element = $( ce );
7776              p = [];
7777              $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
7778                  p[ i ] = that._num( element.css( "padding" + name ) );
7779              });
7780  
7781              that.containerOffset = element.offset();
7782              that.containerPosition = element.position();
7783              that.containerSize = {
7784                  height: ( element.innerHeight() - p[ 3 ] ),
7785                  width: ( element.innerWidth() - p[ 1 ] )
7786              };
7787  
7788              co = that.containerOffset;
7789              ch = that.containerSize.height;
7790              cw = that.containerSize.width;
7791              width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
7792              height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
7793  
7794              that.parentData = {
7795                  element: ce,
7796                  left: co.left,
7797                  top: co.top,
7798                  width: width,
7799                  height: height
7800              };
7801          }
7802      },
7803  
7804      resize: function( event ) {
7805          var woset, hoset, isParent, isOffsetRelative,
7806              that = $( this ).resizable( "instance" ),
7807              o = that.options,
7808              co = that.containerOffset,
7809              cp = that.position,
7810              pRatio = that._aspectRatio || event.shiftKey,
7811              cop = {
7812                  top: 0,
7813                  left: 0
7814              },
7815              ce = that.containerElement,
7816              continueResize = true;
7817  
7818          if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
7819              cop = co;
7820          }
7821  
7822          if ( cp.left < ( that._helper ? co.left : 0 ) ) {
7823              that.size.width = that.size.width +
7824                  ( that._helper ?
7825                      ( that.position.left - co.left ) :
7826                      ( that.position.left - cop.left ) );
7827  
7828              if ( pRatio ) {
7829                  that.size.height = that.size.width / that.aspectRatio;
7830                  continueResize = false;
7831              }
7832              that.position.left = o.helper ? co.left : 0;
7833          }
7834  
7835          if ( cp.top < ( that._helper ? co.top : 0 ) ) {
7836              that.size.height = that.size.height +
7837                  ( that._helper ?
7838                      ( that.position.top - co.top ) :
7839                      that.position.top );
7840  
7841              if ( pRatio ) {
7842                  that.size.width = that.size.height * that.aspectRatio;
7843                  continueResize = false;
7844              }
7845              that.position.top = that._helper ? co.top : 0;
7846          }
7847  
7848          isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
7849          isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
7850  
7851          if ( isParent && isOffsetRelative ) {
7852              that.offset.left = that.parentData.left + that.position.left;
7853              that.offset.top = that.parentData.top + that.position.top;
7854          } else {
7855              that.offset.left = that.element.offset().left;
7856              that.offset.top = that.element.offset().top;
7857          }
7858  
7859          woset = Math.abs( that.sizeDiff.width +
7860              (that._helper ?
7861                  that.offset.left - cop.left :
7862                  (that.offset.left - co.left)) );
7863  
7864          hoset = Math.abs( that.sizeDiff.height +
7865              (that._helper ?
7866                  that.offset.top - cop.top :
7867                  (that.offset.top - co.top)) );
7868  
7869          if ( woset + that.size.width >= that.parentData.width ) {
7870              that.size.width = that.parentData.width - woset;
7871              if ( pRatio ) {
7872                  that.size.height = that.size.width / that.aspectRatio;
7873                  continueResize = false;
7874              }
7875          }
7876  
7877          if ( hoset + that.size.height >= that.parentData.height ) {
7878              that.size.height = that.parentData.height - hoset;
7879              if ( pRatio ) {
7880                  that.size.width = that.size.height * that.aspectRatio;
7881                  continueResize = false;
7882              }
7883          }
7884  
7885          if ( !continueResize ) {
7886              that.position.left = that.prevPosition.left;
7887              that.position.top = that.prevPosition.top;
7888              that.size.width = that.prevSize.width;
7889              that.size.height = that.prevSize.height;
7890          }
7891      },
7892  
7893      stop: function() {
7894          var that = $( this ).resizable( "instance" ),
7895              o = that.options,
7896              co = that.containerOffset,
7897              cop = that.containerPosition,
7898              ce = that.containerElement,
7899              helper = $( that.helper ),
7900              ho = helper.offset(),
7901              w = helper.outerWidth() - that.sizeDiff.width,
7902              h = helper.outerHeight() - that.sizeDiff.height;
7903  
7904          if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
7905              $( this ).css({
7906                  left: ho.left - cop.left - co.left,
7907                  width: w,
7908                  height: h
7909              });
7910          }
7911  
7912          if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
7913              $( this ).css({
7914                  left: ho.left - cop.left - co.left,
7915                  width: w,
7916                  height: h
7917              });
7918          }
7919      }
7920  });
7921  
7922  $.ui.plugin.add("resizable", "alsoResize", {
7923  
7924      start: function() {
7925          var that = $(this).resizable( "instance" ),
7926              o = that.options;
7927  
7928          $(o.alsoResize).each(function() {
7929              var el = $(this);
7930              el.data("ui-resizable-alsoresize", {
7931                  width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
7932                  left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
7933              });
7934          });
7935      },
7936  
7937      resize: function(event, ui) {
7938          var that = $(this).resizable( "instance" ),
7939              o = that.options,
7940              os = that.originalSize,
7941              op = that.originalPosition,
7942              delta = {
7943                  height: (that.size.height - os.height) || 0,
7944                  width: (that.size.width - os.width) || 0,
7945                  top: (that.position.top - op.top) || 0,
7946                  left: (that.position.left - op.left) || 0
7947              };
7948  
7949              $(o.alsoResize).each(function() {
7950                  var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
7951                      css = el.parents(ui.originalElement[0]).length ?
7952                              [ "width", "height" ] :
7953                              [ "width", "height", "top", "left" ];
7954  
7955                  $.each(css, function(i, prop) {
7956                      var sum = (start[prop] || 0) + (delta[prop] || 0);
7957                      if (sum && sum >= 0) {
7958                          style[prop] = sum || null;
7959                      }
7960                  });
7961  
7962                  el.css(style);
7963              });
7964      },
7965  
7966      stop: function() {
7967          $(this).removeData("resizable-alsoresize");
7968      }
7969  });
7970  
7971  $.ui.plugin.add("resizable", "ghost", {
7972  
7973      start: function() {
7974  
7975          var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;
7976  
7977          that.ghost = that.originalElement.clone();
7978          that.ghost
7979              .css({
7980                  opacity: 0.25,
7981                  display: "block",
7982                  position: "relative",
7983                  height: cs.height,
7984                  width: cs.width,
7985                  margin: 0,
7986                  left: 0,
7987                  top: 0
7988              })
7989              .addClass("ui-resizable-ghost")
7990              .addClass(typeof o.ghost === "string" ? o.ghost : "");
7991  
7992          that.ghost.appendTo(that.helper);
7993  
7994      },
7995  
7996      resize: function() {
7997          var that = $(this).resizable( "instance" );
7998          if (that.ghost) {
7999              that.ghost.css({
8000                  position: "relative",
8001                  height: that.size.height,
8002                  width: that.size.width
8003              });
8004          }
8005      },
8006  
8007      stop: function() {
8008          var that = $(this).resizable( "instance" );
8009          if (that.ghost && that.helper) {
8010              that.helper.get(0).removeChild(that.ghost.get(0));
8011          }
8012      }
8013  
8014  });
8015  
8016  $.ui.plugin.add("resizable", "grid", {
8017  
8018      resize: function() {
8019          var outerDimensions,
8020              that = $(this).resizable( "instance" ),
8021              o = that.options,
8022              cs = that.size,
8023              os = that.originalSize,
8024              op = that.originalPosition,
8025              a = that.axis,
8026              grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
8027              gridX = (grid[0] || 1),
8028              gridY = (grid[1] || 1),
8029              ox = Math.round((cs.width - os.width) / gridX) * gridX,
8030              oy = Math.round((cs.height - os.height) / gridY) * gridY,
8031              newWidth = os.width + ox,
8032              newHeight = os.height + oy,
8033              isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
8034              isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
8035              isMinWidth = o.minWidth && (o.minWidth > newWidth),
8036              isMinHeight = o.minHeight && (o.minHeight > newHeight);
8037  
8038          o.grid = grid;
8039  
8040          if (isMinWidth) {
8041              newWidth += gridX;
8042          }
8043          if (isMinHeight) {
8044              newHeight += gridY;
8045          }
8046          if (isMaxWidth) {
8047              newWidth -= gridX;
8048          }
8049          if (isMaxHeight) {
8050              newHeight -= gridY;
8051          }
8052  
8053          if (/^(se|s|e)$/.test(a)) {
8054              that.size.width = newWidth;
8055              that.size.height = newHeight;
8056          } else if (/^(ne)$/.test(a)) {
8057              that.size.width = newWidth;
8058              that.size.height = newHeight;
8059              that.position.top = op.top - oy;
8060          } else if (/^(sw)$/.test(a)) {
8061              that.size.width = newWidth;
8062              that.size.height = newHeight;
8063              that.position.left = op.left - ox;
8064          } else {
8065              if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {
8066                  outerDimensions = that._getPaddingPlusBorderDimensions( this );
8067              }
8068  
8069              if ( newHeight - gridY > 0 ) {
8070                  that.size.height = newHeight;
8071                  that.position.top = op.top - oy;
8072              } else {
8073                  newHeight = gridY - outerDimensions.height;
8074                  that.size.height = newHeight;
8075                  that.position.top = op.top + os.height - newHeight;
8076              }
8077              if ( newWidth - gridX > 0 ) {
8078                  that.size.width = newWidth;
8079                  that.position.left = op.left - ox;
8080              } else {
8081                  newWidth = gridX - outerDimensions.width;
8082                  that.size.width = newWidth;
8083                  that.position.left = op.left + os.width - newWidth;
8084              }
8085          }
8086      }
8087  
8088  });
8089  
8090  var resizable = $.ui.resizable;
8091  
8092  
8093  /*!
8094   * jQuery UI Dialog 1.11.4
8095   * http://jqueryui.com
8096   *
8097   * Copyright jQuery Foundation and other contributors
8098   * Released under the MIT license.
8099   * http://jquery.org/license
8100   *
8101   * http://api.jqueryui.com/dialog/
8102   */
8103  
8104  
8105  var dialog = $.widget( "ui.dialog", {
8106      version: "1.11.4",
8107      options: {
8108          appendTo: "body",
8109          autoOpen: true,
8110          buttons: [],
8111          closeOnEscape: true,
8112          closeText: "Close",
8113          dialogClass: "",
8114          draggable: true,
8115          hide: null,
8116          height: "auto",
8117          maxHeight: null,
8118          maxWidth: null,
8119          minHeight: 150,
8120          minWidth: 150,
8121          modal: false,
8122          position: {
8123              my: "center",
8124              at: "center",
8125              of: window,
8126              collision: "fit",
8127              // Ensure the titlebar is always visible
8128              using: function( pos ) {
8129                  var topOffset = $( this ).css( pos ).offset().top;
8130                  if ( topOffset < 0 ) {
8131                      $( this ).css( "top", pos.top - topOffset );
8132                  }
8133              }
8134          },
8135          resizable: true,
8136          show: null,
8137          title: null,
8138          width: 300,
8139  
8140          // callbacks
8141          beforeClose: null,
8142          close: null,
8143          drag: null,
8144          dragStart: null,
8145          dragStop: null,
8146          focus: null,
8147          open: null,
8148          resize: null,
8149          resizeStart: null,
8150          resizeStop: null
8151      },
8152  
8153      sizeRelatedOptions: {
8154          buttons: true,
8155          height: true,
8156          maxHeight: true,
8157          maxWidth: true,
8158          minHeight: true,
8159          minWidth: true,
8160          width: true
8161      },
8162  
8163      resizableRelatedOptions: {
8164          maxHeight: true,
8165          maxWidth: true,
8166          minHeight: true,
8167          minWidth: true
8168      },
8169  
8170      _create: function() {
8171          this.originalCss = {
8172              display: this.element[ 0 ].style.display,
8173              width: this.element[ 0 ].style.width,
8174              minHeight: this.element[ 0 ].style.minHeight,
8175              maxHeight: this.element[ 0 ].style.maxHeight,
8176              height: this.element[ 0 ].style.height
8177          };
8178          this.originalPosition = {
8179              parent: this.element.parent(),
8180              index: this.element.parent().children().index( this.element )
8181          };
8182          this.originalTitle = this.element.attr( "title" );
8183          this.options.title = this.options.title || this.originalTitle;
8184  
8185          this._createWrapper();
8186  
8187          this.element
8188              .show()
8189              .removeAttr( "title" )
8190              .addClass( "ui-dialog-content ui-widget-content" )
8191              .appendTo( this.uiDialog );
8192  
8193          this._createTitlebar();
8194          this._createButtonPane();
8195  
8196          if ( this.options.draggable && $.fn.draggable ) {
8197              this._makeDraggable();
8198          }
8199          if ( this.options.resizable && $.fn.resizable ) {
8200              this._makeResizable();
8201          }
8202  
8203          this._isOpen = false;
8204  
8205          this._trackFocus();
8206      },
8207  
8208      _init: function() {
8209          if ( this.options.autoOpen ) {
8210              this.open();
8211          }
8212      },
8213  
8214      _appendTo: function() {
8215          var element = this.options.appendTo;
8216          if ( element && (element.jquery || element.nodeType) ) {
8217              return $( element );
8218          }
8219          return this.document.find( element || "body" ).eq( 0 );
8220      },
8221  
8222      _destroy: function() {
8223          var next,
8224              originalPosition = this.originalPosition;
8225  
8226          this._untrackInstance();
8227          this._destroyOverlay();
8228  
8229          this.element
8230              .removeUniqueId()
8231              .removeClass( "ui-dialog-content ui-widget-content" )
8232              .css( this.originalCss )
8233              // Without detaching first, the following becomes really slow
8234              .detach();
8235  
8236          this.uiDialog.stop( true, true ).remove();
8237  
8238          if ( this.originalTitle ) {
8239              this.element.attr( "title", this.originalTitle );
8240          }
8241  
8242          next = originalPosition.parent.children().eq( originalPosition.index );
8243          // Don't try to place the dialog next to itself (#8613)
8244          if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
8245              next.before( this.element );
8246          } else {
8247              originalPosition.parent.append( this.element );
8248          }
8249      },
8250  
8251      widget: function() {
8252          return this.uiDialog;
8253      },
8254  
8255      disable: $.noop,
8256      enable: $.noop,
8257  
8258      close: function( event ) {
8259          var activeElement,
8260              that = this;
8261  
8262          if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
8263              return;
8264          }
8265  
8266          this._isOpen = false;
8267          this._focusedElement = null;
8268          this._destroyOverlay();
8269          this._untrackInstance();
8270  
8271          if ( !this.opener.filter( ":focusable" ).focus().length ) {
8272  
8273              // support: IE9
8274              // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
8275              try {
8276                  activeElement = this.document[ 0 ].activeElement;
8277  
8278                  // Support: IE9, IE10
8279                  // If the <body> is blurred, IE will switch windows, see #4520
8280                  if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
8281  
8282                      // Hiding a focused element doesn't trigger blur in WebKit
8283                      // so in case we have nothing to focus on, explicitly blur the active element
8284                      // https://bugs.webkit.org/show_bug.cgi?id=47182
8285                      $( activeElement ).blur();
8286                  }
8287              } catch ( error ) {}
8288          }
8289  
8290          this._hide( this.uiDialog, this.options.hide, function() {
8291              that._trigger( "close", event );
8292          });
8293      },
8294  
8295      isOpen: function() {
8296          return this._isOpen;
8297      },
8298  
8299      moveToTop: function() {
8300          this._moveToTop();
8301      },
8302  
8303      _moveToTop: function( event, silent ) {
8304          var moved = false,
8305              zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
8306                  return +$( this ).css( "z-index" );
8307              }).get(),
8308              zIndexMax = Math.max.apply( null, zIndices );
8309  
8310          if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
8311              this.uiDialog.css( "z-index", zIndexMax + 1 );
8312              moved = true;
8313          }
8314  
8315          if ( moved && !silent ) {
8316              this._trigger( "focus", event );
8317          }
8318          return moved;
8319      },
8320  
8321      open: function() {
8322          var that = this;
8323          if ( this._isOpen ) {
8324              if ( this._moveToTop() ) {
8325                  this._focusTabbable();
8326              }
8327              return;
8328          }
8329  
8330          this._isOpen = true;
8331          this.opener = $( this.document[ 0 ].activeElement );
8332  
8333          this._size();
8334          this._position();
8335          this._createOverlay();
8336          this._moveToTop( null, true );
8337  
8338          // Ensure the overlay is moved to the top with the dialog, but only when
8339          // opening. The overlay shouldn't move after the dialog is open so that
8340          // modeless dialogs opened after the modal dialog stack properly.
8341          if ( this.overlay ) {
8342              this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
8343          }
8344  
8345          this._show( this.uiDialog, this.options.show, function() {
8346              that._focusTabbable();
8347              that._trigger( "focus" );
8348          });
8349  
8350          // Track the dialog immediately upon openening in case a focus event
8351          // somehow occurs outside of the dialog before an element inside the
8352          // dialog is focused (#10152)
8353          this._makeFocusTarget();
8354  
8355          this._trigger( "open" );
8356      },
8357  
8358      _focusTabbable: function() {
8359          // Set focus to the first match:
8360          // 1. An element that was focused previously
8361          // 2. First element inside the dialog matching [autofocus]
8362          // 3. Tabbable element inside the content element
8363          // 4. Tabbable element inside the buttonpane
8364          // 5. The close button
8365          // 6. The dialog itself
8366          var hasFocus = this._focusedElement;
8367          if ( !hasFocus ) {
8368              hasFocus = this.element.find( "[autofocus]" );
8369          }
8370          if ( !hasFocus.length ) {
8371              hasFocus = this.element.find( ":tabbable" );
8372          }
8373          if ( !hasFocus.length ) {
8374              hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
8375          }
8376          if ( !hasFocus.length ) {
8377              hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
8378          }
8379          if ( !hasFocus.length ) {
8380              hasFocus = this.uiDialog;
8381          }
8382          hasFocus.eq( 0 ).focus();
8383      },
8384  
8385      _keepFocus: function( event ) {
8386  		function checkFocus() {
8387              var activeElement = this.document[0].activeElement,
8388                  isActive = this.uiDialog[0] === activeElement ||
8389                      $.contains( this.uiDialog[0], activeElement );
8390              if ( !isActive ) {
8391                  this._focusTabbable();
8392              }
8393          }
8394          event.preventDefault();
8395          checkFocus.call( this );
8396          // support: IE
8397          // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
8398          // so we check again later
8399          this._delay( checkFocus );
8400      },
8401  
8402      _createWrapper: function() {
8403          this.uiDialog = $("<div>")
8404              .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
8405                  this.options.dialogClass )
8406              .hide()
8407              .attr({
8408                  // Setting tabIndex makes the div focusable
8409                  tabIndex: -1,
8410                  role: "dialog"
8411              })
8412              .appendTo( this._appendTo() );
8413  
8414          this._on( this.uiDialog, {
8415              keydown: function( event ) {
8416                  if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
8417                          event.keyCode === $.ui.keyCode.ESCAPE ) {
8418                      event.preventDefault();
8419                      this.close( event );
8420                      return;
8421                  }
8422  
8423                  // prevent tabbing out of dialogs
8424                  if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
8425                      return;
8426                  }
8427                  var tabbables = this.uiDialog.find( ":tabbable" ),
8428                      first = tabbables.filter( ":first" ),
8429                      last = tabbables.filter( ":last" );
8430  
8431                  if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
8432                      this._delay(function() {
8433                          first.focus();
8434                      });
8435                      event.preventDefault();
8436                  } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
8437                      this._delay(function() {
8438                          last.focus();
8439                      });
8440                      event.preventDefault();
8441                  }
8442              },
8443              mousedown: function( event ) {
8444                  if ( this._moveToTop( event ) ) {
8445                      this._focusTabbable();
8446                  }
8447              }
8448          });
8449  
8450          // We assume that any existing aria-describedby attribute means
8451          // that the dialog content is marked up properly
8452          // otherwise we brute force the content as the description
8453          if ( !this.element.find( "[aria-describedby]" ).length ) {
8454              this.uiDialog.attr({
8455                  "aria-describedby": this.element.uniqueId().attr( "id" )
8456              });
8457          }
8458      },
8459  
8460      _createTitlebar: function() {
8461          var uiDialogTitle;
8462  
8463          this.uiDialogTitlebar = $( "<div>" )
8464              .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
8465              .prependTo( this.uiDialog );
8466          this._on( this.uiDialogTitlebar, {
8467              mousedown: function( event ) {
8468                  // Don't prevent click on close button (#8838)
8469                  // Focusing a dialog that is partially scrolled out of view
8470                  // causes the browser to scroll it into view, preventing the click event
8471                  if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
8472                      // Dialog isn't getting focus when dragging (#8063)
8473                      this.uiDialog.focus();
8474                  }
8475              }
8476          });
8477  
8478          // support: IE
8479          // Use type="button" to prevent enter keypresses in textboxes from closing the
8480          // dialog in IE (#9312)
8481          this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
8482              .button({
8483                  label: this.options.closeText,
8484                  icons: {
8485                      primary: "ui-icon-closethick"
8486                  },
8487                  text: false
8488              })
8489              .addClass( "ui-dialog-titlebar-close" )
8490              .appendTo( this.uiDialogTitlebar );
8491          this._on( this.uiDialogTitlebarClose, {
8492              click: function( event ) {
8493                  event.preventDefault();
8494                  this.close( event );
8495              }
8496          });
8497  
8498          uiDialogTitle = $( "<span>" )
8499              .uniqueId()
8500              .addClass( "ui-dialog-title" )
8501              .prependTo( this.uiDialogTitlebar );
8502          this._title( uiDialogTitle );
8503  
8504          this.uiDialog.attr({
8505              "aria-labelledby": uiDialogTitle.attr( "id" )
8506          });
8507      },
8508  
8509      _title: function( title ) {
8510          if ( !this.options.title ) {
8511              title.html( "&#160;" );
8512          }
8513          title.text( this.options.title );
8514      },
8515  
8516      _createButtonPane: function() {
8517          this.uiDialogButtonPane = $( "<div>" )
8518              .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
8519  
8520          this.uiButtonSet = $( "<div>" )
8521              .addClass( "ui-dialog-buttonset" )
8522              .appendTo( this.uiDialogButtonPane );
8523  
8524          this._createButtons();
8525      },
8526  
8527      _createButtons: function() {
8528          var that = this,
8529              buttons = this.options.buttons;
8530  
8531          // if we already have a button pane, remove it
8532          this.uiDialogButtonPane.remove();
8533          this.uiButtonSet.empty();
8534  
8535          if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
8536              this.uiDialog.removeClass( "ui-dialog-buttons" );
8537              return;
8538          }
8539  
8540          $.each( buttons, function( name, props ) {
8541              var click, buttonOptions;
8542              props = $.isFunction( props ) ?
8543                  { click: props, text: name } :
8544                  props;
8545              // Default to a non-submitting button
8546              props = $.extend( { type: "button" }, props );
8547              // Change the context for the click callback to be the main element
8548              click = props.click;
8549              props.click = function() {
8550                  click.apply( that.element[ 0 ], arguments );
8551              };
8552              buttonOptions = {
8553                  icons: props.icons,
8554                  text: props.showText
8555              };
8556              delete props.icons;
8557              delete props.showText;
8558              $( "<button></button>", props )
8559                  .button( buttonOptions )
8560                  .appendTo( that.uiButtonSet );
8561          });
8562          this.uiDialog.addClass( "ui-dialog-buttons" );
8563          this.uiDialogButtonPane.appendTo( this.uiDialog );
8564      },
8565  
8566      _makeDraggable: function() {
8567          var that = this,
8568              options = this.options;
8569  
8570  		function filteredUi( ui ) {
8571              return {
8572                  position: ui.position,
8573                  offset: ui.offset
8574              };
8575          }
8576  
8577          this.uiDialog.draggable({
8578              cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
8579              handle: ".ui-dialog-titlebar",
8580              containment: "document",
8581              start: function( event, ui ) {
8582                  $( this ).addClass( "ui-dialog-dragging" );
8583                  that._blockFrames();
8584                  that._trigger( "dragStart", event, filteredUi( ui ) );
8585              },
8586              drag: function( event, ui ) {
8587                  that._trigger( "drag", event, filteredUi( ui ) );
8588              },
8589              stop: function( event, ui ) {
8590                  var left = ui.offset.left - that.document.scrollLeft(),
8591                      top = ui.offset.top - that.document.scrollTop();
8592  
8593                  options.position = {
8594                      my: "left top",
8595                      at: "left" + (left >= 0 ? "+" : "") + left + " " +
8596                          "top" + (top >= 0 ? "+" : "") + top,
8597                      of: that.window
8598                  };
8599                  $( this ).removeClass( "ui-dialog-dragging" );
8600                  that._unblockFrames();
8601                  that._trigger( "dragStop", event, filteredUi( ui ) );
8602              }
8603          });
8604      },
8605  
8606      _makeResizable: function() {
8607          var that = this,
8608              options = this.options,
8609              handles = options.resizable,
8610              // .ui-resizable has position: relative defined in the stylesheet
8611              // but dialogs have to use absolute or fixed positioning
8612              position = this.uiDialog.css("position"),
8613              resizeHandles = typeof handles === "string" ?
8614                  handles    :
8615                  "n,e,s,w,se,sw,ne,nw";
8616  
8617  		function filteredUi( ui ) {
8618              return {
8619                  originalPosition: ui.originalPosition,
8620                  originalSize: ui.originalSize,
8621                  position: ui.position,
8622                  size: ui.size
8623              };
8624          }
8625  
8626          this.uiDialog.resizable({
8627              cancel: ".ui-dialog-content",
8628              containment: "document",
8629              alsoResize: this.element,
8630              maxWidth: options.maxWidth,
8631              maxHeight: options.maxHeight,
8632              minWidth: options.minWidth,
8633              minHeight: this._minHeight(),
8634              handles: resizeHandles,
8635              start: function( event, ui ) {
8636                  $( this ).addClass( "ui-dialog-resizing" );
8637                  that._blockFrames();
8638                  that._trigger( "resizeStart", event, filteredUi( ui ) );
8639              },
8640              resize: function( event, ui ) {
8641                  that._trigger( "resize", event, filteredUi( ui ) );
8642              },
8643              stop: function( event, ui ) {
8644                  var offset = that.uiDialog.offset(),
8645                      left = offset.left - that.document.scrollLeft(),
8646                      top = offset.top - that.document.scrollTop();
8647  
8648                  options.height = that.uiDialog.height();
8649                  options.width = that.uiDialog.width();
8650                  options.position = {
8651                      my: "left top",
8652                      at: "left" + (left >= 0 ? "+" : "") + left + " " +
8653                          "top" + (top >= 0 ? "+" : "") + top,
8654                      of: that.window
8655                  };
8656                  $( this ).removeClass( "ui-dialog-resizing" );
8657                  that._unblockFrames();
8658                  that._trigger( "resizeStop", event, filteredUi( ui ) );
8659              }
8660          })
8661          .css( "position", position );
8662      },
8663  
8664      _trackFocus: function() {
8665          this._on( this.widget(), {
8666              focusin: function( event ) {
8667                  this._makeFocusTarget();
8668                  this._focusedElement = $( event.target );
8669              }
8670          });
8671      },
8672  
8673      _makeFocusTarget: function() {
8674          this._untrackInstance();
8675          this._trackingInstances().unshift( this );
8676      },
8677  
8678      _untrackInstance: function() {
8679          var instances = this._trackingInstances(),
8680              exists = $.inArray( this, instances );
8681          if ( exists !== -1 ) {
8682              instances.splice( exists, 1 );
8683          }
8684      },
8685  
8686      _trackingInstances: function() {
8687          var instances = this.document.data( "ui-dialog-instances" );
8688          if ( !instances ) {
8689              instances = [];
8690              this.document.data( "ui-dialog-instances", instances );
8691          }
8692          return instances;
8693      },
8694  
8695      _minHeight: function() {
8696          var options = this.options;
8697  
8698          return options.height === "auto" ?
8699              options.minHeight :
8700              Math.min( options.minHeight, options.height );
8701      },
8702  
8703      _position: function() {
8704          // Need to show the dialog to get the actual offset in the position plugin
8705          var isVisible = this.uiDialog.is( ":visible" );
8706          if ( !isVisible ) {
8707              this.uiDialog.show();
8708          }
8709          this.uiDialog.position( this.options.position );
8710          if ( !isVisible ) {
8711              this.uiDialog.hide();
8712          }
8713      },
8714  
8715      _setOptions: function( options ) {
8716          var that = this,
8717              resize = false,
8718              resizableOptions = {};
8719  
8720          $.each( options, function( key, value ) {
8721              that._setOption( key, value );
8722  
8723              if ( key in that.sizeRelatedOptions ) {
8724                  resize = true;
8725              }
8726              if ( key in that.resizableRelatedOptions ) {
8727                  resizableOptions[ key ] = value;
8728              }
8729          });
8730  
8731          if ( resize ) {
8732              this._size();
8733              this._position();
8734          }
8735          if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
8736              this.uiDialog.resizable( "option", resizableOptions );
8737          }
8738      },
8739  
8740      _setOption: function( key, value ) {
8741          var isDraggable, isResizable,
8742              uiDialog = this.uiDialog;
8743  
8744          if ( key === "dialogClass" ) {
8745              uiDialog
8746                  .removeClass( this.options.dialogClass )
8747                  .addClass( value );
8748          }
8749  
8750          if ( key === "disabled" ) {
8751              return;
8752          }
8753  
8754          this._super( key, value );
8755  
8756          if ( key === "appendTo" ) {
8757              this.uiDialog.appendTo( this._appendTo() );
8758          }
8759  
8760          if ( key === "buttons" ) {
8761              this._createButtons();
8762          }
8763  
8764          if ( key === "closeText" ) {
8765              this.uiDialogTitlebarClose.button({
8766                  // Ensure that we always pass a string
8767                  label: "" + value
8768              });
8769          }
8770  
8771          if ( key === "draggable" ) {
8772              isDraggable = uiDialog.is( ":data(ui-draggable)" );
8773              if ( isDraggable && !value ) {
8774                  uiDialog.draggable( "destroy" );
8775              }
8776  
8777              if ( !isDraggable && value ) {
8778                  this._makeDraggable();
8779              }
8780          }
8781  
8782          if ( key === "position" ) {
8783              this._position();
8784          }
8785  
8786          if ( key === "resizable" ) {
8787              // currently resizable, becoming non-resizable
8788              isResizable = uiDialog.is( ":data(ui-resizable)" );
8789              if ( isResizable && !value ) {
8790                  uiDialog.resizable( "destroy" );
8791              }
8792  
8793              // currently resizable, changing handles
8794              if ( isResizable && typeof value === "string" ) {
8795                  uiDialog.resizable( "option", "handles", value );
8796              }
8797  
8798              // currently non-resizable, becoming resizable
8799              if ( !isResizable && value !== false ) {
8800                  this._makeResizable();
8801              }
8802          }
8803  
8804          if ( key === "title" ) {
8805              this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
8806          }
8807      },
8808  
8809      _size: function() {
8810          // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
8811          // divs will both have width and height set, so we need to reset them
8812          var nonContentHeight, minContentHeight, maxContentHeight,
8813              options = this.options;
8814  
8815          // Reset content sizing
8816          this.element.show().css({
8817              width: "auto",
8818              minHeight: 0,
8819              maxHeight: "none",
8820              height: 0
8821          });
8822  
8823          if ( options.minWidth > options.width ) {
8824              options.width = options.minWidth;
8825          }
8826  
8827          // reset wrapper sizing
8828          // determine the height of all the non-content elements
8829          nonContentHeight = this.uiDialog.css({
8830                  height: "auto",
8831                  width: options.width
8832              })
8833              .outerHeight();
8834          minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
8835          maxContentHeight = typeof options.maxHeight === "number" ?
8836              Math.max( 0, options.maxHeight - nonContentHeight ) :
8837              "none";
8838  
8839          if ( options.height === "auto" ) {
8840              this.element.css({
8841                  minHeight: minContentHeight,
8842                  maxHeight: maxContentHeight,
8843                  height: "auto"
8844              });
8845          } else {
8846              this.element.height( Math.max( 0, options.height - nonContentHeight ) );
8847          }
8848  
8849          if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
8850              this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
8851          }
8852      },
8853  
8854      _blockFrames: function() {
8855          this.iframeBlocks = this.document.find( "iframe" ).map(function() {
8856              var iframe = $( this );
8857  
8858              return $( "<div>" )
8859                  .css({
8860                      position: "absolute",
8861                      width: iframe.outerWidth(),
8862                      height: iframe.outerHeight()
8863                  })
8864                  .appendTo( iframe.parent() )
8865                  .offset( iframe.offset() )[0];
8866          });
8867      },
8868  
8869      _unblockFrames: function() {
8870          if ( this.iframeBlocks ) {
8871              this.iframeBlocks.remove();
8872              delete this.iframeBlocks;
8873          }
8874      },
8875  
8876      _allowInteraction: function( event ) {
8877          if ( $( event.target ).closest( ".ui-dialog" ).length ) {
8878              return true;
8879          }
8880  
8881          // TODO: Remove hack when datepicker implements
8882          // the .ui-front logic (#8989)
8883          return !!$( event.target ).closest( ".ui-datepicker" ).length;
8884      },
8885  
8886      _createOverlay: function() {
8887          if ( !this.options.modal ) {
8888              return;
8889          }
8890  
8891          // We use a delay in case the overlay is created from an
8892          // event that we're going to be cancelling (#2804)
8893          var isOpening = true;
8894          this._delay(function() {
8895              isOpening = false;
8896          });
8897  
8898          if ( !this.document.data( "ui-dialog-overlays" ) ) {
8899  
8900              // Prevent use of anchors and inputs
8901              // Using _on() for an event handler shared across many instances is
8902              // safe because the dialogs stack and must be closed in reverse order
8903              this._on( this.document, {
8904                  focusin: function( event ) {
8905                      if ( isOpening ) {
8906                          return;
8907                      }
8908  
8909                      if ( !this._allowInteraction( event ) ) {
8910                          event.preventDefault();
8911                          this._trackingInstances()[ 0 ]._focusTabbable();
8912                      }
8913                  }
8914              });
8915          }
8916  
8917          this.overlay = $( "<div>" )
8918              .addClass( "ui-widget-overlay ui-front" )
8919              .appendTo( this._appendTo() );
8920          this._on( this.overlay, {
8921              mousedown: "_keepFocus"
8922          });
8923          this.document.data( "ui-dialog-overlays",
8924              (this.document.data( "ui-dialog-overlays" ) || 0) + 1 );
8925      },
8926  
8927      _destroyOverlay: function() {
8928          if ( !this.options.modal ) {
8929              return;
8930          }
8931  
8932          if ( this.overlay ) {
8933              var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
8934  
8935              if ( !overlays ) {
8936                  this.document
8937                      .unbind( "focusin" )
8938                      .removeData( "ui-dialog-overlays" );
8939              } else {
8940                  this.document.data( "ui-dialog-overlays", overlays );
8941              }
8942  
8943              this.overlay.remove();
8944              this.overlay = null;
8945          }
8946      }
8947  });
8948  
8949  
8950  /*!
8951   * jQuery UI Droppable 1.11.4
8952   * http://jqueryui.com
8953   *
8954   * Copyright jQuery Foundation and other contributors
8955   * Released under the MIT license.
8956   * http://jquery.org/license
8957   *
8958   * http://api.jqueryui.com/droppable/
8959   */
8960  
8961  
8962  $.widget( "ui.droppable", {
8963      version: "1.11.4",
8964      widgetEventPrefix: "drop",
8965      options: {
8966          accept: "*",
8967          activeClass: false,
8968          addClasses: true,
8969          greedy: false,
8970          hoverClass: false,
8971          scope: "default",
8972          tolerance: "intersect",
8973  
8974          // callbacks
8975          activate: null,
8976          deactivate: null,
8977          drop: null,
8978          out: null,
8979          over: null
8980      },
8981      _create: function() {
8982  
8983          var proportions,
8984              o = this.options,
8985              accept = o.accept;
8986  
8987          this.isover = false;
8988          this.isout = true;
8989  
8990          this.accept = $.isFunction( accept ) ? accept : function( d ) {
8991              return d.is( accept );
8992          };
8993  
8994          this.proportions = function( /* valueToWrite */ ) {
8995              if ( arguments.length ) {
8996                  // Store the droppable's proportions
8997                  proportions = arguments[ 0 ];
8998              } else {
8999                  // Retrieve or derive the droppable's proportions
9000                  return proportions ?
9001                      proportions :
9002                      proportions = {
9003                          width: this.element[ 0 ].offsetWidth,
9004                          height: this.element[ 0 ].offsetHeight
9005                      };
9006              }
9007          };
9008  
9009          this._addToManager( o.scope );
9010  
9011          o.addClasses && this.element.addClass( "ui-droppable" );
9012  
9013      },
9014  
9015      _addToManager: function( scope ) {
9016          // Add the reference and positions to the manager
9017          $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
9018          $.ui.ddmanager.droppables[ scope ].push( this );
9019      },
9020  
9021      _splice: function( drop ) {
9022          var i = 0;
9023          for ( ; i < drop.length; i++ ) {
9024              if ( drop[ i ] === this ) {
9025                  drop.splice( i, 1 );
9026              }
9027          }
9028      },
9029  
9030      _destroy: function() {
9031          var drop = $.ui.ddmanager.droppables[ this.options.scope ];
9032  
9033          this._splice( drop );
9034  
9035          this.element.removeClass( "ui-droppable ui-droppable-disabled" );
9036      },
9037  
9038      _setOption: function( key, value ) {
9039  
9040          if ( key === "accept" ) {
9041              this.accept = $.isFunction( value ) ? value : function( d ) {
9042                  return d.is( value );
9043              };
9044          } else if ( key === "scope" ) {
9045              var drop = $.ui.ddmanager.droppables[ this.options.scope ];
9046  
9047              this._splice( drop );
9048              this._addToManager( value );
9049          }
9050  
9051          this._super( key, value );
9052      },
9053  
9054      _activate: function( event ) {
9055          var draggable = $.ui.ddmanager.current;
9056          if ( this.options.activeClass ) {
9057              this.element.addClass( this.options.activeClass );
9058          }
9059          if ( draggable ){
9060              this._trigger( "activate", event, this.ui( draggable ) );
9061          }
9062      },
9063  
9064      _deactivate: function( event ) {
9065          var draggable = $.ui.ddmanager.current;
9066          if ( this.options.activeClass ) {
9067              this.element.removeClass( this.options.activeClass );
9068          }
9069          if ( draggable ){
9070              this._trigger( "deactivate", event, this.ui( draggable ) );
9071          }
9072      },
9073  
9074      _over: function( event ) {
9075  
9076          var draggable = $.ui.ddmanager.current;
9077  
9078          // Bail if draggable and droppable are same element
9079          if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
9080              return;
9081          }
9082  
9083          if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9084              if ( this.options.hoverClass ) {
9085                  this.element.addClass( this.options.hoverClass );
9086              }
9087              this._trigger( "over", event, this.ui( draggable ) );
9088          }
9089  
9090      },
9091  
9092      _out: function( event ) {
9093  
9094          var draggable = $.ui.ddmanager.current;
9095  
9096          // Bail if draggable and droppable are same element
9097          if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
9098              return;
9099          }
9100  
9101          if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9102              if ( this.options.hoverClass ) {
9103                  this.element.removeClass( this.options.hoverClass );
9104              }
9105              this._trigger( "out", event, this.ui( draggable ) );
9106          }
9107  
9108      },
9109  
9110      _drop: function( event, custom ) {
9111  
9112          var draggable = custom || $.ui.ddmanager.current,
9113              childrenIntersection = false;
9114  
9115          // Bail if draggable and droppable are same element
9116          if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
9117              return false;
9118          }
9119  
9120          this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
9121              var inst = $( this ).droppable( "instance" );
9122              if (
9123                  inst.options.greedy &&
9124                  !inst.options.disabled &&
9125                  inst.options.scope === draggable.options.scope &&
9126                  inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
9127                  $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
9128              ) { childrenIntersection = true; return false; }
9129          });
9130          if ( childrenIntersection ) {
9131              return false;
9132          }
9133  
9134          if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9135              if ( this.options.activeClass ) {
9136                  this.element.removeClass( this.options.activeClass );
9137              }
9138              if ( this.options.hoverClass ) {
9139                  this.element.removeClass( this.options.hoverClass );
9140              }
9141              this._trigger( "drop", event, this.ui( draggable ) );
9142              return this.element;
9143          }
9144  
9145          return false;
9146  
9147      },
9148  
9149      ui: function( c ) {
9150          return {
9151              draggable: ( c.currentItem || c.element ),
9152              helper: c.helper,
9153              position: c.position,
9154              offset: c.positionAbs
9155          };
9156      }
9157  
9158  });
9159  
9160  $.ui.intersect = (function() {
9161  	function isOverAxis( x, reference, size ) {
9162          return ( x >= reference ) && ( x < ( reference + size ) );
9163      }
9164  
9165      return function( draggable, droppable, toleranceMode, event ) {
9166  
9167          if ( !droppable.offset ) {
9168              return false;
9169          }
9170  
9171          var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
9172              y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
9173              x2 = x1 + draggable.helperProportions.width,
9174              y2 = y1 + draggable.helperProportions.height,
9175              l = droppable.offset.left,
9176              t = droppable.offset.top,
9177              r = l + droppable.proportions().width,
9178              b = t + droppable.proportions().height;
9179  
9180          switch ( toleranceMode ) {
9181          case "fit":
9182              return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
9183          case "intersect":
9184              return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
9185                  x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
9186                  t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
9187                  y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
9188          case "pointer":
9189              return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
9190          case "touch":
9191              return (
9192                  ( y1 >= t && y1 <= b ) || // Top edge touching
9193                  ( y2 >= t && y2 <= b ) || // Bottom edge touching
9194                  ( y1 < t && y2 > b ) // Surrounded vertically
9195              ) && (
9196                  ( x1 >= l && x1 <= r ) || // Left edge touching
9197                  ( x2 >= l && x2 <= r ) || // Right edge touching
9198                  ( x1 < l && x2 > r ) // Surrounded horizontally
9199              );
9200          default:
9201              return false;
9202          }
9203      };
9204  })();
9205  
9206  /*
9207      This manager tracks offsets of draggables and droppables
9208  */
9209  $.ui.ddmanager = {
9210      current: null,
9211      droppables: { "default": [] },
9212      prepareOffsets: function( t, event ) {
9213  
9214          var i, j,
9215              m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
9216              type = event ? event.type : null, // workaround for #2317
9217              list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
9218  
9219          droppablesLoop: for ( i = 0; i < m.length; i++ ) {
9220  
9221              // No disabled and non-accepted
9222              if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
9223                  continue;
9224              }
9225  
9226              // Filter out elements in the current dragged item
9227              for ( j = 0; j < list.length; j++ ) {
9228                  if ( list[ j ] === m[ i ].element[ 0 ] ) {
9229                      m[ i ].proportions().height = 0;
9230                      continue droppablesLoop;
9231                  }
9232              }
9233  
9234              m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
9235              if ( !m[ i ].visible ) {
9236                  continue;
9237              }
9238  
9239              // Activate the droppable if used directly from draggables
9240              if ( type === "mousedown" ) {
9241                  m[ i ]._activate.call( m[ i ], event );
9242              }
9243  
9244              m[ i ].offset = m[ i ].element.offset();
9245              m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
9246  
9247          }
9248  
9249      },
9250      drop: function( draggable, event ) {
9251  
9252          var dropped = false;
9253          // Create a copy of the droppables in case the list changes during the drop (#9116)
9254          $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
9255  
9256              if ( !this.options ) {
9257                  return;
9258              }
9259              if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
9260                  dropped = this._drop.call( this, event ) || dropped;
9261              }
9262  
9263              if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9264                  this.isout = true;
9265                  this.isover = false;
9266                  this._deactivate.call( this, event );
9267              }
9268  
9269          });
9270          return dropped;
9271  
9272      },
9273      dragStart: function( draggable, event ) {
9274          // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
9275          draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
9276              if ( !draggable.options.refreshPositions ) {
9277                  $.ui.ddmanager.prepareOffsets( draggable, event );
9278              }
9279          });
9280      },
9281      drag: function( draggable, event ) {
9282  
9283          // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
9284          if ( draggable.options.refreshPositions ) {
9285              $.ui.ddmanager.prepareOffsets( draggable, event );
9286          }
9287  
9288          // Run through all droppables and check their positions based on specific tolerance options
9289          $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
9290  
9291              if ( this.options.disabled || this.greedyChild || !this.visible ) {
9292                  return;
9293              }
9294  
9295              var parentInstance, scope, parent,
9296                  intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
9297                  c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
9298              if ( !c ) {
9299                  return;
9300              }
9301  
9302              if ( this.options.greedy ) {
9303                  // find droppable parents with same scope
9304                  scope = this.options.scope;
9305                  parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
9306                      return $( this ).droppable( "instance" ).options.scope === scope;
9307                  });
9308  
9309                  if ( parent.length ) {
9310                      parentInstance = $( parent[ 0 ] ).droppable( "instance" );
9311                      parentInstance.greedyChild = ( c === "isover" );
9312                  }
9313              }
9314  
9315              // we just moved into a greedy child
9316              if ( parentInstance && c === "isover" ) {
9317                  parentInstance.isover = false;
9318                  parentInstance.isout = true;
9319                  parentInstance._out.call( parentInstance, event );
9320              }
9321  
9322              this[ c ] = true;
9323              this[c === "isout" ? "isover" : "isout"] = false;
9324              this[c === "isover" ? "_over" : "_out"].call( this, event );
9325  
9326              // we just moved out of a greedy child
9327              if ( parentInstance && c === "isout" ) {
9328                  parentInstance.isout = false;
9329                  parentInstance.isover = true;
9330                  parentInstance._over.call( parentInstance, event );
9331              }
9332          });
9333  
9334      },
9335      dragStop: function( draggable, event ) {
9336          draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
9337          // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
9338          if ( !draggable.options.refreshPositions ) {
9339              $.ui.ddmanager.prepareOffsets( draggable, event );
9340          }
9341      }
9342  };
9343  
9344  var droppable = $.ui.droppable;
9345  
9346  
9347  /*!
9348   * jQuery UI Effects 1.11.4
9349   * http://jqueryui.com
9350   *
9351   * Copyright jQuery Foundation and other contributors
9352   * Released under the MIT license.
9353   * http://jquery.org/license
9354   *
9355   * http://api.jqueryui.com/category/effects-core/
9356   */
9357  
9358  
9359  var dataSpace = "ui-effects-",
9360  
9361      // Create a local jQuery because jQuery Color relies on it and the
9362      // global may not exist with AMD and a custom build (#10199)
9363      jQuery = $;
9364  
9365  $.effects = {
9366      effect: {}
9367  };
9368  
9369  /*!
9370   * jQuery Color Animations v2.1.2
9371   * https://github.com/jquery/jquery-color
9372   *
9373   * Copyright 2014 jQuery Foundation and other contributors
9374   * Released under the MIT license.
9375   * http://jquery.org/license
9376   *
9377   * Date: Wed Jan 16 08:47:09 2013 -0600
9378   */
9379  (function( jQuery, undefined ) {
9380  
9381      var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
9382  
9383      // plusequals test for += 100 -= 100
9384      rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
9385      // a set of RE's that can match strings and generate color tuples.
9386      stringParsers = [ {
9387              re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9388              parse: function( execResult ) {
9389                  return [
9390                      execResult[ 1 ],
9391                      execResult[ 2 ],
9392                      execResult[ 3 ],
9393                      execResult[ 4 ]
9394                  ];
9395              }
9396          }, {
9397              re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9398              parse: function( execResult ) {
9399                  return [
9400                      execResult[ 1 ] * 2.55,
9401                      execResult[ 2 ] * 2.55,
9402                      execResult[ 3 ] * 2.55,
9403                      execResult[ 4 ]
9404                  ];
9405              }
9406          }, {
9407              // this regex ignores A-F because it's compared against an already lowercased string
9408              re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
9409              parse: function( execResult ) {
9410                  return [
9411                      parseInt( execResult[ 1 ], 16 ),
9412                      parseInt( execResult[ 2 ], 16 ),
9413                      parseInt( execResult[ 3 ], 16 )
9414                  ];
9415              }
9416          }, {
9417              // this regex ignores A-F because it's compared against an already lowercased string
9418              re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
9419              parse: function( execResult ) {
9420                  return [
9421                      parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
9422                      parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
9423                      parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
9424                  ];
9425              }
9426          }, {
9427              re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9428              space: "hsla",
9429              parse: function( execResult ) {
9430                  return [
9431                      execResult[ 1 ],
9432                      execResult[ 2 ] / 100,
9433                      execResult[ 3 ] / 100,
9434                      execResult[ 4 ]
9435                  ];
9436              }
9437          } ],
9438  
9439      // jQuery.Color( )
9440      color = jQuery.Color = function( color, green, blue, alpha ) {
9441          return new jQuery.Color.fn.parse( color, green, blue, alpha );
9442      },
9443      spaces = {
9444          rgba: {
9445              props: {
9446                  red: {
9447                      idx: 0,
9448                      type: "byte"
9449                  },
9450                  green: {
9451                      idx: 1,
9452                      type: "byte"
9453                  },
9454                  blue: {
9455                      idx: 2,
9456                      type: "byte"
9457                  }
9458              }
9459          },
9460  
9461          hsla: {
9462              props: {
9463                  hue: {
9464                      idx: 0,
9465                      type: "degrees"
9466                  },
9467                  saturation: {
9468                      idx: 1,
9469                      type: "percent"
9470                  },
9471                  lightness: {
9472                      idx: 2,
9473                      type: "percent"
9474                  }
9475              }
9476          }
9477      },
9478      propTypes = {
9479          "byte": {
9480              floor: true,
9481              max: 255
9482          },
9483          "percent": {
9484              max: 1
9485          },
9486          "degrees": {
9487              mod: 360,
9488              floor: true
9489          }
9490      },
9491      support = color.support = {},
9492  
9493      // element for support tests
9494      supportElem = jQuery( "<p>" )[ 0 ],
9495  
9496      // colors = jQuery.Color.names
9497      colors,
9498  
9499      // local aliases of functions called often
9500      each = jQuery.each;
9501  
9502  // determine rgba support immediately
9503  supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
9504  support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
9505  
9506  // define cache name and alpha properties
9507  // for rgba and hsla spaces
9508  each( spaces, function( spaceName, space ) {
9509      space.cache = "_" + spaceName;
9510      space.props.alpha = {
9511          idx: 3,
9512          type: "percent",
9513          def: 1
9514      };
9515  });
9516  
9517  function clamp( value, prop, allowEmpty ) {
9518      var type = propTypes[ prop.type ] || {};
9519  
9520      if ( value == null ) {
9521          return (allowEmpty || !prop.def) ? null : prop.def;
9522      }
9523  
9524      // ~~ is an short way of doing floor for positive numbers
9525      value = type.floor ? ~~value : parseFloat( value );
9526  
9527      // IE will pass in empty strings as value for alpha,
9528      // which will hit this case
9529      if ( isNaN( value ) ) {
9530          return prop.def;
9531      }
9532  
9533      if ( type.mod ) {
9534          // we add mod before modding to make sure that negatives values
9535          // get converted properly: -10 -> 350
9536          return (value + type.mod) % type.mod;
9537      }
9538  
9539      // for now all property types without mod have min and max
9540      return 0 > value ? 0 : type.max < value ? type.max : value;
9541  }
9542  
9543  function stringParse( string ) {
9544      var inst = color(),
9545          rgba = inst._rgba = [];
9546  
9547      string = string.toLowerCase();
9548  
9549      each( stringParsers, function( i, parser ) {
9550          var parsed,
9551              match = parser.re.exec( string ),
9552              values = match && parser.parse( match ),
9553              spaceName = parser.space || "rgba";
9554  
9555          if ( values ) {
9556              parsed = inst[ spaceName ]( values );
9557  
9558              // if this was an rgba parse the assignment might happen twice
9559              // oh well....
9560              inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
9561              rgba = inst._rgba = parsed._rgba;
9562  
9563              // exit each( stringParsers ) here because we matched
9564              return false;
9565          }
9566      });
9567  
9568      // Found a stringParser that handled it
9569      if ( rgba.length ) {
9570  
9571          // if this came from a parsed string, force "transparent" when alpha is 0
9572          // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
9573          if ( rgba.join() === "0,0,0,0" ) {
9574              jQuery.extend( rgba, colors.transparent );
9575          }
9576          return inst;
9577      }
9578  
9579      // named colors
9580      return colors[ string ];
9581  }
9582  
9583  color.fn = jQuery.extend( color.prototype, {
9584      parse: function( red, green, blue, alpha ) {
9585          if ( red === undefined ) {
9586              this._rgba = [ null, null, null, null ];
9587              return this;
9588          }
9589          if ( red.jquery || red.nodeType ) {
9590              red = jQuery( red ).css( green );
9591              green = undefined;
9592          }
9593  
9594          var inst = this,
9595              type = jQuery.type( red ),
9596              rgba = this._rgba = [];
9597  
9598          // more than 1 argument specified - assume ( red, green, blue, alpha )
9599          if ( green !== undefined ) {
9600              red = [ red, green, blue, alpha ];
9601              type = "array";
9602          }
9603  
9604          if ( type === "string" ) {
9605              return this.parse( stringParse( red ) || colors._default );
9606          }
9607  
9608          if ( type === "array" ) {
9609              each( spaces.rgba.props, function( key, prop ) {
9610                  rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
9611              });
9612              return this;
9613          }
9614  
9615          if ( type === "object" ) {
9616              if ( red instanceof color ) {
9617                  each( spaces, function( spaceName, space ) {
9618                      if ( red[ space.cache ] ) {
9619                          inst[ space.cache ] = red[ space.cache ].slice();
9620                      }
9621                  });
9622              } else {
9623                  each( spaces, function( spaceName, space ) {
9624                      var cache = space.cache;
9625                      each( space.props, function( key, prop ) {
9626  
9627                          // if the cache doesn't exist, and we know how to convert
9628                          if ( !inst[ cache ] && space.to ) {
9629  
9630                              // if the value was null, we don't need to copy it
9631                              // if the key was alpha, we don't need to copy it either
9632                              if ( key === "alpha" || red[ key ] == null ) {
9633                                  return;
9634                              }
9635                              inst[ cache ] = space.to( inst._rgba );
9636                          }
9637  
9638                          // this is the only case where we allow nulls for ALL properties.
9639                          // call clamp with alwaysAllowEmpty
9640                          inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
9641                      });
9642  
9643                      // everything defined but alpha?
9644                      if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
9645                          // use the default of 1
9646                          inst[ cache ][ 3 ] = 1;
9647                          if ( space.from ) {
9648                              inst._rgba = space.from( inst[ cache ] );
9649                          }
9650                      }
9651                  });
9652              }
9653              return this;
9654          }
9655      },
9656      is: function( compare ) {
9657          var is = color( compare ),
9658              same = true,
9659              inst = this;
9660  
9661          each( spaces, function( _, space ) {
9662              var localCache,
9663                  isCache = is[ space.cache ];
9664              if (isCache) {
9665                  localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
9666                  each( space.props, function( _, prop ) {
9667                      if ( isCache[ prop.idx ] != null ) {
9668                          same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
9669                          return same;
9670                      }
9671                  });
9672              }
9673              return same;
9674          });
9675          return same;
9676      },
9677      _space: function() {
9678          var used = [],
9679              inst = this;
9680          each( spaces, function( spaceName, space ) {
9681              if ( inst[ space.cache ] ) {
9682                  used.push( spaceName );
9683              }
9684          });
9685          return used.pop();
9686      },
9687      transition: function( other, distance ) {
9688          var end = color( other ),
9689              spaceName = end._space(),
9690              space = spaces[ spaceName ],
9691              startColor = this.alpha() === 0 ? color( "transparent" ) : this,
9692              start = startColor[ space.cache ] || space.to( startColor._rgba ),
9693              result = start.slice();
9694  
9695          end = end[ space.cache ];
9696          each( space.props, function( key, prop ) {
9697              var index = prop.idx,
9698                  startValue = start[ index ],
9699                  endValue = end[ index ],
9700                  type = propTypes[ prop.type ] || {};
9701  
9702              // if null, don't override start value
9703              if ( endValue === null ) {
9704                  return;
9705              }
9706              // if null - use end
9707              if ( startValue === null ) {
9708                  result[ index ] = endValue;
9709              } else {
9710                  if ( type.mod ) {
9711                      if ( endValue - startValue > type.mod / 2 ) {
9712                          startValue += type.mod;
9713                      } else if ( startValue - endValue > type.mod / 2 ) {
9714                          startValue -= type.mod;
9715                      }
9716                  }
9717                  result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
9718              }
9719          });
9720          return this[ spaceName ]( result );
9721      },
9722      blend: function( opaque ) {
9723          // if we are already opaque - return ourself
9724          if ( this._rgba[ 3 ] === 1 ) {
9725              return this;
9726          }
9727  
9728          var rgb = this._rgba.slice(),
9729              a = rgb.pop(),
9730              blend = color( opaque )._rgba;
9731  
9732          return color( jQuery.map( rgb, function( v, i ) {
9733              return ( 1 - a ) * blend[ i ] + a * v;
9734          }));
9735      },
9736      toRgbaString: function() {
9737          var prefix = "rgba(",
9738              rgba = jQuery.map( this._rgba, function( v, i ) {
9739                  return v == null ? ( i > 2 ? 1 : 0 ) : v;
9740              });
9741  
9742          if ( rgba[ 3 ] === 1 ) {
9743              rgba.pop();
9744              prefix = "rgb(";
9745          }
9746  
9747          return prefix + rgba.join() + ")";
9748      },
9749      toHslaString: function() {
9750          var prefix = "hsla(",
9751              hsla = jQuery.map( this.hsla(), function( v, i ) {
9752                  if ( v == null ) {
9753                      v = i > 2 ? 1 : 0;
9754                  }
9755  
9756                  // catch 1 and 2
9757                  if ( i && i < 3 ) {
9758                      v = Math.round( v * 100 ) + "%";
9759                  }
9760                  return v;
9761              });
9762  
9763          if ( hsla[ 3 ] === 1 ) {
9764              hsla.pop();
9765              prefix = "hsl(";
9766          }
9767          return prefix + hsla.join() + ")";
9768      },
9769      toHexString: function( includeAlpha ) {
9770          var rgba = this._rgba.slice(),
9771              alpha = rgba.pop();
9772  
9773          if ( includeAlpha ) {
9774              rgba.push( ~~( alpha * 255 ) );
9775          }
9776  
9777          return "#" + jQuery.map( rgba, function( v ) {
9778  
9779              // default to 0 when nulls exist
9780              v = ( v || 0 ).toString( 16 );
9781              return v.length === 1 ? "0" + v : v;
9782          }).join("");
9783      },
9784      toString: function() {
9785          return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
9786      }
9787  });
9788  color.fn.parse.prototype = color.fn;
9789  
9790  // hsla conversions adapted from:
9791  // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
9792  
9793  function hue2rgb( p, q, h ) {
9794      h = ( h + 1 ) % 1;
9795      if ( h * 6 < 1 ) {
9796          return p + ( q - p ) * h * 6;
9797      }
9798      if ( h * 2 < 1) {
9799          return q;
9800      }
9801      if ( h * 3 < 2 ) {
9802          return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
9803      }
9804      return p;
9805  }
9806  
9807  spaces.hsla.to = function( rgba ) {
9808      if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
9809          return [ null, null, null, rgba[ 3 ] ];
9810      }
9811      var r = rgba[ 0 ] / 255,
9812          g = rgba[ 1 ] / 255,
9813          b = rgba[ 2 ] / 255,
9814          a = rgba[ 3 ],
9815          max = Math.max( r, g, b ),
9816          min = Math.min( r, g, b ),
9817          diff = max - min,
9818          add = max + min,
9819          l = add * 0.5,
9820          h, s;
9821  
9822      if ( min === max ) {
9823          h = 0;
9824      } else if ( r === max ) {
9825          h = ( 60 * ( g - b ) / diff ) + 360;
9826      } else if ( g === max ) {
9827          h = ( 60 * ( b - r ) / diff ) + 120;
9828      } else {
9829          h = ( 60 * ( r - g ) / diff ) + 240;
9830      }
9831  
9832      // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
9833      // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
9834      if ( diff === 0 ) {
9835          s = 0;
9836      } else if ( l <= 0.5 ) {
9837          s = diff / add;
9838      } else {
9839          s = diff / ( 2 - add );
9840      }
9841      return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
9842  };
9843  
9844  spaces.hsla.from = function( hsla ) {
9845      if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
9846          return [ null, null, null, hsla[ 3 ] ];
9847      }
9848      var h = hsla[ 0 ] / 360,
9849          s = hsla[ 1 ],
9850          l = hsla[ 2 ],
9851          a = hsla[ 3 ],
9852          q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
9853          p = 2 * l - q;
9854  
9855      return [
9856          Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
9857          Math.round( hue2rgb( p, q, h ) * 255 ),
9858          Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
9859          a
9860      ];
9861  };
9862  
9863  each( spaces, function( spaceName, space ) {
9864      var props = space.props,
9865          cache = space.cache,
9866          to = space.to,
9867          from = space.from;
9868  
9869      // makes rgba() and hsla()
9870      color.fn[ spaceName ] = function( value ) {
9871  
9872          // generate a cache for this space if it doesn't exist
9873          if ( to && !this[ cache ] ) {
9874              this[ cache ] = to( this._rgba );
9875          }
9876          if ( value === undefined ) {
9877              return this[ cache ].slice();
9878          }
9879  
9880          var ret,
9881              type = jQuery.type( value ),
9882              arr = ( type === "array" || type === "object" ) ? value : arguments,
9883              local = this[ cache ].slice();
9884  
9885          each( props, function( key, prop ) {
9886              var val = arr[ type === "object" ? key : prop.idx ];
9887              if ( val == null ) {
9888                  val = local[ prop.idx ];
9889              }
9890              local[ prop.idx ] = clamp( val, prop );
9891          });
9892  
9893          if ( from ) {
9894              ret = color( from( local ) );
9895              ret[ cache ] = local;
9896              return ret;
9897          } else {
9898              return color( local );
9899          }
9900      };
9901  
9902      // makes red() green() blue() alpha() hue() saturation() lightness()
9903      each( props, function( key, prop ) {
9904          // alpha is included in more than one space
9905          if ( color.fn[ key ] ) {
9906              return;
9907          }
9908          color.fn[ key ] = function( value ) {
9909              var vtype = jQuery.type( value ),
9910                  fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
9911                  local = this[ fn ](),
9912                  cur = local[ prop.idx ],
9913                  match;
9914  
9915              if ( vtype === "undefined" ) {
9916                  return cur;
9917              }
9918  
9919              if ( vtype === "function" ) {
9920                  value = value.call( this, cur );
9921                  vtype = jQuery.type( value );
9922              }
9923              if ( value == null && prop.empty ) {
9924                  return this;
9925              }
9926              if ( vtype === "string" ) {
9927                  match = rplusequals.exec( value );
9928                  if ( match ) {
9929                      value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
9930                  }
9931              }
9932              local[ prop.idx ] = value;
9933              return this[ fn ]( local );
9934          };
9935      });
9936  });
9937  
9938  // add cssHook and .fx.step function for each named hook.
9939  // accept a space separated string of properties
9940  color.hook = function( hook ) {
9941      var hooks = hook.split( " " );
9942      each( hooks, function( i, hook ) {
9943          jQuery.cssHooks[ hook ] = {
9944              set: function( elem, value ) {
9945                  var parsed, curElem,
9946                      backgroundColor = "";
9947  
9948                  if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
9949                      value = color( parsed || value );
9950                      if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
9951                          curElem = hook === "backgroundColor" ? elem.parentNode : elem;
9952                          while (
9953                              (backgroundColor === "" || backgroundColor === "transparent") &&
9954                              curElem && curElem.style
9955                          ) {
9956                              try {
9957                                  backgroundColor = jQuery.css( curElem, "backgroundColor" );
9958                                  curElem = curElem.parentNode;
9959                              } catch ( e ) {
9960                              }
9961                          }
9962  
9963                          value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
9964                              backgroundColor :
9965                              "_default" );
9966                      }
9967  
9968                      value = value.toRgbaString();
9969                  }
9970                  try {
9971                      elem.style[ hook ] = value;
9972                  } catch ( e ) {
9973                      // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
9974                  }
9975              }
9976          };
9977          jQuery.fx.step[ hook ] = function( fx ) {
9978              if ( !fx.colorInit ) {
9979                  fx.start = color( fx.elem, hook );
9980                  fx.end = color( fx.end );
9981                  fx.colorInit = true;
9982              }
9983              jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
9984          };
9985      });
9986  
9987  };
9988  
9989  color.hook( stepHooks );
9990  
9991  jQuery.cssHooks.borderColor = {
9992      expand: function( value ) {
9993          var expanded = {};
9994  
9995          each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
9996              expanded[ "border" + part + "Color" ] = value;
9997          });
9998          return expanded;
9999      }
10000  };
10001  
10002  // Basic color names only.
10003  // Usage of any of the other color names requires adding yourself or including
10004  // jquery.color.svg-names.js.
10005  colors = jQuery.Color.names = {
10006      // 4.1. Basic color keywords
10007      aqua: "#00ffff",
10008      black: "#000000",
10009      blue: "#0000ff",
10010      fuchsia: "#ff00ff",
10011      gray: "#808080",
10012      green: "#008000",
10013      lime: "#00ff00",
10014      maroon: "#800000",
10015      navy: "#000080",
10016      olive: "#808000",
10017      purple: "#800080",
10018      red: "#ff0000",
10019      silver: "#c0c0c0",
10020      teal: "#008080",
10021      white: "#ffffff",
10022      yellow: "#ffff00",
10023  
10024      // 4.2.3. "transparent" color keyword
10025      transparent: [ null, null, null, 0 ],
10026  
10027      _default: "#ffffff"
10028  };
10029  
10030  })( jQuery );
10031  
10032  /******************************************************************************/
10033  /****************************** CLASS ANIMATIONS ******************************/
10034  /******************************************************************************/
10035  (function() {
10036  
10037  var classAnimationActions = [ "add", "remove", "toggle" ],
10038      shorthandStyles = {
10039          border: 1,
10040          borderBottom: 1,
10041          borderColor: 1,
10042          borderLeft: 1,
10043          borderRight: 1,
10044          borderTop: 1,
10045          borderWidth: 1,
10046          margin: 1,
10047          padding: 1
10048      };
10049  
10050  $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
10051      $.fx.step[ prop ] = function( fx ) {
10052          if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
10053              jQuery.style( fx.elem, prop, fx.end );
10054              fx.setAttr = true;
10055          }
10056      };
10057  });
10058  
10059  function getElementStyles( elem ) {
10060      var key, len,
10061          style = elem.ownerDocument.defaultView ?
10062              elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
10063              elem.currentStyle,
10064          styles = {};
10065  
10066      if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
10067          len = style.length;
10068          while ( len-- ) {
10069              key = style[ len ];
10070              if ( typeof style[ key ] === "string" ) {
10071                  styles[ $.camelCase( key ) ] = style[ key ];
10072              }
10073          }
10074      // support: Opera, IE <9
10075      } else {
10076          for ( key in style ) {
10077              if ( typeof style[ key ] === "string" ) {
10078                  styles[ key ] = style[ key ];
10079              }
10080          }
10081      }
10082  
10083      return styles;
10084  }
10085  
10086  function styleDifference( oldStyle, newStyle ) {
10087      var diff = {},
10088          name, value;
10089  
10090      for ( name in newStyle ) {
10091          value = newStyle[ name ];
10092          if ( oldStyle[ name ] !== value ) {
10093              if ( !shorthandStyles[ name ] ) {
10094                  if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
10095                      diff[ name ] = value;
10096                  }
10097              }
10098          }
10099      }
10100  
10101      return diff;
10102  }
10103  
10104  // support: jQuery <1.8
10105  if ( !$.fn.addBack ) {
10106      $.fn.addBack = function( selector ) {
10107          return this.add( selector == null ?
10108              this.prevObject : this.prevObject.filter( selector )
10109          );
10110      };
10111  }
10112  
10113  $.effects.animateClass = function( value, duration, easing, callback ) {
10114      var o = $.speed( duration, easing, callback );
10115  
10116      return this.queue( function() {
10117          var animated = $( this ),
10118              baseClass = animated.attr( "class" ) || "",
10119              applyClassChange,
10120              allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
10121  
10122          // map the animated objects to store the original styles.
10123          allAnimations = allAnimations.map(function() {
10124              var el = $( this );
10125              return {
10126                  el: el,
10127                  start: getElementStyles( this )
10128              };
10129          });
10130  
10131          // apply class change
10132          applyClassChange = function() {
10133              $.each( classAnimationActions, function(i, action) {
10134                  if ( value[ action ] ) {
10135                      animated[ action + "Class" ]( value[ action ] );
10136                  }
10137              });
10138          };
10139          applyClassChange();
10140  
10141          // map all animated objects again - calculate new styles and diff
10142          allAnimations = allAnimations.map(function() {
10143              this.end = getElementStyles( this.el[ 0 ] );
10144              this.diff = styleDifference( this.start, this.end );
10145              return this;
10146          });
10147  
10148          // apply original class
10149          animated.attr( "class", baseClass );
10150  
10151          // map all animated objects again - this time collecting a promise
10152          allAnimations = allAnimations.map(function() {
10153              var styleInfo = this,
10154                  dfd = $.Deferred(),
10155                  opts = $.extend({}, o, {
10156                      queue: false,
10157                      complete: function() {
10158                          dfd.resolve( styleInfo );
10159                      }
10160                  });
10161  
10162              this.el.animate( this.diff, opts );
10163              return dfd.promise();
10164          });
10165  
10166          // once all animations have completed:
10167          $.when.apply( $, allAnimations.get() ).done(function() {
10168  
10169              // set the final class
10170              applyClassChange();
10171  
10172              // for each animated element,
10173              // clear all css properties that were animated
10174              $.each( arguments, function() {
10175                  var el = this.el;
10176                  $.each( this.diff, function(key) {
10177                      el.css( key, "" );
10178                  });
10179              });
10180  
10181              // this is guarnteed to be there if you use jQuery.speed()
10182              // it also handles dequeuing the next anim...
10183              o.complete.call( animated[ 0 ] );
10184          });
10185      });
10186  };
10187  
10188  $.fn.extend({
10189      addClass: (function( orig ) {
10190          return function( classNames, speed, easing, callback ) {
10191              return speed ?
10192                  $.effects.animateClass.call( this,
10193                      { add: classNames }, speed, easing, callback ) :
10194                  orig.apply( this, arguments );
10195          };
10196      })( $.fn.addClass ),
10197  
10198      removeClass: (function( orig ) {
10199          return function( classNames, speed, easing, callback ) {
10200              return arguments.length > 1 ?
10201                  $.effects.animateClass.call( this,
10202                      { remove: classNames }, speed, easing, callback ) :
10203                  orig.apply( this, arguments );
10204          };
10205      })( $.fn.removeClass ),
10206  
10207      toggleClass: (function( orig ) {
10208          return function( classNames, force, speed, easing, callback ) {
10209              if ( typeof force === "boolean" || force === undefined ) {
10210                  if ( !speed ) {
10211                      // without speed parameter
10212                      return orig.apply( this, arguments );
10213                  } else {
10214                      return $.effects.animateClass.call( this,
10215                          (force ? { add: classNames } : { remove: classNames }),
10216                          speed, easing, callback );
10217                  }
10218              } else {
10219                  // without force parameter
10220                  return $.effects.animateClass.call( this,
10221                      { toggle: classNames }, force, speed, easing );
10222              }
10223          };
10224      })( $.fn.toggleClass ),
10225  
10226      switchClass: function( remove, add, speed, easing, callback) {
10227          return $.effects.animateClass.call( this, {
10228              add: add,
10229              remove: remove
10230          }, speed, easing, callback );
10231      }
10232  });
10233  
10234  })();
10235  
10236  /******************************************************************************/
10237  /*********************************** EFFECTS **********************************/
10238  /******************************************************************************/
10239  
10240  (function() {
10241  
10242  $.extend( $.effects, {
10243      version: "1.11.4",
10244  
10245      // Saves a set of properties in a data storage
10246      save: function( element, set ) {
10247          for ( var i = 0; i < set.length; i++ ) {
10248              if ( set[ i ] !== null ) {
10249                  element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
10250              }
10251          }
10252      },
10253  
10254      // Restores a set of previously saved properties from a data storage
10255      restore: function( element, set ) {
10256          var val, i;
10257          for ( i = 0; i < set.length; i++ ) {
10258              if ( set[ i ] !== null ) {
10259                  val = element.data( dataSpace + set[ i ] );
10260                  // support: jQuery 1.6.2
10261                  // http://bugs.jquery.com/ticket/9917
10262                  // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
10263                  // We can't differentiate between "" and 0 here, so we just assume
10264                  // empty string since it's likely to be a more common value...
10265                  if ( val === undefined ) {
10266                      val = "";
10267                  }
10268                  element.css( set[ i ], val );
10269              }
10270          }
10271      },
10272  
10273      setMode: function( el, mode ) {
10274          if (mode === "toggle") {
10275              mode = el.is( ":hidden" ) ? "show" : "hide";
10276          }
10277          return mode;
10278      },
10279  
10280      // Translates a [top,left] array into a baseline value
10281      // this should be a little more flexible in the future to handle a string & hash
10282      getBaseline: function( origin, original ) {
10283          var y, x;
10284          switch ( origin[ 0 ] ) {
10285              case "top": y = 0; break;
10286              case "middle": y = 0.5; break;
10287              case "bottom": y = 1; break;
10288              default: y = origin[ 0 ] / original.height;
10289          }
10290          switch ( origin[ 1 ] ) {
10291              case "left": x = 0; break;
10292              case "center": x = 0.5; break;
10293              case "right": x = 1; break;
10294              default: x = origin[ 1 ] / original.width;
10295          }
10296          return {
10297              x: x,
10298              y: y
10299          };
10300      },
10301  
10302      // Wraps the element around a wrapper that copies position properties
10303      createWrapper: function( element ) {
10304  
10305          // if the element is already wrapped, return it
10306          if ( element.parent().is( ".ui-effects-wrapper" )) {
10307              return element.parent();
10308          }
10309  
10310          // wrap the element
10311          var props = {
10312                  width: element.outerWidth(true),
10313                  height: element.outerHeight(true),
10314                  "float": element.css( "float" )
10315              },
10316              wrapper = $( "<div></div>" )
10317                  .addClass( "ui-effects-wrapper" )
10318                  .css({
10319                      fontSize: "100%",
10320                      background: "transparent",
10321                      border: "none",
10322                      margin: 0,
10323                      padding: 0
10324                  }),
10325              // Store the size in case width/height are defined in % - Fixes #5245
10326              size = {
10327                  width: element.width(),
10328                  height: element.height()
10329              },
10330              active = document.activeElement;
10331  
10332          // support: Firefox
10333          // Firefox incorrectly exposes anonymous content
10334          // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
10335          try {
10336              active.id;
10337          } catch ( e ) {
10338              active = document.body;
10339          }
10340  
10341          element.wrap( wrapper );
10342  
10343          // Fixes #7595 - Elements lose focus when wrapped.
10344          if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
10345              $( active ).focus();
10346          }
10347  
10348          wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
10349  
10350          // transfer positioning properties to the wrapper
10351          if ( element.css( "position" ) === "static" ) {
10352              wrapper.css({ position: "relative" });
10353              element.css({ position: "relative" });
10354          } else {
10355              $.extend( props, {
10356                  position: element.css( "position" ),
10357                  zIndex: element.css( "z-index" )
10358              });
10359              $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
10360                  props[ pos ] = element.css( pos );
10361                  if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
10362                      props[ pos ] = "auto";
10363                  }
10364              });
10365              element.css({
10366                  position: "relative",
10367                  top: 0,
10368                  left: 0,
10369                  right: "auto",
10370                  bottom: "auto"
10371              });
10372          }
10373          element.css(size);
10374  
10375          return wrapper.css( props ).show();
10376      },
10377  
10378      removeWrapper: function( element ) {
10379          var active = document.activeElement;
10380  
10381          if ( element.parent().is( ".ui-effects-wrapper" ) ) {
10382              element.parent().replaceWith( element );
10383  
10384              // Fixes #7595 - Elements lose focus when wrapped.
10385              if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
10386                  $( active ).focus();
10387              }
10388          }
10389  
10390          return element;
10391      },
10392  
10393      setTransition: function( element, list, factor, value ) {
10394          value = value || {};
10395          $.each( list, function( i, x ) {
10396              var unit = element.cssUnit( x );
10397              if ( unit[ 0 ] > 0 ) {
10398                  value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
10399              }
10400          });
10401          return value;
10402      }
10403  });
10404  
10405  // return an effect options object for the given parameters:
10406  function _normalizeArguments( effect, options, speed, callback ) {
10407  
10408      // allow passing all options as the first parameter
10409      if ( $.isPlainObject( effect ) ) {
10410          options = effect;
10411          effect = effect.effect;
10412      }
10413  
10414      // convert to an object
10415      effect = { effect: effect };
10416  
10417      // catch (effect, null, ...)
10418      if ( options == null ) {
10419          options = {};
10420      }
10421  
10422      // catch (effect, callback)
10423      if ( $.isFunction( options ) ) {
10424          callback = options;
10425          speed = null;
10426          options = {};
10427      }
10428  
10429      // catch (effect, speed, ?)
10430      if ( typeof options === "number" || $.fx.speeds[ options ] ) {
10431          callback = speed;
10432          speed = options;
10433          options = {};
10434      }
10435  
10436      // catch (effect, options, callback)
10437      if ( $.isFunction( speed ) ) {
10438          callback = speed;
10439          speed = null;
10440      }
10441  
10442      // add options to effect
10443      if ( options ) {
10444          $.extend( effect, options );
10445      }
10446  
10447      speed = speed || options.duration;
10448      effect.duration = $.fx.off ? 0 :
10449          typeof speed === "number" ? speed :
10450          speed in $.fx.speeds ? $.fx.speeds[ speed ] :
10451          $.fx.speeds._default;
10452  
10453      effect.complete = callback || options.complete;
10454  
10455      return effect;
10456  }
10457  
10458  function standardAnimationOption( option ) {
10459      // Valid standard speeds (nothing, number, named speed)
10460      if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
10461          return true;
10462      }
10463  
10464      // Invalid strings - treat as "normal" speed
10465      if ( typeof option === "string" && !$.effects.effect[ option ] ) {
10466          return true;
10467      }
10468  
10469      // Complete callback
10470      if ( $.isFunction( option ) ) {
10471          return true;
10472      }
10473  
10474      // Options hash (but not naming an effect)
10475      if ( typeof option === "object" && !option.effect ) {
10476          return true;
10477      }
10478  
10479      // Didn't match any standard API
10480      return false;
10481  }
10482  
10483  $.fn.extend({
10484      effect: function( /* effect, options, speed, callback */ ) {
10485          var args = _normalizeArguments.apply( this, arguments ),
10486              mode = args.mode,
10487              queue = args.queue,
10488              effectMethod = $.effects.effect[ args.effect ];
10489  
10490          if ( $.fx.off || !effectMethod ) {
10491              // delegate to the original method (e.g., .show()) if possible
10492              if ( mode ) {
10493                  return this[ mode ]( args.duration, args.complete );
10494              } else {
10495                  return this.each( function() {
10496                      if ( args.complete ) {
10497                          args.complete.call( this );
10498                      }
10499                  });
10500              }
10501          }
10502  
10503  		function run( next ) {
10504              var elem = $( this ),
10505                  complete = args.complete,
10506                  mode = args.mode;
10507  
10508  			function done() {
10509                  if ( $.isFunction( complete ) ) {
10510                      complete.call( elem[0] );
10511                  }
10512                  if ( $.isFunction( next ) ) {
10513                      next();
10514                  }
10515              }
10516  
10517              // If the element already has the correct final state, delegate to
10518              // the core methods so the internal tracking of "olddisplay" works.
10519              if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
10520                  elem[ mode ]();
10521                  done();
10522              } else {
10523                  effectMethod.call( elem[0], args, done );
10524              }
10525          }
10526  
10527          return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
10528      },
10529  
10530      show: (function( orig ) {
10531          return function( option ) {
10532              if ( standardAnimationOption( option ) ) {
10533                  return orig.apply( this, arguments );
10534              } else {
10535                  var args = _normalizeArguments.apply( this, arguments );
10536                  args.mode = "show";
10537                  return this.effect.call( this, args );
10538              }
10539          };
10540      })( $.fn.show ),
10541  
10542      hide: (function( orig ) {
10543          return function( option ) {
10544              if ( standardAnimationOption( option ) ) {
10545                  return orig.apply( this, arguments );
10546              } else {
10547                  var args = _normalizeArguments.apply( this, arguments );
10548                  args.mode = "hide";
10549                  return this.effect.call( this, args );
10550              }
10551          };
10552      })( $.fn.hide ),
10553  
10554      toggle: (function( orig ) {
10555          return function( option ) {
10556              if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
10557                  return orig.apply( this, arguments );
10558              } else {
10559                  var args = _normalizeArguments.apply( this, arguments );
10560                  args.mode = "toggle";
10561                  return this.effect.call( this, args );
10562              }
10563          };
10564      })( $.fn.toggle ),
10565  
10566      // helper functions
10567      cssUnit: function(key) {
10568          var style = this.css( key ),
10569              val = [];
10570  
10571          $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
10572              if ( style.indexOf( unit ) > 0 ) {
10573                  val = [ parseFloat( style ), unit ];
10574              }
10575          });
10576          return val;
10577      }
10578  });
10579  
10580  })();
10581  
10582  /******************************************************************************/
10583  /*********************************** EASING ***********************************/
10584  /******************************************************************************/
10585  
10586  (function() {
10587  
10588  // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
10589  
10590  var baseEasings = {};
10591  
10592  $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
10593      baseEasings[ name ] = function( p ) {
10594          return Math.pow( p, i + 2 );
10595      };
10596  });
10597  
10598  $.extend( baseEasings, {
10599      Sine: function( p ) {
10600          return 1 - Math.cos( p * Math.PI / 2 );
10601      },
10602      Circ: function( p ) {
10603          return 1 - Math.sqrt( 1 - p * p );
10604      },
10605      Elastic: function( p ) {
10606          return p === 0 || p === 1 ? p :
10607              -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
10608      },
10609      Back: function( p ) {
10610          return p * p * ( 3 * p - 2 );
10611      },
10612      Bounce: function( p ) {
10613          var pow2,
10614              bounce = 4;
10615  
10616          while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
10617          return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
10618      }
10619  });
10620  
10621  $.each( baseEasings, function( name, easeIn ) {
10622      $.easing[ "easeIn" + name ] = easeIn;
10623      $.easing[ "easeOut" + name ] = function( p ) {
10624          return 1 - easeIn( 1 - p );
10625      };
10626      $.easing[ "easeInOut" + name ] = function( p ) {
10627          return p < 0.5 ?
10628              easeIn( p * 2 ) / 2 :
10629              1 - easeIn( p * -2 + 2 ) / 2;
10630      };
10631  });
10632  
10633  })();
10634  
10635  var effect = $.effects;
10636  
10637  
10638  /*!
10639   * jQuery UI Effects Blind 1.11.4
10640   * http://jqueryui.com
10641   *
10642   * Copyright jQuery Foundation and other contributors
10643   * Released under the MIT license.
10644   * http://jquery.org/license
10645   *
10646   * http://api.jqueryui.com/blind-effect/
10647   */
10648  
10649  
10650  var effectBlind = $.effects.effect.blind = function( o, done ) {
10651      // Create element
10652      var el = $( this ),
10653          rvertical = /up|down|vertical/,
10654          rpositivemotion = /up|left|vertical|horizontal/,
10655          props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10656          mode = $.effects.setMode( el, o.mode || "hide" ),
10657          direction = o.direction || "up",
10658          vertical = rvertical.test( direction ),
10659          ref = vertical ? "height" : "width",
10660          ref2 = vertical ? "top" : "left",
10661          motion = rpositivemotion.test( direction ),
10662          animation = {},
10663          show = mode === "show",
10664          wrapper, distance, margin;
10665  
10666      // if already wrapped, the wrapper's properties are my property. #6245
10667      if ( el.parent().is( ".ui-effects-wrapper" ) ) {
10668          $.effects.save( el.parent(), props );
10669      } else {
10670          $.effects.save( el, props );
10671      }
10672      el.show();
10673      wrapper = $.effects.createWrapper( el ).css({
10674          overflow: "hidden"
10675      });
10676  
10677      distance = wrapper[ ref ]();
10678      margin = parseFloat( wrapper.css( ref2 ) ) || 0;
10679  
10680      animation[ ref ] = show ? distance : 0;
10681      if ( !motion ) {
10682          el
10683              .css( vertical ? "bottom" : "right", 0 )
10684              .css( vertical ? "top" : "left", "auto" )
10685              .css({ position: "absolute" });
10686  
10687          animation[ ref2 ] = show ? margin : distance + margin;
10688      }
10689  
10690      // start at 0 if we are showing
10691      if ( show ) {
10692          wrapper.css( ref, 0 );
10693          if ( !motion ) {
10694              wrapper.css( ref2, margin + distance );
10695          }
10696      }
10697  
10698      // Animate
10699      wrapper.animate( animation, {
10700          duration: o.duration,
10701          easing: o.easing,
10702          queue: false,
10703          complete: function() {
10704              if ( mode === "hide" ) {
10705                  el.hide();
10706              }
10707              $.effects.restore( el, props );
10708              $.effects.removeWrapper( el );
10709              done();
10710          }
10711      });
10712  };
10713  
10714  
10715  /*!
10716   * jQuery UI Effects Bounce 1.11.4
10717   * http://jqueryui.com
10718   *
10719   * Copyright jQuery Foundation and other contributors
10720   * Released under the MIT license.
10721   * http://jquery.org/license
10722   *
10723   * http://api.jqueryui.com/bounce-effect/
10724   */
10725  
10726  
10727  var effectBounce = $.effects.effect.bounce = function( o, done ) {
10728      var el = $( this ),
10729          props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10730  
10731          // defaults:
10732          mode = $.effects.setMode( el, o.mode || "effect" ),
10733          hide = mode === "hide",
10734          show = mode === "show",
10735          direction = o.direction || "up",
10736          distance = o.distance,
10737          times = o.times || 5,
10738  
10739          // number of internal animations
10740          anims = times * 2 + ( show || hide ? 1 : 0 ),
10741          speed = o.duration / anims,
10742          easing = o.easing,
10743  
10744          // utility:
10745          ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10746          motion = ( direction === "up" || direction === "left" ),
10747          i,
10748          upAnim,
10749          downAnim,
10750  
10751          // we will need to re-assemble the queue to stack our animations in place
10752          queue = el.queue(),
10753          queuelen = queue.length;
10754  
10755      // Avoid touching opacity to prevent clearType and PNG issues in IE
10756      if ( show || hide ) {
10757          props.push( "opacity" );
10758      }
10759  
10760      $.effects.save( el, props );
10761      el.show();
10762      $.effects.createWrapper( el ); // Create Wrapper
10763  
10764      // default distance for the BIGGEST bounce is the outer Distance / 3
10765      if ( !distance ) {
10766          distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
10767      }
10768  
10769      if ( show ) {
10770          downAnim = { opacity: 1 };
10771          downAnim[ ref ] = 0;
10772  
10773          // if we are showing, force opacity 0 and set the initial position
10774          // then do the "first" animation
10775          el.css( "opacity", 0 )
10776              .css( ref, motion ? -distance * 2 : distance * 2 )
10777              .animate( downAnim, speed, easing );
10778      }
10779  
10780      // start at the smallest distance if we are hiding
10781      if ( hide ) {
10782          distance = distance / Math.pow( 2, times - 1 );
10783      }
10784  
10785      downAnim = {};
10786      downAnim[ ref ] = 0;
10787      // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
10788      for ( i = 0; i < times; i++ ) {
10789          upAnim = {};
10790          upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10791  
10792          el.animate( upAnim, speed, easing )
10793              .animate( downAnim, speed, easing );
10794  
10795          distance = hide ? distance * 2 : distance / 2;
10796      }
10797  
10798      // Last Bounce when Hiding
10799      if ( hide ) {
10800          upAnim = { opacity: 0 };
10801          upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10802  
10803          el.animate( upAnim, speed, easing );
10804      }
10805  
10806      el.queue(function() {
10807          if ( hide ) {
10808              el.hide();
10809          }
10810          $.effects.restore( el, props );
10811          $.effects.removeWrapper( el );
10812          done();
10813      });
10814  
10815      // inject all the animations we just queued to be first in line (after "inprogress")
10816      if ( queuelen > 1) {
10817          queue.splice.apply( queue,
10818              [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10819      }
10820      el.dequeue();
10821  
10822  };
10823  
10824  
10825  /*!
10826   * jQuery UI Effects Clip 1.11.4
10827   * http://jqueryui.com
10828   *
10829   * Copyright jQuery Foundation and other contributors
10830   * Released under the MIT license.
10831   * http://jquery.org/license
10832   *
10833   * http://api.jqueryui.com/clip-effect/
10834   */
10835  
10836  
10837  var effectClip = $.effects.effect.clip = function( o, done ) {
10838      // Create element
10839      var el = $( this ),
10840          props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10841          mode = $.effects.setMode( el, o.mode || "hide" ),
10842          show = mode === "show",
10843          direction = o.direction || "vertical",
10844          vert = direction === "vertical",
10845          size = vert ? "height" : "width",
10846          position = vert ? "top" : "left",
10847          animation = {},
10848          wrapper, animate, distance;
10849  
10850      // Save & Show
10851      $.effects.save( el, props );
10852      el.show();
10853  
10854      // Create Wrapper
10855      wrapper = $.effects.createWrapper( el ).css({
10856          overflow: "hidden"
10857      });
10858      animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
10859      distance = animate[ size ]();
10860  
10861      // Shift
10862      if ( show ) {
10863          animate.css( size, 0 );
10864          animate.css( position, distance / 2 );
10865      }
10866  
10867      // Create Animation Object:
10868      animation[ size ] = show ? distance : 0;
10869      animation[ position ] = show ? 0 : distance / 2;
10870  
10871      // Animate
10872      animate.animate( animation, {
10873          queue: false,
10874          duration: o.duration,
10875          easing: o.easing,
10876          complete: function() {
10877              if ( !show ) {
10878                  el.hide();
10879              }
10880              $.effects.restore( el, props );
10881              $.effects.removeWrapper( el );
10882              done();
10883          }
10884      });
10885  
10886  };
10887  
10888  
10889  /*!
10890   * jQuery UI Effects Drop 1.11.4
10891   * http://jqueryui.com
10892   *
10893   * Copyright jQuery Foundation and other contributors
10894   * Released under the MIT license.
10895   * http://jquery.org/license
10896   *
10897   * http://api.jqueryui.com/drop-effect/
10898   */
10899  
10900  
10901  var effectDrop = $.effects.effect.drop = function( o, done ) {
10902  
10903      var el = $( this ),
10904          props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
10905          mode = $.effects.setMode( el, o.mode || "hide" ),
10906          show = mode === "show",
10907          direction = o.direction || "left",
10908          ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10909          motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
10910          animation = {
10911              opacity: show ? 1 : 0
10912          },
10913          distance;
10914  
10915      // Adjust
10916      $.effects.save( el, props );
10917      el.show();
10918      $.effects.createWrapper( el );
10919  
10920      distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
10921  
10922      if ( show ) {
10923          el
10924              .css( "opacity", 0 )
10925              .css( ref, motion === "pos" ? -distance : distance );
10926      }
10927  
10928      // Animation
10929      animation[ ref ] = ( show ?
10930          ( motion === "pos" ? "+=" : "-=" ) :
10931          ( motion === "pos" ? "-=" : "+=" ) ) +
10932          distance;
10933  
10934      // Animate
10935      el.animate( animation, {
10936          queue: false,
10937          duration: o.duration,
10938          easing: o.easing,
10939          complete: function() {
10940              if ( mode === "hide" ) {
10941                  el.hide();
10942              }
10943              $.effects.restore( el, props );
10944              $.effects.removeWrapper( el );
10945              done();
10946          }
10947      });
10948  };
10949  
10950  
10951  /*!
10952   * jQuery UI Effects Explode 1.11.4
10953   * http://jqueryui.com
10954   *
10955   * Copyright jQuery Foundation and other contributors
10956   * Released under the MIT license.
10957   * http://jquery.org/license
10958   *
10959   * http://api.jqueryui.com/explode-effect/
10960   */
10961  
10962  
10963  var effectExplode = $.effects.effect.explode = function( o, done ) {
10964  
10965      var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
10966          cells = rows,
10967          el = $( this ),
10968          mode = $.effects.setMode( el, o.mode || "hide" ),
10969          show = mode === "show",
10970  
10971          // show and then visibility:hidden the element before calculating offset
10972          offset = el.show().css( "visibility", "hidden" ).offset(),
10973  
10974          // width and height of a piece
10975          width = Math.ceil( el.outerWidth() / cells ),
10976          height = Math.ceil( el.outerHeight() / rows ),
10977          pieces = [],
10978  
10979          // loop
10980          i, j, left, top, mx, my;
10981  
10982      // children animate complete:
10983  	function childComplete() {
10984          pieces.push( this );
10985          if ( pieces.length === rows * cells ) {
10986              animComplete();
10987          }
10988      }
10989  
10990      // clone the element for each row and cell.
10991      for ( i = 0; i < rows ; i++ ) { // ===>
10992          top = offset.top + i * height;
10993          my = i - ( rows - 1 ) / 2 ;
10994  
10995          for ( j = 0; j < cells ; j++ ) { // |||
10996              left = offset.left + j * width;
10997              mx = j - ( cells - 1 ) / 2 ;
10998  
10999              // Create a clone of the now hidden main element that will be absolute positioned
11000              // within a wrapper div off the -left and -top equal to size of our pieces
11001              el
11002                  .clone()
11003                  .appendTo( "body" )
11004                  .wrap( "<div></div>" )
11005                  .css({
11006                      position: "absolute",
11007                      visibility: "visible",
11008                      left: -j * width,
11009                      top: -i * height
11010                  })
11011  
11012              // select the wrapper - make it overflow: hidden and absolute positioned based on
11013              // where the original was located +left and +top equal to the size of pieces
11014                  .parent()
11015                  .addClass( "ui-effects-explode" )
11016                  .css({
11017                      position: "absolute",
11018                      overflow: "hidden",
11019                      width: width,
11020                      height: height,
11021                      left: left + ( show ? mx * width : 0 ),
11022                      top: top + ( show ? my * height : 0 ),
11023                      opacity: show ? 0 : 1
11024                  }).animate({
11025                      left: left + ( show ? 0 : mx * width ),
11026                      top: top + ( show ? 0 : my * height ),
11027                      opacity: show ? 1 : 0
11028                  }, o.duration || 500, o.easing, childComplete );
11029          }
11030      }
11031  
11032  	function animComplete() {
11033          el.css({
11034              visibility: "visible"
11035          });
11036          $( pieces ).remove();
11037          if ( !show ) {
11038              el.hide();
11039          }
11040          done();
11041      }
11042  };
11043  
11044  
11045  /*!
11046   * jQuery UI Effects Fade 1.11.4
11047   * http://jqueryui.com
11048   *
11049   * Copyright jQuery Foundation and other contributors
11050   * Released under the MIT license.
11051   * http://jquery.org/license
11052   *
11053   * http://api.jqueryui.com/fade-effect/
11054   */
11055  
11056  
11057  var effectFade = $.effects.effect.fade = function( o, done ) {
11058      var el = $( this ),
11059          mode = $.effects.setMode( el, o.mode || "toggle" );
11060  
11061      el.animate({
11062          opacity: mode
11063      }, {
11064          queue: false,
11065          duration: o.duration,
11066          easing: o.easing,
11067          complete: done
11068      });
11069  };
11070  
11071  
11072  /*!
11073   * jQuery UI Effects Fold 1.11.4
11074   * http://jqueryui.com
11075   *
11076   * Copyright jQuery Foundation and other contributors
11077   * Released under the MIT license.
11078   * http://jquery.org/license
11079   *
11080   * http://api.jqueryui.com/fold-effect/
11081   */
11082  
11083  
11084  var effectFold = $.effects.effect.fold = function( o, done ) {
11085  
11086      // Create element
11087      var el = $( this ),
11088          props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
11089          mode = $.effects.setMode( el, o.mode || "hide" ),
11090          show = mode === "show",
11091          hide = mode === "hide",
11092          size = o.size || 15,
11093          percent = /([0-9]+)%/.exec( size ),
11094          horizFirst = !!o.horizFirst,
11095          widthFirst = show !== horizFirst,
11096          ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
11097          duration = o.duration / 2,
11098          wrapper, distance,
11099          animation1 = {},
11100          animation2 = {};
11101  
11102      $.effects.save( el, props );
11103      el.show();
11104  
11105      // Create Wrapper
11106      wrapper = $.effects.createWrapper( el ).css({
11107          overflow: "hidden"
11108      });
11109      distance = widthFirst ?
11110          [ wrapper.width(), wrapper.height() ] :
11111          [ wrapper.height(), wrapper.width() ];
11112  
11113      if ( percent ) {
11114          size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
11115      }
11116      if ( show ) {
11117          wrapper.css( horizFirst ? {
11118              height: 0,
11119              width: size
11120          } : {
11121              height: size,
11122              width: 0
11123          });
11124      }
11125  
11126      // Animation
11127      animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
11128      animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
11129  
11130      // Animate
11131      wrapper
11132          .animate( animation1, duration, o.easing )
11133          .animate( animation2, duration, o.easing, function() {
11134              if ( hide ) {
11135                  el.hide();
11136              }
11137              $.effects.restore( el, props );
11138              $.effects.removeWrapper( el );
11139              done();
11140          });
11141  
11142  };
11143  
11144  
11145  /*!
11146   * jQuery UI Effects Highlight 1.11.4
11147   * http://jqueryui.com
11148   *
11149   * Copyright jQuery Foundation and other contributors
11150   * Released under the MIT license.
11151   * http://jquery.org/license
11152   *
11153   * http://api.jqueryui.com/highlight-effect/
11154   */
11155  
11156  
11157  var effectHighlight = $.effects.effect.highlight = function( o, done ) {
11158      var elem = $( this ),
11159          props = [ "backgroundImage", "backgroundColor", "opacity" ],
11160          mode = $.effects.setMode( elem, o.mode || "show" ),
11161          animation = {
11162              backgroundColor: elem.css( "backgroundColor" )
11163          };
11164  
11165      if (mode === "hide") {
11166          animation.opacity = 0;
11167      }
11168  
11169      $.effects.save( elem, props );
11170  
11171      elem
11172          .show()
11173          .css({
11174              backgroundImage: "none",
11175              backgroundColor: o.color || "#ffff99"
11176          })
11177          .animate( animation, {
11178              queue: false,
11179              duration: o.duration,
11180              easing: o.easing,
11181              complete: function() {
11182                  if ( mode === "hide" ) {
11183                      elem.hide();
11184                  }
11185                  $.effects.restore( elem, props );
11186                  done();
11187              }
11188          });
11189  };
11190  
11191  
11192  /*!
11193   * jQuery UI Effects Size 1.11.4
11194   * http://jqueryui.com
11195   *
11196   * Copyright jQuery Foundation and other contributors
11197   * Released under the MIT license.
11198   * http://jquery.org/license
11199   *
11200   * http://api.jqueryui.com/size-effect/
11201   */
11202  
11203  
11204  var effectSize = $.effects.effect.size = function( o, done ) {
11205  
11206      // Create element
11207      var original, baseline, factor,
11208          el = $( this ),
11209          props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
11210  
11211          // Always restore
11212          props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
11213  
11214          // Copy for children
11215          props2 = [ "width", "height", "overflow" ],
11216          cProps = [ "fontSize" ],
11217          vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
11218          hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
11219  
11220          // Set options
11221          mode = $.effects.setMode( el, o.mode || "effect" ),
11222          restore = o.restore || mode !== "effect",
11223          scale = o.scale || "both",
11224          origin = o.origin || [ "middle", "center" ],
11225          position = el.css( "position" ),
11226          props = restore ? props0 : props1,
11227          zero = {
11228              height: 0,
11229              width: 0,
11230              outerHeight: 0,
11231              outerWidth: 0
11232          };
11233  
11234      if ( mode === "show" ) {
11235          el.show();
11236      }
11237      original = {
11238          height: el.height(),
11239          width: el.width(),
11240          outerHeight: el.outerHeight(),
11241          outerWidth: el.outerWidth()
11242      };
11243  
11244      if ( o.mode === "toggle" && mode === "show" ) {
11245          el.from = o.to || zero;
11246          el.to = o.from || original;
11247      } else {
11248          el.from = o.from || ( mode === "show" ? zero : original );
11249          el.to = o.to || ( mode === "hide" ? zero : original );
11250      }
11251  
11252      // Set scaling factor
11253      factor = {
11254          from: {
11255              y: el.from.height / original.height,
11256              x: el.from.width / original.width
11257          },
11258          to: {
11259              y: el.to.height / original.height,
11260              x: el.to.width / original.width
11261          }
11262      };
11263  
11264      // Scale the css box
11265      if ( scale === "box" || scale === "both" ) {
11266  
11267          // Vertical props scaling
11268          if ( factor.from.y !== factor.to.y ) {
11269              props = props.concat( vProps );
11270              el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
11271              el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
11272          }
11273  
11274          // Horizontal props scaling
11275          if ( factor.from.x !== factor.to.x ) {
11276              props = props.concat( hProps );
11277              el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
11278              el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
11279          }
11280      }
11281  
11282      // Scale the content
11283      if ( scale === "content" || scale === "both" ) {
11284  
11285          // Vertical props scaling
11286          if ( factor.from.y !== factor.to.y ) {
11287              props = props.concat( cProps ).concat( props2 );
11288              el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
11289              el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
11290          }
11291      }
11292  
11293      $.effects.save( el, props );
11294      el.show();
11295      $.effects.createWrapper( el );
11296      el.css( "overflow", "hidden" ).css( el.from );
11297  
11298      // Adjust
11299      if (origin) { // Calculate baseline shifts
11300          baseline = $.effects.getBaseline( origin, original );
11301          el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
11302          el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
11303          el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
11304          el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
11305      }
11306      el.css( el.from ); // set top & left
11307  
11308      // Animate
11309      if ( scale === "content" || scale === "both" ) { // Scale the children
11310  
11311          // Add margins/font-size
11312          vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
11313          hProps = hProps.concat([ "marginLeft", "marginRight" ]);
11314          props2 = props0.concat(vProps).concat(hProps);
11315  
11316          el.find( "*[width]" ).each( function() {
11317              var child = $( this ),
11318                  c_original = {
11319                      height: child.height(),
11320                      width: child.width(),
11321                      outerHeight: child.outerHeight(),
11322                      outerWidth: child.outerWidth()
11323                  };
11324              if (restore) {
11325                  $.effects.save(child, props2);
11326              }
11327  
11328              child.from = {
11329                  height: c_original.height * factor.from.y,
11330                  width: c_original.width * factor.from.x,
11331                  outerHeight: c_original.outerHeight * factor.from.y,
11332                  outerWidth: c_original.outerWidth * factor.from.x
11333              };
11334              child.to = {
11335                  height: c_original.height * factor.to.y,
11336                  width: c_original.width * factor.to.x,
11337                  outerHeight: c_original.height * factor.to.y,
11338                  outerWidth: c_original.width * factor.to.x
11339              };
11340  
11341              // Vertical props scaling
11342              if ( factor.from.y !== factor.to.y ) {
11343                  child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
11344                  child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
11345              }
11346  
11347              // Horizontal props scaling
11348              if ( factor.from.x !== factor.to.x ) {
11349                  child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
11350                  child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
11351              }
11352  
11353              // Animate children
11354              child.css( child.from );
11355              child.animate( child.to, o.duration, o.easing, function() {
11356  
11357                  // Restore children
11358                  if ( restore ) {
11359                      $.effects.restore( child, props2 );
11360                  }
11361              });
11362          });
11363      }
11364  
11365      // Animate
11366      el.animate( el.to, {
11367          queue: false,
11368          duration: o.duration,
11369          easing: o.easing,
11370          complete: function() {
11371              if ( el.to.opacity === 0 ) {
11372                  el.css( "opacity", el.from.opacity );
11373              }
11374              if ( mode === "hide" ) {
11375                  el.hide();
11376              }
11377              $.effects.restore( el, props );
11378              if ( !restore ) {
11379  
11380                  // we need to calculate our new positioning based on the scaling
11381                  if ( position === "static" ) {
11382                      el.css({
11383                          position: "relative",
11384                          top: el.to.top,
11385                          left: el.to.left
11386                      });
11387                  } else {
11388                      $.each([ "top", "left" ], function( idx, pos ) {
11389                          el.css( pos, function( _, str ) {
11390                              var val = parseInt( str, 10 ),
11391                                  toRef = idx ? el.to.left : el.to.top;
11392  
11393                              // if original was "auto", recalculate the new value from wrapper
11394                              if ( str === "auto" ) {
11395                                  return toRef + "px";
11396                              }
11397  
11398                              return val + toRef + "px";
11399                          });
11400                      });
11401                  }
11402              }
11403  
11404              $.effects.removeWrapper( el );
11405              done();
11406          }
11407      });
11408  
11409  };
11410  
11411  
11412  /*!
11413   * jQuery UI Effects Scale 1.11.4
11414   * http://jqueryui.com
11415   *
11416   * Copyright jQuery Foundation and other contributors
11417   * Released under the MIT license.
11418   * http://jquery.org/license
11419   *
11420   * http://api.jqueryui.com/scale-effect/
11421   */
11422  
11423  
11424  var effectScale = $.effects.effect.scale = function( o, done ) {
11425  
11426      // Create element
11427      var el = $( this ),
11428          options = $.extend( true, {}, o ),
11429          mode = $.effects.setMode( el, o.mode || "effect" ),
11430          percent = parseInt( o.percent, 10 ) ||
11431              ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
11432          direction = o.direction || "both",
11433          origin = o.origin,
11434          original = {
11435              height: el.height(),
11436              width: el.width(),
11437              outerHeight: el.outerHeight(),
11438              outerWidth: el.outerWidth()
11439          },
11440          factor = {
11441              y: direction !== "horizontal" ? (percent / 100) : 1,
11442              x: direction !== "vertical" ? (percent / 100) : 1
11443          };
11444  
11445      // We are going to pass this effect to the size effect:
11446      options.effect = "size";
11447      options.queue = false;
11448      options.complete = done;
11449  
11450      // Set default origin and restore for show/hide
11451      if ( mode !== "effect" ) {
11452          options.origin = origin || [ "middle", "center" ];
11453          options.restore = true;
11454      }
11455  
11456      options.from = o.from || ( mode === "show" ? {
11457          height: 0,
11458          width: 0,
11459          outerHeight: 0,
11460          outerWidth: 0
11461      } : original );
11462      options.to = {
11463          height: original.height * factor.y,
11464          width: original.width * factor.x,
11465          outerHeight: original.outerHeight * factor.y,
11466          outerWidth: original.outerWidth * factor.x
11467      };
11468  
11469      // Fade option to support puff
11470      if ( options.fade ) {
11471          if ( mode === "show" ) {
11472              options.from.opacity = 0;
11473              options.to.opacity = 1;
11474          }
11475          if ( mode === "hide" ) {
11476              options.from.opacity = 1;
11477              options.to.opacity = 0;
11478          }
11479      }
11480  
11481      // Animate
11482      el.effect( options );
11483  
11484  };
11485  
11486  
11487  /*!
11488   * jQuery UI Effects Puff 1.11.4
11489   * http://jqueryui.com
11490   *
11491   * Copyright jQuery Foundation and other contributors
11492   * Released under the MIT license.
11493   * http://jquery.org/license
11494   *
11495   * http://api.jqueryui.com/puff-effect/
11496   */
11497  
11498  
11499  var effectPuff = $.effects.effect.puff = function( o, done ) {
11500      var elem = $( this ),
11501          mode = $.effects.setMode( elem, o.mode || "hide" ),
11502          hide = mode === "hide",
11503          percent = parseInt( o.percent, 10 ) || 150,
11504          factor = percent / 100,
11505          original = {
11506              height: elem.height(),
11507              width: elem.width(),
11508              outerHeight: elem.outerHeight(),
11509              outerWidth: elem.outerWidth()
11510          };
11511  
11512      $.extend( o, {
11513          effect: "scale",
11514          queue: false,
11515          fade: true,
11516          mode: mode,
11517          complete: done,
11518          percent: hide ? percent : 100,
11519          from: hide ?
11520              original :
11521              {
11522                  height: original.height * factor,
11523                  width: original.width * factor,
11524                  outerHeight: original.outerHeight * factor,
11525                  outerWidth: original.outerWidth * factor
11526              }
11527      });
11528  
11529      elem.effect( o );
11530  };
11531  
11532  
11533  /*!
11534   * jQuery UI Effects Pulsate 1.11.4
11535   * http://jqueryui.com
11536   *
11537   * Copyright jQuery Foundation and other contributors
11538   * Released under the MIT license.
11539   * http://jquery.org/license
11540   *
11541   * http://api.jqueryui.com/pulsate-effect/
11542   */
11543  
11544  
11545  var effectPulsate = $.effects.effect.pulsate = function( o, done ) {
11546      var elem = $( this ),
11547          mode = $.effects.setMode( elem, o.mode || "show" ),
11548          show = mode === "show",
11549          hide = mode === "hide",
11550          showhide = ( show || mode === "hide" ),
11551  
11552          // showing or hiding leaves of the "last" animation
11553          anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
11554          duration = o.duration / anims,
11555          animateTo = 0,
11556          queue = elem.queue(),
11557          queuelen = queue.length,
11558          i;
11559  
11560      if ( show || !elem.is(":visible")) {
11561          elem.css( "opacity", 0 ).show();
11562          animateTo = 1;
11563      }
11564  
11565      // anims - 1 opacity "toggles"
11566      for ( i = 1; i < anims; i++ ) {
11567          elem.animate({
11568              opacity: animateTo
11569          }, duration, o.easing );
11570          animateTo = 1 - animateTo;
11571      }
11572  
11573      elem.animate({
11574          opacity: animateTo
11575      }, duration, o.easing);
11576  
11577      elem.queue(function() {
11578          if ( hide ) {
11579              elem.hide();
11580          }
11581          done();
11582      });
11583  
11584      // We just queued up "anims" animations, we need to put them next in the queue
11585      if ( queuelen > 1 ) {
11586          queue.splice.apply( queue,
11587              [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11588      }
11589      elem.dequeue();
11590  };
11591  
11592  
11593  /*!
11594   * jQuery UI Effects Shake 1.11.4
11595   * http://jqueryui.com
11596   *
11597   * Copyright jQuery Foundation and other contributors
11598   * Released under the MIT license.
11599   * http://jquery.org/license
11600   *
11601   * http://api.jqueryui.com/shake-effect/
11602   */
11603  
11604  
11605  var effectShake = $.effects.effect.shake = function( o, done ) {
11606  
11607      var el = $( this ),
11608          props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
11609          mode = $.effects.setMode( el, o.mode || "effect" ),
11610          direction = o.direction || "left",
11611          distance = o.distance || 20,
11612          times = o.times || 3,
11613          anims = times * 2 + 1,
11614          speed = Math.round( o.duration / anims ),
11615          ref = (direction === "up" || direction === "down") ? "top" : "left",
11616          positiveMotion = (direction === "up" || direction === "left"),
11617          animation = {},
11618          animation1 = {},
11619          animation2 = {},
11620          i,
11621  
11622          // we will need to re-assemble the queue to stack our animations in place
11623          queue = el.queue(),
11624          queuelen = queue.length;
11625  
11626      $.effects.save( el, props );
11627      el.show();
11628      $.effects.createWrapper( el );
11629  
11630      // Animation
11631      animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
11632      animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
11633      animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
11634  
11635      // Animate
11636      el.animate( animation, speed, o.easing );
11637  
11638      // Shakes
11639      for ( i = 1; i < times; i++ ) {
11640          el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
11641      }
11642      el
11643          .animate( animation1, speed, o.easing )
11644          .animate( animation, speed / 2, o.easing )
11645          .queue(function() {
11646              if ( mode === "hide" ) {
11647                  el.hide();
11648              }
11649              $.effects.restore( el, props );
11650              $.effects.removeWrapper( el );
11651              done();
11652          });
11653  
11654      // inject all the animations we just queued to be first in line (after "inprogress")
11655      if ( queuelen > 1) {
11656          queue.splice.apply( queue,
11657              [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11658      }
11659      el.dequeue();
11660  
11661  };
11662  
11663  
11664  /*!
11665   * jQuery UI Effects Slide 1.11.4
11666   * http://jqueryui.com
11667   *
11668   * Copyright jQuery Foundation and other contributors
11669   * Released under the MIT license.
11670   * http://jquery.org/license
11671   *
11672   * http://api.jqueryui.com/slide-effect/
11673   */
11674  
11675  
11676  var effectSlide = $.effects.effect.slide = function( o, done ) {
11677  
11678      // Create element
11679      var el = $( this ),
11680          props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
11681          mode = $.effects.setMode( el, o.mode || "show" ),
11682          show = mode === "show",
11683          direction = o.direction || "left",
11684          ref = (direction === "up" || direction === "down") ? "top" : "left",
11685          positiveMotion = (direction === "up" || direction === "left"),
11686          distance,
11687          animation = {};
11688  
11689      // Adjust
11690      $.effects.save( el, props );
11691      el.show();
11692      distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
11693  
11694      $.effects.createWrapper( el ).css({
11695          overflow: "hidden"
11696      });
11697  
11698      if ( show ) {
11699          el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
11700      }
11701  
11702      // Animation
11703      animation[ ref ] = ( show ?
11704          ( positiveMotion ? "+=" : "-=") :
11705          ( positiveMotion ? "-=" : "+=")) +
11706          distance;
11707  
11708      // Animate
11709      el.animate( animation, {
11710          queue: false,
11711          duration: o.duration,
11712          easing: o.easing,
11713          complete: function() {
11714              if ( mode === "hide" ) {
11715                  el.hide();
11716              }
11717              $.effects.restore( el, props );
11718              $.effects.removeWrapper( el );
11719              done();
11720          }
11721      });
11722  };
11723  
11724  
11725  /*!
11726   * jQuery UI Effects Transfer 1.11.4
11727   * http://jqueryui.com
11728   *
11729   * Copyright jQuery Foundation and other contributors
11730   * Released under the MIT license.
11731   * http://jquery.org/license
11732   *
11733   * http://api.jqueryui.com/transfer-effect/
11734   */
11735  
11736  
11737  var effectTransfer = $.effects.effect.transfer = function( o, done ) {
11738      var elem = $( this ),
11739          target = $( o.to ),
11740          targetFixed = target.css( "position" ) === "fixed",
11741          body = $("body"),
11742          fixTop = targetFixed ? body.scrollTop() : 0,
11743          fixLeft = targetFixed ? body.scrollLeft() : 0,
11744          endPosition = target.offset(),
11745          animation = {
11746              top: endPosition.top - fixTop,
11747              left: endPosition.left - fixLeft,
11748              height: target.innerHeight(),
11749              width: target.innerWidth()
11750          },
11751          startPosition = elem.offset(),
11752          transfer = $( "<div class='ui-effects-transfer'></div>" )
11753              .appendTo( document.body )
11754              .addClass( o.className )
11755              .css({
11756                  top: startPosition.top - fixTop,
11757                  left: startPosition.left - fixLeft,
11758                  height: elem.innerHeight(),
11759                  width: elem.innerWidth(),
11760                  position: targetFixed ? "fixed" : "absolute"
11761              })
11762              .animate( animation, o.duration, o.easing, function() {
11763                  transfer.remove();
11764                  done();
11765              });
11766  };
11767  
11768  
11769  /*!
11770   * jQuery UI Progressbar 1.11.4
11771   * http://jqueryui.com
11772   *
11773   * Copyright jQuery Foundation and other contributors
11774   * Released under the MIT license.
11775   * http://jquery.org/license
11776   *
11777   * http://api.jqueryui.com/progressbar/
11778   */
11779  
11780  
11781  var progressbar = $.widget( "ui.progressbar", {
11782      version: "1.11.4",
11783      options: {
11784          max: 100,
11785          value: 0,
11786  
11787          change: null,
11788          complete: null
11789      },
11790  
11791      min: 0,
11792  
11793      _create: function() {
11794          // Constrain initial value
11795          this.oldValue = this.options.value = this._constrainedValue();
11796  
11797          this.element
11798              .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
11799              .attr({
11800                  // Only set static values, aria-valuenow and aria-valuemax are
11801                  // set inside _refreshValue()
11802                  role: "progressbar",
11803                  "aria-valuemin": this.min
11804              });
11805  
11806          this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
11807              .appendTo( this.element );
11808  
11809          this._refreshValue();
11810      },
11811  
11812      _destroy: function() {
11813          this.element
11814              .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
11815              .removeAttr( "role" )
11816              .removeAttr( "aria-valuemin" )
11817              .removeAttr( "aria-valuemax" )
11818              .removeAttr( "aria-valuenow" );
11819  
11820          this.valueDiv.remove();
11821      },
11822  
11823      value: function( newValue ) {
11824          if ( newValue === undefined ) {
11825              return this.options.value;
11826          }
11827  
11828          this.options.value = this._constrainedValue( newValue );
11829          this._refreshValue();
11830      },
11831  
11832      _constrainedValue: function( newValue ) {
11833          if ( newValue === undefined ) {
11834              newValue = this.options.value;
11835          }
11836  
11837          this.indeterminate = newValue === false;
11838  
11839          // sanitize value
11840          if ( typeof newValue !== "number" ) {
11841              newValue = 0;
11842          }
11843  
11844          return this.indeterminate ? false :
11845              Math.min( this.options.max, Math.max( this.min, newValue ) );
11846      },
11847  
11848      _setOptions: function( options ) {
11849          // Ensure "value" option is set after other values (like max)
11850          var value = options.value;
11851          delete options.value;
11852  
11853          this._super( options );
11854  
11855          this.options.value = this._constrainedValue( value );
11856          this._refreshValue();
11857      },
11858  
11859      _setOption: function( key, value ) {
11860          if ( key === "max" ) {
11861              // Don't allow a max less than min
11862              value = Math.max( this.min, value );
11863          }
11864          if ( key === "disabled" ) {
11865              this.element
11866                  .toggleClass( "ui-state-disabled", !!value )
11867                  .attr( "aria-disabled", value );
11868          }
11869          this._super( key, value );
11870      },
11871  
11872      _percentage: function() {
11873          return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
11874      },
11875  
11876      _refreshValue: function() {
11877          var value = this.options.value,
11878              percentage = this._percentage();
11879  
11880          this.valueDiv
11881              .toggle( this.indeterminate || value > this.min )
11882              .toggleClass( "ui-corner-right", value === this.options.max )
11883              .width( percentage.toFixed(0) + "%" );
11884  
11885          this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
11886  
11887          if ( this.indeterminate ) {
11888              this.element.removeAttr( "aria-valuenow" );
11889              if ( !this.overlayDiv ) {
11890                  this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
11891              }
11892          } else {
11893              this.element.attr({
11894                  "aria-valuemax": this.options.max,
11895                  "aria-valuenow": value
11896              });
11897              if ( this.overlayDiv ) {
11898                  this.overlayDiv.remove();
11899                  this.overlayDiv = null;
11900              }
11901          }
11902  
11903          if ( this.oldValue !== value ) {
11904              this.oldValue = value;
11905              this._trigger( "change" );
11906          }
11907          if ( value === this.options.max ) {
11908              this._trigger( "complete" );
11909          }
11910      }
11911  });
11912  
11913  
11914  /*!
11915   * jQuery UI Selectable 1.11.4
11916   * http://jqueryui.com
11917   *
11918   * Copyright jQuery Foundation and other contributors
11919   * Released under the MIT license.
11920   * http://jquery.org/license
11921   *
11922   * http://api.jqueryui.com/selectable/
11923   */
11924  
11925  
11926  var selectable = $.widget("ui.selectable", $.ui.mouse, {
11927      version: "1.11.4",
11928      options: {
11929          appendTo: "body",
11930          autoRefresh: true,
11931          distance: 0,
11932          filter: "*",
11933          tolerance: "touch",
11934  
11935          // callbacks
11936          selected: null,
11937          selecting: null,
11938          start: null,
11939          stop: null,
11940          unselected: null,
11941          unselecting: null
11942      },
11943      _create: function() {
11944          var selectees,
11945              that = this;
11946  
11947          this.element.addClass("ui-selectable");
11948  
11949          this.dragged = false;
11950  
11951          // cache selectee children based on filter
11952          this.refresh = function() {
11953              selectees = $(that.options.filter, that.element[0]);
11954              selectees.addClass("ui-selectee");
11955              selectees.each(function() {
11956                  var $this = $(this),
11957                      pos = $this.offset();
11958                  $.data(this, "selectable-item", {
11959                      element: this,
11960                      $element: $this,
11961                      left: pos.left,
11962                      top: pos.top,
11963                      right: pos.left + $this.outerWidth(),
11964                      bottom: pos.top + $this.outerHeight(),
11965                      startselected: false,
11966                      selected: $this.hasClass("ui-selected"),
11967                      selecting: $this.hasClass("ui-selecting"),
11968                      unselecting: $this.hasClass("ui-unselecting")
11969                  });
11970              });
11971          };
11972          this.refresh();
11973  
11974          this.selectees = selectees.addClass("ui-selectee");
11975  
11976          this._mouseInit();
11977  
11978          this.helper = $("<div class='ui-selectable-helper'></div>");
11979      },
11980  
11981      _destroy: function() {
11982          this.selectees
11983              .removeClass("ui-selectee")
11984              .removeData("selectable-item");
11985          this.element
11986              .removeClass("ui-selectable ui-selectable-disabled");
11987          this._mouseDestroy();
11988      },
11989  
11990      _mouseStart: function(event) {
11991          var that = this,
11992              options = this.options;
11993  
11994          this.opos = [ event.pageX, event.pageY ];
11995  
11996          if (this.options.disabled) {
11997              return;
11998          }
11999  
12000          this.selectees = $(options.filter, this.element[0]);
12001  
12002          this._trigger("start", event);
12003  
12004          $(options.appendTo).append(this.helper);
12005          // position helper (lasso)
12006          this.helper.css({
12007              "left": event.pageX,
12008              "top": event.pageY,
12009              "width": 0,
12010              "height": 0
12011          });
12012  
12013          if (options.autoRefresh) {
12014              this.refresh();
12015          }
12016  
12017          this.selectees.filter(".ui-selected").each(function() {
12018              var selectee = $.data(this, "selectable-item");
12019              selectee.startselected = true;
12020              if (!event.metaKey && !event.ctrlKey) {
12021                  selectee.$element.removeClass("ui-selected");
12022                  selectee.selected = false;
12023                  selectee.$element.addClass("ui-unselecting");
12024                  selectee.unselecting = true;
12025                  // selectable UNSELECTING callback
12026                  that._trigger("unselecting", event, {
12027                      unselecting: selectee.element
12028                  });
12029              }
12030          });
12031  
12032          $(event.target).parents().addBack().each(function() {
12033              var doSelect,
12034                  selectee = $.data(this, "selectable-item");
12035              if (selectee) {
12036                  doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
12037                  selectee.$element
12038                      .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
12039                      .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
12040                  selectee.unselecting = !doSelect;
12041                  selectee.selecting = doSelect;
12042                  selectee.selected = doSelect;
12043                  // selectable (UN)SELECTING callback
12044                  if (doSelect) {
12045                      that._trigger("selecting", event, {
12046                          selecting: selectee.element
12047                      });
12048                  } else {
12049                      that._trigger("unselecting", event, {
12050                          unselecting: selectee.element
12051                      });
12052                  }
12053                  return false;
12054              }
12055          });
12056  
12057      },
12058  
12059      _mouseDrag: function(event) {
12060  
12061          this.dragged = true;
12062  
12063          if (this.options.disabled) {
12064              return;
12065          }
12066  
12067          var tmp,
12068              that = this,
12069              options = this.options,
12070              x1 = this.opos[0],
12071              y1 = this.opos[1],
12072              x2 = event.pageX,
12073              y2 = event.pageY;
12074  
12075          if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
12076          if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
12077          this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
12078  
12079          this.selectees.each(function() {
12080              var selectee = $.data(this, "selectable-item"),
12081                  hit = false;
12082  
12083              //prevent helper from being selected if appendTo: selectable
12084              if (!selectee || selectee.element === that.element[0]) {
12085                  return;
12086              }
12087  
12088              if (options.tolerance === "touch") {
12089                  hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
12090              } else if (options.tolerance === "fit") {
12091                  hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
12092              }
12093  
12094              if (hit) {
12095                  // SELECT
12096                  if (selectee.selected) {
12097                      selectee.$element.removeClass("ui-selected");
12098                      selectee.selected = false;
12099                  }
12100                  if (selectee.unselecting) {
12101                      selectee.$element.removeClass("ui-unselecting");
12102                      selectee.unselecting = false;
12103                  }
12104                  if (!selectee.selecting) {
12105                      selectee.$element.addClass("ui-selecting");
12106                      selectee.selecting = true;
12107                      // selectable SELECTING callback
12108                      that._trigger("selecting", event, {
12109                          selecting: selectee.element
12110                      });
12111                  }
12112              } else {
12113                  // UNSELECT
12114                  if (selectee.selecting) {
12115                      if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
12116                          selectee.$element.removeClass("ui-selecting");
12117                          selectee.selecting = false;
12118                          selectee.$element.addClass("ui-selected");
12119                          selectee.selected = true;
12120                      } else {
12121                          selectee.$element.removeClass("ui-selecting");
12122                          selectee.selecting = false;
12123                          if (selectee.startselected) {
12124                              selectee.$element.addClass("ui-unselecting");
12125                              selectee.unselecting = true;
12126                          }
12127                          // selectable UNSELECTING callback
12128                          that._trigger("unselecting", event, {
12129                              unselecting: selectee.element
12130                          });
12131                      }
12132                  }
12133                  if (selectee.selected) {
12134                      if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
12135                          selectee.$element.removeClass("ui-selected");
12136                          selectee.selected = false;
12137  
12138                          selectee.$element.addClass("ui-unselecting");
12139                          selectee.unselecting = true;
12140                          // selectable UNSELECTING callback
12141                          that._trigger("unselecting", event, {
12142                              unselecting: selectee.element
12143                          });
12144                      }
12145                  }
12146              }
12147          });
12148  
12149          return false;
12150      },
12151  
12152      _mouseStop: function(event) {
12153          var that = this;
12154  
12155          this.dragged = false;
12156  
12157          $(".ui-unselecting", this.element[0]).each(function() {
12158              var selectee = $.data(this, "selectable-item");
12159              selectee.$element.removeClass("ui-unselecting");
12160              selectee.unselecting = false;
12161              selectee.startselected = false;
12162              that._trigger("unselected", event, {
12163                  unselected: selectee.element
12164              });
12165          });
12166          $(".ui-selecting", this.element[0]).each(function() {
12167              var selectee = $.data(this, "selectable-item");
12168              selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
12169              selectee.selecting = false;
12170              selectee.selected = true;
12171              selectee.startselected = true;
12172              that._trigger("selected", event, {
12173                  selected: selectee.element
12174              });
12175          });
12176          this._trigger("stop", event);
12177  
12178          this.helper.remove();
12179  
12180          return false;
12181      }
12182  
12183  });
12184  
12185  
12186  /*!
12187   * jQuery UI Selectmenu 1.11.4
12188   * http://jqueryui.com
12189   *
12190   * Copyright jQuery Foundation and other contributors
12191   * Released under the MIT license.
12192   * http://jquery.org/license
12193   *
12194   * http://api.jqueryui.com/selectmenu
12195   */
12196  
12197  
12198  var selectmenu = $.widget( "ui.selectmenu", {
12199      version: "1.11.4",
12200      defaultElement: "<select>",
12201      options: {
12202          appendTo: null,
12203          disabled: null,
12204          icons: {
12205              button: "ui-icon-triangle-1-s"
12206          },
12207          position: {
12208              my: "left top",
12209              at: "left bottom",
12210              collision: "none"
12211          },
12212          width: null,
12213  
12214          // callbacks
12215          change: null,
12216          close: null,
12217          focus: null,
12218          open: null,
12219          select: null
12220      },
12221  
12222      _create: function() {
12223          var selectmenuId = this.element.uniqueId().attr( "id" );
12224          this.ids = {
12225              element: selectmenuId,
12226              button: selectmenuId + "-button",
12227              menu: selectmenuId + "-menu"
12228          };
12229  
12230          this._drawButton();
12231          this._drawMenu();
12232  
12233          if ( this.options.disabled ) {
12234              this.disable();
12235          }
12236      },
12237  
12238      _drawButton: function() {
12239          var that = this;
12240  
12241          // Associate existing label with the new button
12242          this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button );
12243          this._on( this.label, {
12244              click: function( event ) {
12245                  this.button.focus();
12246                  event.preventDefault();
12247              }
12248          });
12249  
12250          // Hide original select element
12251          this.element.hide();
12252  
12253          // Create button
12254          this.button = $( "<span>", {
12255              "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
12256              tabindex: this.options.disabled ? -1 : 0,
12257              id: this.ids.button,
12258              role: "combobox",
12259              "aria-expanded": "false",
12260              "aria-autocomplete": "list",
12261              "aria-owns": this.ids.menu,
12262              "aria-haspopup": "true"
12263          })
12264              .insertAfter( this.element );
12265  
12266          $( "<span>", {
12267              "class": "ui-icon " + this.options.icons.button
12268          })
12269              .prependTo( this.button );
12270  
12271          this.buttonText = $( "<span>", {
12272              "class": "ui-selectmenu-text"
12273          })
12274              .appendTo( this.button );
12275  
12276          this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
12277          this._resizeButton();
12278  
12279          this._on( this.button, this._buttonEvents );
12280          this.button.one( "focusin", function() {
12281  
12282              // Delay rendering the menu items until the button receives focus.
12283              // The menu may have already been rendered via a programmatic open.
12284              if ( !that.menuItems ) {
12285                  that._refreshMenu();
12286              }
12287          });
12288          this._hoverable( this.button );
12289          this._focusable( this.button );
12290      },
12291  
12292      _drawMenu: function() {
12293          var that = this;
12294  
12295          // Create menu
12296          this.menu = $( "<ul>", {
12297              "aria-hidden": "true",
12298              "aria-labelledby": this.ids.button,
12299              id: this.ids.menu
12300          });
12301  
12302          // Wrap menu
12303          this.menuWrap = $( "<div>", {
12304              "class": "ui-selectmenu-menu ui-front"
12305          })
12306              .append( this.menu )
12307              .appendTo( this._appendTo() );
12308  
12309          // Initialize menu widget
12310          this.menuInstance = this.menu
12311              .menu({
12312                  role: "listbox",
12313                  select: function( event, ui ) {
12314                      event.preventDefault();
12315  
12316                      // support: IE8
12317                      // If the item was selected via a click, the text selection
12318                      // will be destroyed in IE
12319                      that._setSelection();
12320  
12321                      that._select( ui.item.data( "ui-selectmenu-item" ), event );
12322                  },
12323                  focus: function( event, ui ) {
12324                      var item = ui.item.data( "ui-selectmenu-item" );
12325  
12326                      // Prevent inital focus from firing and check if its a newly focused item
12327                      if ( that.focusIndex != null && item.index !== that.focusIndex ) {
12328                          that._trigger( "focus", event, { item: item } );
12329                          if ( !that.isOpen ) {
12330                              that._select( item, event );
12331                          }
12332                      }
12333                      that.focusIndex = item.index;
12334  
12335                      that.button.attr( "aria-activedescendant",
12336                          that.menuItems.eq( item.index ).attr( "id" ) );
12337                  }
12338              })
12339              .menu( "instance" );
12340  
12341          // Adjust menu styles to dropdown
12342          this.menu
12343              .addClass( "ui-corner-bottom" )
12344              .removeClass( "ui-corner-all" );
12345  
12346          // Don't close the menu on mouseleave
12347          this.menuInstance._off( this.menu, "mouseleave" );
12348  
12349          // Cancel the menu's collapseAll on document click
12350          this.menuInstance._closeOnDocumentClick = function() {
12351              return false;
12352          };
12353  
12354          // Selects often contain empty items, but never contain dividers
12355          this.menuInstance._isDivider = function() {
12356              return false;
12357          };
12358      },
12359  
12360      refresh: function() {
12361          this._refreshMenu();
12362          this._setText( this.buttonText, this._getSelectedItem().text() );
12363          if ( !this.options.width ) {
12364              this._resizeButton();
12365          }
12366      },
12367  
12368      _refreshMenu: function() {
12369          this.menu.empty();
12370  
12371          var item,
12372              options = this.element.find( "option" );
12373  
12374          if ( !options.length ) {
12375              return;
12376          }
12377  
12378          this._parseOptions( options );
12379          this._renderMenu( this.menu, this.items );
12380  
12381          this.menuInstance.refresh();
12382          this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );
12383  
12384          item = this._getSelectedItem();
12385  
12386          // Update the menu to have the correct item focused
12387          this.menuInstance.focus( null, item );
12388          this._setAria( item.data( "ui-selectmenu-item" ) );
12389  
12390          // Set disabled state
12391          this._setOption( "disabled", this.element.prop( "disabled" ) );
12392      },
12393  
12394      open: function( event ) {
12395          if ( this.options.disabled ) {
12396              return;
12397          }
12398  
12399          // If this is the first time the menu is being opened, render the items
12400          if ( !this.menuItems ) {
12401              this._refreshMenu();
12402          } else {
12403  
12404              // Menu clears focus on close, reset focus to selected item
12405              this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
12406              this.menuInstance.focus( null, this._getSelectedItem() );
12407          }
12408  
12409          this.isOpen = true;
12410          this._toggleAttr();
12411          this._resizeMenu();
12412          this._position();
12413  
12414          this._on( this.document, this._documentClick );
12415  
12416          this._trigger( "open", event );
12417      },
12418  
12419      _position: function() {
12420          this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
12421      },
12422  
12423      close: function( event ) {
12424          if ( !this.isOpen ) {
12425              return;
12426          }
12427  
12428          this.isOpen = false;
12429          this._toggleAttr();
12430  
12431          this.range = null;
12432          this._off( this.document );
12433  
12434          this._trigger( "close", event );
12435      },
12436  
12437      widget: function() {
12438          return this.button;
12439      },
12440  
12441      menuWidget: function() {
12442          return this.menu;
12443      },
12444  
12445      _renderMenu: function( ul, items ) {
12446          var that = this,
12447              currentOptgroup = "";
12448  
12449          $.each( items, function( index, item ) {
12450              if ( item.optgroup !== currentOptgroup ) {
12451                  $( "<li>", {
12452                      "class": "ui-selectmenu-optgroup ui-menu-divider" +
12453                          ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
12454                              " ui-state-disabled" :
12455                              "" ),
12456                      text: item.optgroup
12457                  })
12458                      .appendTo( ul );
12459  
12460                  currentOptgroup = item.optgroup;
12461              }
12462  
12463              that._renderItemData( ul, item );
12464          });
12465      },
12466  
12467      _renderItemData: function( ul, item ) {
12468          return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
12469      },
12470  
12471      _renderItem: function( ul, item ) {
12472          var li = $( "<li>" );
12473  
12474          if ( item.disabled ) {
12475              li.addClass( "ui-state-disabled" );
12476          }
12477          this._setText( li, item.label );
12478  
12479          return li.appendTo( ul );
12480      },
12481  
12482      _setText: function( element, value ) {
12483          if ( value ) {
12484              element.text( value );
12485          } else {
12486              element.html( "&#160;" );
12487          }
12488      },
12489  
12490      _move: function( direction, event ) {
12491          var item, next,
12492              filter = ".ui-menu-item";
12493  
12494          if ( this.isOpen ) {
12495              item = this.menuItems.eq( this.focusIndex );
12496          } else {
12497              item = this.menuItems.eq( this.element[ 0 ].selectedIndex );
12498              filter += ":not(.ui-state-disabled)";
12499          }
12500  
12501          if ( direction === "first" || direction === "last" ) {
12502              next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
12503          } else {
12504              next = item[ direction + "All" ]( filter ).eq( 0 );
12505          }
12506  
12507          if ( next.length ) {
12508              this.menuInstance.focus( event, next );
12509          }
12510      },
12511  
12512      _getSelectedItem: function() {
12513          return this.menuItems.eq( this.element[ 0 ].selectedIndex );
12514      },
12515  
12516      _toggle: function( event ) {
12517          this[ this.isOpen ? "close" : "open" ]( event );
12518      },
12519  
12520      _setSelection: function() {
12521          var selection;
12522  
12523          if ( !this.range ) {
12524              return;
12525          }
12526  
12527          if ( window.getSelection ) {
12528              selection = window.getSelection();
12529              selection.removeAllRanges();
12530              selection.addRange( this.range );
12531  
12532          // support: IE8
12533          } else {
12534              this.range.select();
12535          }
12536  
12537          // support: IE
12538          // Setting the text selection kills the button focus in IE, but
12539          // restoring the focus doesn't kill the selection.
12540          this.button.focus();
12541      },
12542  
12543      _documentClick: {
12544          mousedown: function( event ) {
12545              if ( !this.isOpen ) {
12546                  return;
12547              }
12548  
12549              if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) {
12550                  this.close( event );
12551              }
12552          }
12553      },
12554  
12555      _buttonEvents: {
12556  
12557          // Prevent text selection from being reset when interacting with the selectmenu (#10144)
12558          mousedown: function() {
12559              var selection;
12560  
12561              if ( window.getSelection ) {
12562                  selection = window.getSelection();
12563                  if ( selection.rangeCount ) {
12564                      this.range = selection.getRangeAt( 0 );
12565                  }
12566  
12567              // support: IE8
12568              } else {
12569                  this.range = document.selection.createRange();
12570              }
12571          },
12572  
12573          click: function( event ) {
12574              this._setSelection();
12575              this._toggle( event );
12576          },
12577  
12578          keydown: function( event ) {
12579              var preventDefault = true;
12580              switch ( event.keyCode ) {
12581                  case $.ui.keyCode.TAB:
12582                  case $.ui.keyCode.ESCAPE:
12583                      this.close( event );
12584                      preventDefault = false;
12585                      break;
12586                  case $.ui.keyCode.ENTER:
12587                      if ( this.isOpen ) {
12588                          this._selectFocusedItem( event );
12589                      }
12590                      break;
12591                  case $.ui.keyCode.UP:
12592                      if ( event.altKey ) {
12593                          this._toggle( event );
12594                      } else {
12595                          this._move( "prev", event );
12596                      }
12597                      break;
12598                  case $.ui.keyCode.DOWN:
12599                      if ( event.altKey ) {
12600                          this._toggle( event );
12601                      } else {
12602                          this._move( "next", event );
12603                      }
12604                      break;
12605                  case $.ui.keyCode.SPACE:
12606                      if ( this.isOpen ) {
12607                          this._selectFocusedItem( event );
12608                      } else {
12609                          this._toggle( event );
12610                      }
12611                      break;
12612                  case $.ui.keyCode.LEFT:
12613                      this._move( "prev", event );
12614                      break;
12615                  case $.ui.keyCode.RIGHT:
12616                      this._move( "next", event );
12617                      break;
12618                  case $.ui.keyCode.HOME:
12619                  case $.ui.keyCode.PAGE_UP:
12620                      this._move( "first", event );
12621                      break;
12622                  case $.ui.keyCode.END:
12623                  case $.ui.keyCode.PAGE_DOWN:
12624                      this._move( "last", event );
12625                      break;
12626                  default:
12627                      this.menu.trigger( event );
12628                      preventDefault = false;
12629              }
12630  
12631              if ( preventDefault ) {
12632                  event.preventDefault();
12633              }
12634          }
12635      },
12636  
12637      _selectFocusedItem: function( event ) {
12638          var item = this.menuItems.eq( this.focusIndex );
12639          if ( !item.hasClass( "ui-state-disabled" ) ) {
12640              this._select( item.data( "ui-selectmenu-item" ), event );
12641          }
12642      },
12643  
12644      _select: function( item, event ) {
12645          var oldIndex = this.element[ 0 ].selectedIndex;
12646  
12647          // Change native select element
12648          this.element[ 0 ].selectedIndex = item.index;
12649          this._setText( this.buttonText, item.label );
12650          this._setAria( item );
12651          this._trigger( "select", event, { item: item } );
12652  
12653          if ( item.index !== oldIndex ) {
12654              this._trigger( "change", event, { item: item } );
12655          }
12656  
12657          this.close( event );
12658      },
12659  
12660      _setAria: function( item ) {
12661          var id = this.menuItems.eq( item.index ).attr( "id" );
12662  
12663          this.button.attr({
12664              "aria-labelledby": id,
12665              "aria-activedescendant": id
12666          });
12667          this.menu.attr( "aria-activedescendant", id );
12668      },
12669  
12670      _setOption: function( key, value ) {
12671          if ( key === "icons" ) {
12672              this.button.find( "span.ui-icon" )
12673                  .removeClass( this.options.icons.button )
12674                  .addClass( value.button );
12675          }
12676  
12677          this._super( key, value );
12678  
12679          if ( key === "appendTo" ) {
12680              this.menuWrap.appendTo( this._appendTo() );
12681          }
12682  
12683          if ( key === "disabled" ) {
12684              this.menuInstance.option( "disabled", value );
12685              this.button
12686                  .toggleClass( "ui-state-disabled", value )
12687                  .attr( "aria-disabled", value );
12688  
12689              this.element.prop( "disabled", value );
12690              if ( value ) {
12691                  this.button.attr( "tabindex", -1 );
12692                  this.close();
12693              } else {
12694                  this.button.attr( "tabindex", 0 );
12695              }
12696          }
12697  
12698          if ( key === "width" ) {
12699              this._resizeButton();
12700          }
12701      },
12702  
12703      _appendTo: function() {
12704          var element = this.options.appendTo;
12705  
12706          if ( element ) {
12707              element = element.jquery || element.nodeType ?
12708                  $( element ) :
12709                  this.document.find( element ).eq( 0 );
12710          }
12711  
12712          if ( !element || !element[ 0 ] ) {
12713              element = this.element.closest( ".ui-front" );
12714          }
12715  
12716          if ( !element.length ) {
12717              element = this.document[ 0 ].body;
12718          }
12719  
12720          return element;
12721      },
12722  
12723      _toggleAttr: function() {
12724          this.button
12725              .toggleClass( "ui-corner-top", this.isOpen )
12726              .toggleClass( "ui-corner-all", !this.isOpen )
12727              .attr( "aria-expanded", this.isOpen );
12728          this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
12729          this.menu.attr( "aria-hidden", !this.isOpen );
12730      },
12731  
12732      _resizeButton: function() {
12733          var width = this.options.width;
12734  
12735          if ( !width ) {
12736              width = this.element.show().outerWidth();
12737              this.element.hide();
12738          }
12739  
12740          this.button.outerWidth( width );
12741      },
12742  
12743      _resizeMenu: function() {
12744          this.menu.outerWidth( Math.max(
12745              this.button.outerWidth(),
12746  
12747              // support: IE10
12748              // IE10 wraps long text (possibly a rounding bug)
12749              // so we add 1px to avoid the wrapping
12750              this.menu.width( "" ).outerWidth() + 1
12751          ) );
12752      },
12753  
12754      _getCreateOptions: function() {
12755          return { disabled: this.element.prop( "disabled" ) };
12756      },
12757  
12758      _parseOptions: function( options ) {
12759          var data = [];
12760          options.each(function( index, item ) {
12761              var option = $( item ),
12762                  optgroup = option.parent( "optgroup" );
12763              data.push({
12764                  element: option,
12765                  index: index,
12766                  value: option.val(),
12767                  label: option.text(),
12768                  optgroup: optgroup.attr( "label" ) || "",
12769                  disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
12770              });
12771          });
12772          this.items = data;
12773      },
12774  
12775      _destroy: function() {
12776          this.menuWrap.remove();
12777          this.button.remove();
12778          this.element.show();
12779          this.element.removeUniqueId();
12780          this.label.attr( "for", this.ids.element );
12781      }
12782  });
12783  
12784  
12785  /*!
12786   * jQuery UI Slider 1.11.4
12787   * http://jqueryui.com
12788   *
12789   * Copyright jQuery Foundation and other contributors
12790   * Released under the MIT license.
12791   * http://jquery.org/license
12792   *
12793   * http://api.jqueryui.com/slider/
12794   */
12795  
12796  
12797  var slider = $.widget( "ui.slider", $.ui.mouse, {
12798      version: "1.11.4",
12799      widgetEventPrefix: "slide",
12800  
12801      options: {
12802          animate: false,
12803          distance: 0,
12804          max: 100,
12805          min: 0,
12806          orientation: "horizontal",
12807          range: false,
12808          step: 1,
12809          value: 0,
12810          values: null,
12811  
12812          // callbacks
12813          change: null,
12814          slide: null,
12815          start: null,
12816          stop: null
12817      },
12818  
12819      // number of pages in a slider
12820      // (how many times can you page up/down to go through the whole range)
12821      numPages: 5,
12822  
12823      _create: function() {
12824          this._keySliding = false;
12825          this._mouseSliding = false;
12826          this._animateOff = true;
12827          this._handleIndex = null;
12828          this._detectOrientation();
12829          this._mouseInit();
12830          this._calculateNewMax();
12831  
12832          this.element
12833              .addClass( "ui-slider" +
12834                  " ui-slider-" + this.orientation +
12835                  " ui-widget" +
12836                  " ui-widget-content" +
12837                  " ui-corner-all");
12838  
12839          this._refresh();
12840          this._setOption( "disabled", this.options.disabled );
12841  
12842          this._animateOff = false;
12843      },
12844  
12845      _refresh: function() {
12846          this._createRange();
12847          this._createHandles();
12848          this._setupEvents();
12849          this._refreshValue();
12850      },
12851  
12852      _createHandles: function() {
12853          var i, handleCount,
12854              options = this.options,
12855              existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
12856              handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",
12857              handles = [];
12858  
12859          handleCount = ( options.values && options.values.length ) || 1;
12860  
12861          if ( existingHandles.length > handleCount ) {
12862              existingHandles.slice( handleCount ).remove();
12863              existingHandles = existingHandles.slice( 0, handleCount );
12864          }
12865  
12866          for ( i = existingHandles.length; i < handleCount; i++ ) {
12867              handles.push( handle );
12868          }
12869  
12870          this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
12871  
12872          this.handle = this.handles.eq( 0 );
12873  
12874          this.handles.each(function( i ) {
12875              $( this ).data( "ui-slider-handle-index", i );
12876          });
12877      },
12878  
12879      _createRange: function() {
12880          var options = this.options,
12881              classes = "";
12882  
12883          if ( options.range ) {
12884              if ( options.range === true ) {
12885                  if ( !options.values ) {
12886                      options.values = [ this._valueMin(), this._valueMin() ];
12887                  } else if ( options.values.length && options.values.length !== 2 ) {
12888                      options.values = [ options.values[0], options.values[0] ];
12889                  } else if ( $.isArray( options.values ) ) {
12890                      options.values = options.values.slice(0);
12891                  }
12892              }
12893  
12894              if ( !this.range || !this.range.length ) {
12895                  this.range = $( "<div></div>" )
12896                      .appendTo( this.element );
12897  
12898                  classes = "ui-slider-range" +
12899                  // note: this isn't the most fittingly semantic framework class for this element,
12900                  // but worked best visually with a variety of themes
12901                  " ui-widget-header ui-corner-all";
12902              } else {
12903                  this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
12904                      // Handle range switching from true to min/max
12905                      .css({
12906                          "left": "",
12907                          "bottom": ""
12908                      });
12909              }
12910  
12911              this.range.addClass( classes +
12912                  ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
12913          } else {
12914              if ( this.range ) {
12915                  this.range.remove();
12916              }
12917              this.range = null;
12918          }
12919      },
12920  
12921      _setupEvents: function() {
12922          this._off( this.handles );
12923          this._on( this.handles, this._handleEvents );
12924          this._hoverable( this.handles );
12925          this._focusable( this.handles );
12926      },
12927  
12928      _destroy: function() {
12929          this.handles.remove();
12930          if ( this.range ) {
12931              this.range.remove();
12932          }
12933  
12934          this.element
12935              .removeClass( "ui-slider" +
12936                  " ui-slider-horizontal" +
12937                  " ui-slider-vertical" +
12938                  " ui-widget" +
12939                  " ui-widget-content" +
12940                  " ui-corner-all" );
12941  
12942          this._mouseDestroy();
12943      },
12944  
12945      _mouseCapture: function( event ) {
12946          var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
12947              that = this,
12948              o = this.options;
12949  
12950          if ( o.disabled ) {
12951              return false;
12952          }
12953  
12954          this.elementSize = {
12955              width: this.element.outerWidth(),
12956              height: this.element.outerHeight()
12957          };
12958          this.elementOffset = this.element.offset();
12959  
12960          position = { x: event.pageX, y: event.pageY };
12961          normValue = this._normValueFromMouse( position );
12962          distance = this._valueMax() - this._valueMin() + 1;
12963          this.handles.each(function( i ) {
12964              var thisDistance = Math.abs( normValue - that.values(i) );
12965              if (( distance > thisDistance ) ||
12966                  ( distance === thisDistance &&
12967                      (i === that._lastChangedValue || that.values(i) === o.min ))) {
12968                  distance = thisDistance;
12969                  closestHandle = $( this );
12970                  index = i;
12971              }
12972          });
12973  
12974          allowed = this._start( event, index );
12975          if ( allowed === false ) {
12976              return false;
12977          }
12978          this._mouseSliding = true;
12979  
12980          this._handleIndex = index;
12981  
12982          closestHandle
12983              .addClass( "ui-state-active" )
12984              .focus();
12985  
12986          offset = closestHandle.offset();
12987          mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
12988          this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
12989              left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
12990              top: event.pageY - offset.top -
12991                  ( closestHandle.height() / 2 ) -
12992                  ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
12993                  ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
12994                  ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
12995          };
12996  
12997          if ( !this.handles.hasClass( "ui-state-hover" ) ) {
12998              this._slide( event, index, normValue );
12999          }
13000          this._animateOff = true;
13001          return true;
13002      },
13003  
13004      _mouseStart: function() {
13005          return true;
13006      },
13007  
13008      _mouseDrag: function( event ) {
13009          var position = { x: event.pageX, y: event.pageY },
13010              normValue = this._normValueFromMouse( position );
13011  
13012          this._slide( event, this._handleIndex, normValue );
13013  
13014          return false;
13015      },
13016  
13017      _mouseStop: function( event ) {
13018          this.handles.removeClass( "ui-state-active" );
13019          this._mouseSliding = false;
13020  
13021          this._stop( event, this._handleIndex );
13022          this._change( event, this._handleIndex );
13023  
13024          this._handleIndex = null;
13025          this._clickOffset = null;
13026          this._animateOff = false;
13027  
13028          return false;
13029      },
13030  
13031      _detectOrientation: function() {
13032          this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
13033      },
13034  
13035      _normValueFromMouse: function( position ) {
13036          var pixelTotal,
13037              pixelMouse,
13038              percentMouse,
13039              valueTotal,
13040              valueMouse;
13041  
13042          if ( this.orientation === "horizontal" ) {
13043              pixelTotal = this.elementSize.width;
13044              pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
13045          } else {
13046              pixelTotal = this.elementSize.height;
13047              pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
13048          }
13049  
13050          percentMouse = ( pixelMouse / pixelTotal );
13051          if ( percentMouse > 1 ) {
13052              percentMouse = 1;
13053          }
13054          if ( percentMouse < 0 ) {
13055              percentMouse = 0;
13056          }
13057          if ( this.orientation === "vertical" ) {
13058              percentMouse = 1 - percentMouse;
13059          }
13060  
13061          valueTotal = this._valueMax() - this._valueMin();
13062          valueMouse = this._valueMin() + percentMouse * valueTotal;
13063  
13064          return this._trimAlignValue( valueMouse );
13065      },
13066  
13067      _start: function( event, index ) {
13068          var uiHash = {
13069              handle: this.handles[ index ],
13070              value: this.value()
13071          };
13072          if ( this.options.values && this.options.values.length ) {
13073              uiHash.value = this.values( index );
13074              uiHash.values = this.values();
13075          }
13076          return this._trigger( "start", event, uiHash );
13077      },
13078  
13079      _slide: function( event, index, newVal ) {
13080          var otherVal,
13081              newValues,
13082              allowed;
13083  
13084          if ( this.options.values && this.options.values.length ) {
13085              otherVal = this.values( index ? 0 : 1 );
13086  
13087              if ( ( this.options.values.length === 2 && this.options.range === true ) &&
13088                      ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
13089                  ) {
13090                  newVal = otherVal;
13091              }
13092  
13093              if ( newVal !== this.values( index ) ) {
13094                  newValues = this.values();
13095                  newValues[ index ] = newVal;
13096                  // A slide can be canceled by returning false from the slide callback
13097                  allowed = this._trigger( "slide", event, {
13098                      handle: this.handles[ index ],
13099                      value: newVal,
13100                      values: newValues
13101                  } );
13102                  otherVal = this.values( index ? 0 : 1 );
13103                  if ( allowed !== false ) {
13104                      this.values( index, newVal );
13105                  }
13106              }
13107          } else {
13108              if ( newVal !== this.value() ) {
13109                  // A slide can be canceled by returning false from the slide callback
13110                  allowed = this._trigger( "slide", event, {
13111                      handle: this.handles[ index ],
13112                      value: newVal
13113                  } );
13114                  if ( allowed !== false ) {
13115                      this.value( newVal );
13116                  }
13117              }
13118          }
13119      },
13120  
13121      _stop: function( event, index ) {
13122          var uiHash = {
13123              handle: this.handles[ index ],
13124              value: this.value()
13125          };
13126          if ( this.options.values && this.options.values.length ) {
13127              uiHash.value = this.values( index );
13128              uiHash.values = this.values();
13129          }
13130  
13131          this._trigger( "stop", event, uiHash );
13132      },
13133  
13134      _change: function( event, index ) {
13135          if ( !this._keySliding && !this._mouseSliding ) {
13136              var uiHash = {
13137                  handle: this.handles[ index ],
13138                  value: this.value()
13139              };
13140              if ( this.options.values && this.options.values.length ) {
13141                  uiHash.value = this.values( index );
13142                  uiHash.values = this.values();
13143              }
13144  
13145              //store the last changed value index for reference when handles overlap
13146              this._lastChangedValue = index;
13147  
13148              this._trigger( "change", event, uiHash );
13149          }
13150      },
13151  
13152      value: function( newValue ) {
13153          if ( arguments.length ) {
13154              this.options.value = this._trimAlignValue( newValue );
13155              this._refreshValue();
13156              this._change( null, 0 );
13157              return;
13158          }
13159  
13160          return this._value();
13161      },
13162  
13163      values: function( index, newValue ) {
13164          var vals,
13165              newValues,
13166              i;
13167  
13168          if ( arguments.length > 1 ) {
13169              this.options.values[ index ] = this._trimAlignValue( newValue );
13170              this._refreshValue();
13171              this._change( null, index );
13172              return;
13173          }
13174  
13175          if ( arguments.length ) {
13176              if ( $.isArray( arguments[ 0 ] ) ) {
13177                  vals = this.options.values;
13178                  newValues = arguments[ 0 ];
13179                  for ( i = 0; i < vals.length; i += 1 ) {
13180                      vals[ i ] = this._trimAlignValue( newValues[ i ] );
13181                      this._change( null, i );
13182                  }
13183                  this._refreshValue();
13184              } else {
13185                  if ( this.options.values && this.options.values.length ) {
13186                      return this._values( index );
13187                  } else {
13188                      return this.value();
13189                  }
13190              }
13191          } else {
13192              return this._values();
13193          }
13194      },
13195  
13196      _setOption: function( key, value ) {
13197          var i,
13198              valsLength = 0;
13199  
13200          if ( key === "range" && this.options.range === true ) {
13201              if ( value === "min" ) {
13202                  this.options.value = this._values( 0 );
13203                  this.options.values = null;
13204              } else if ( value === "max" ) {
13205                  this.options.value = this._values( this.options.values.length - 1 );
13206                  this.options.values = null;
13207              }
13208          }
13209  
13210          if ( $.isArray( this.options.values ) ) {
13211              valsLength = this.options.values.length;
13212          }
13213  
13214          if ( key === "disabled" ) {
13215              this.element.toggleClass( "ui-state-disabled", !!value );
13216          }
13217  
13218          this._super( key, value );
13219  
13220          switch ( key ) {
13221              case "orientation":
13222                  this._detectOrientation();
13223                  this.element
13224                      .removeClass( "ui-slider-horizontal ui-slider-vertical" )
13225                      .addClass( "ui-slider-" + this.orientation );
13226                  this._refreshValue();
13227  
13228                  // Reset positioning from previous orientation
13229                  this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
13230                  break;
13231              case "value":
13232                  this._animateOff = true;
13233                  this._refreshValue();
13234                  this._change( null, 0 );
13235                  this._animateOff = false;
13236                  break;
13237              case "values":
13238                  this._animateOff = true;
13239                  this._refreshValue();
13240                  for ( i = 0; i < valsLength; i += 1 ) {
13241                      this._change( null, i );
13242                  }
13243                  this._animateOff = false;
13244                  break;
13245              case "step":
13246              case "min":
13247              case "max":
13248                  this._animateOff = true;
13249                  this._calculateNewMax();
13250                  this._refreshValue();
13251                  this._animateOff = false;
13252                  break;
13253              case "range":
13254                  this._animateOff = true;
13255                  this._refresh();
13256                  this._animateOff = false;
13257                  break;
13258          }
13259      },
13260  
13261      //internal value getter
13262      // _value() returns value trimmed by min and max, aligned by step
13263      _value: function() {
13264          var val = this.options.value;
13265          val = this._trimAlignValue( val );
13266  
13267          return val;
13268      },
13269  
13270      //internal values getter
13271      // _values() returns array of values trimmed by min and max, aligned by step
13272      // _values( index ) returns single value trimmed by min and max, aligned by step
13273      _values: function( index ) {
13274          var val,
13275              vals,
13276              i;
13277  
13278          if ( arguments.length ) {
13279              val = this.options.values[ index ];
13280              val = this._trimAlignValue( val );
13281  
13282              return val;
13283          } else if ( this.options.values && this.options.values.length ) {
13284              // .slice() creates a copy of the array
13285              // this copy gets trimmed by min and max and then returned
13286              vals = this.options.values.slice();
13287              for ( i = 0; i < vals.length; i += 1) {
13288                  vals[ i ] = this._trimAlignValue( vals[ i ] );
13289              }
13290  
13291              return vals;
13292          } else {
13293              return [];
13294          }
13295      },
13296  
13297      // returns the step-aligned value that val is closest to, between (inclusive) min and max
13298      _trimAlignValue: function( val ) {
13299          if ( val <= this._valueMin() ) {
13300              return this._valueMin();
13301          }
13302          if ( val >= this._valueMax() ) {
13303              return this._valueMax();
13304          }
13305          var step = ( this.options.step > 0 ) ? this.options.step : 1,
13306              valModStep = (val - this._valueMin()) % step,
13307              alignValue = val - valModStep;
13308  
13309          if ( Math.abs(valModStep) * 2 >= step ) {
13310              alignValue += ( valModStep > 0 ) ? step : ( -step );
13311          }
13312  
13313          // Since JavaScript has problems with large floats, round
13314          // the final value to 5 digits after the decimal point (see #4124)
13315          return parseFloat( alignValue.toFixed(5) );
13316      },
13317  
13318      _calculateNewMax: function() {
13319          var max = this.options.max,
13320              min = this._valueMin(),
13321              step = this.options.step,
13322              aboveMin = Math.floor( ( +( max - min ).toFixed( this._precision() ) ) / step ) * step;
13323          max = aboveMin + min;
13324          this.max = parseFloat( max.toFixed( this._precision() ) );
13325      },
13326  
13327      _precision: function() {
13328          var precision = this._precisionOf( this.options.step );
13329          if ( this.options.min !== null ) {
13330              precision = Math.max( precision, this._precisionOf( this.options.min ) );
13331          }
13332          return precision;
13333      },
13334  
13335      _precisionOf: function( num ) {
13336          var str = num.toString(),
13337              decimal = str.indexOf( "." );
13338          return decimal === -1 ? 0 : str.length - decimal - 1;
13339      },
13340  
13341      _valueMin: function() {
13342          return this.options.min;
13343      },
13344  
13345      _valueMax: function() {
13346          return this.max;
13347      },
13348  
13349      _refreshValue: function() {
13350          var lastValPercent, valPercent, value, valueMin, valueMax,
13351              oRange = this.options.range,
13352              o = this.options,
13353              that = this,
13354              animate = ( !this._animateOff ) ? o.animate : false,
13355              _set = {};
13356  
13357          if ( this.options.values && this.options.values.length ) {
13358              this.handles.each(function( i ) {
13359                  valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
13360                  _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13361                  $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13362                  if ( that.options.range === true ) {
13363                      if ( that.orientation === "horizontal" ) {
13364                          if ( i === 0 ) {
13365                              that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
13366                          }
13367                          if ( i === 1 ) {
13368                              that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13369                          }
13370                      } else {
13371                          if ( i === 0 ) {
13372                              that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
13373                          }
13374                          if ( i === 1 ) {
13375                              that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13376                          }
13377                      }
13378                  }
13379                  lastValPercent = valPercent;
13380              });
13381          } else {
13382              value = this.value();
13383              valueMin = this._valueMin();
13384              valueMax = this._valueMax();
13385              valPercent = ( valueMax !== valueMin ) ?
13386                      ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
13387                      0;
13388              _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13389              this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13390  
13391              if ( oRange === "min" && this.orientation === "horizontal" ) {
13392                  this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
13393              }
13394              if ( oRange === "max" && this.orientation === "horizontal" ) {
13395                  this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13396              }
13397              if ( oRange === "min" && this.orientation === "vertical" ) {
13398                  this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
13399              }
13400              if ( oRange === "max" && this.orientation === "vertical" ) {
13401                  this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13402              }
13403          }
13404      },
13405  
13406      _handleEvents: {
13407          keydown: function( event ) {
13408              var allowed, curVal, newVal, step,
13409                  index = $( event.target ).data( "ui-slider-handle-index" );
13410  
13411              switch ( event.keyCode ) {
13412                  case $.ui.keyCode.HOME:
13413                  case $.ui.keyCode.END:
13414                  case $.ui.keyCode.PAGE_UP:
13415                  case $.ui.keyCode.PAGE_DOWN:
13416                  case $.ui.keyCode.UP:
13417                  case $.ui.keyCode.RIGHT:
13418                  case $.ui.keyCode.DOWN:
13419                  case $.ui.keyCode.LEFT:
13420                      event.preventDefault();
13421                      if ( !this._keySliding ) {
13422                          this._keySliding = true;
13423                          $( event.target ).addClass( "ui-state-active" );
13424                          allowed = this._start( event, index );
13425                          if ( allowed === false ) {
13426                              return;
13427                          }
13428                      }
13429                      break;
13430              }
13431  
13432              step = this.options.step;
13433              if ( this.options.values && this.options.values.length ) {
13434                  curVal = newVal = this.values( index );
13435              } else {
13436                  curVal = newVal = this.value();
13437              }
13438  
13439              switch ( event.keyCode ) {
13440                  case $.ui.keyCode.HOME:
13441                      newVal = this._valueMin();
13442                      break;
13443                  case $.ui.keyCode.END:
13444                      newVal = this._valueMax();
13445                      break;
13446                  case $.ui.keyCode.PAGE_UP:
13447                      newVal = this._trimAlignValue(
13448                          curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
13449                      );
13450                      break;
13451                  case $.ui.keyCode.PAGE_DOWN:
13452                      newVal = this._trimAlignValue(
13453                          curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );
13454                      break;
13455                  case $.ui.keyCode.UP:
13456                  case $.ui.keyCode.RIGHT:
13457                      if ( curVal === this._valueMax() ) {
13458                          return;
13459                      }
13460                      newVal = this._trimAlignValue( curVal + step );
13461                      break;
13462                  case $.ui.keyCode.DOWN:
13463                  case $.ui.keyCode.LEFT:
13464                      if ( curVal === this._valueMin() ) {
13465                          return;
13466                      }
13467                      newVal = this._trimAlignValue( curVal - step );
13468                      break;
13469              }
13470  
13471              this._slide( event, index, newVal );
13472          },
13473          keyup: function( event ) {
13474              var index = $( event.target ).data( "ui-slider-handle-index" );
13475  
13476              if ( this._keySliding ) {
13477                  this._keySliding = false;
13478                  this._stop( event, index );
13479                  this._change( event, index );
13480                  $( event.target ).removeClass( "ui-state-active" );
13481              }
13482          }
13483      }
13484  });
13485  
13486  
13487  /*!
13488   * jQuery UI Sortable 1.11.4
13489   * http://jqueryui.com
13490   *
13491   * Copyright jQuery Foundation and other contributors
13492   * Released under the MIT license.
13493   * http://jquery.org/license
13494   *
13495   * http://api.jqueryui.com/sortable/
13496   */
13497  
13498  
13499  var sortable = $.widget("ui.sortable", $.ui.mouse, {
13500      version: "1.11.4",
13501      widgetEventPrefix: "sort",
13502      ready: false,
13503      options: {
13504          appendTo: "parent",
13505          axis: false,
13506          connectWith: false,
13507          containment: false,
13508          cursor: "auto",
13509          cursorAt: false,
13510          dropOnEmpty: true,
13511          forcePlaceholderSize: false,
13512          forceHelperSize: false,
13513          grid: false,
13514          handle: false,
13515          helper: "original",
13516          items: "> *",
13517          opacity: false,
13518          placeholder: false,
13519          revert: false,
13520          scroll: true,
13521          scrollSensitivity: 20,
13522          scrollSpeed: 20,
13523          scope: "default",
13524          tolerance: "intersect",
13525          zIndex: 1000,
13526  
13527          // callbacks
13528          activate: null,
13529          beforeStop: null,
13530          change: null,
13531          deactivate: null,
13532          out: null,
13533          over: null,
13534          receive: null,
13535          remove: null,
13536          sort: null,
13537          start: null,
13538          stop: null,
13539          update: null
13540      },
13541  
13542      _isOverAxis: function( x, reference, size ) {
13543          return ( x >= reference ) && ( x < ( reference + size ) );
13544      },
13545  
13546      _isFloating: function( item ) {
13547          return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
13548      },
13549  
13550      _create: function() {
13551          this.containerCache = {};
13552          this.element.addClass("ui-sortable");
13553  
13554          //Get the items
13555          this.refresh();
13556  
13557          //Let's determine the parent's offset
13558          this.offset = this.element.offset();
13559  
13560          //Initialize mouse events for interaction
13561          this._mouseInit();
13562  
13563          this._setHandleClassName();
13564  
13565          //We're ready to go
13566          this.ready = true;
13567  
13568      },
13569  
13570      _setOption: function( key, value ) {
13571          this._super( key, value );
13572  
13573          if ( key === "handle" ) {
13574              this._setHandleClassName();
13575          }
13576      },
13577  
13578      _setHandleClassName: function() {
13579          this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
13580          $.each( this.items, function() {
13581              ( this.instance.options.handle ?
13582                  this.item.find( this.instance.options.handle ) : this.item )
13583                  .addClass( "ui-sortable-handle" );
13584          });
13585      },
13586  
13587      _destroy: function() {
13588          this.element
13589              .removeClass( "ui-sortable ui-sortable-disabled" )
13590              .find( ".ui-sortable-handle" )
13591                  .removeClass( "ui-sortable-handle" );
13592          this._mouseDestroy();
13593  
13594          for ( var i = this.items.length - 1; i >= 0; i-- ) {
13595              this.items[i].item.removeData(this.widgetName + "-item");
13596          }
13597  
13598          return this;
13599      },
13600  
13601      _mouseCapture: function(event, overrideHandle) {
13602          var currentItem = null,
13603              validHandle = false,
13604              that = this;
13605  
13606          if (this.reverting) {
13607              return false;
13608          }
13609  
13610          if(this.options.disabled || this.options.type === "static") {
13611              return false;
13612          }
13613  
13614          //We have to refresh the items data once first
13615          this._refreshItems(event);
13616  
13617          //Find out if the clicked node (or one of its parents) is a actual item in this.items
13618          $(event.target).parents().each(function() {
13619              if($.data(this, that.widgetName + "-item") === that) {
13620                  currentItem = $(this);
13621                  return false;
13622              }
13623          });
13624          if($.data(event.target, that.widgetName + "-item") === that) {
13625              currentItem = $(event.target);
13626          }
13627  
13628          if(!currentItem) {
13629              return false;
13630          }
13631          if(this.options.handle && !overrideHandle) {
13632              $(this.options.handle, currentItem).find("*").addBack().each(function() {
13633                  if(this === event.target) {
13634                      validHandle = true;
13635                  }
13636              });
13637              if(!validHandle) {
13638                  return false;
13639              }
13640          }
13641  
13642          this.currentItem = currentItem;
13643          this._removeCurrentsFromItems();
13644          return true;
13645  
13646      },
13647  
13648      _mouseStart: function(event, overrideHandle, noActivation) {
13649  
13650          var i, body,
13651              o = this.options;
13652  
13653          this.currentContainer = this;
13654  
13655          //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
13656          this.refreshPositions();
13657  
13658          //Create and append the visible helper
13659          this.helper = this._createHelper(event);
13660  
13661          //Cache the helper size
13662          this._cacheHelperProportions();
13663  
13664          /*
13665           * - Position generation -
13666           * This block generates everything position related - it's the core of draggables.
13667           */
13668  
13669          //Cache the margins of the original element
13670          this._cacheMargins();
13671  
13672          //Get the next scrolling parent
13673          this.scrollParent = this.helper.scrollParent();
13674  
13675          //The element's absolute position on the page minus margins
13676          this.offset = this.currentItem.offset();
13677          this.offset = {
13678              top: this.offset.top - this.margins.top,
13679              left: this.offset.left - this.margins.left
13680          };
13681  
13682          $.extend(this.offset, {
13683              click: { //Where the click happened, relative to the element
13684                  left: event.pageX - this.offset.left,
13685                  top: event.pageY - this.offset.top
13686              },
13687              parent: this._getParentOffset(),
13688              relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
13689          });
13690  
13691          // Only after we got the offset, we can change the helper's position to absolute
13692          // TODO: Still need to figure out a way to make relative sorting possible
13693          this.helper.css("position", "absolute");
13694          this.cssPosition = this.helper.css("position");
13695  
13696          //Generate the original position
13697          this.originalPosition = this._generatePosition(event);
13698          this.originalPageX = event.pageX;
13699          this.originalPageY = event.pageY;
13700  
13701          //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
13702          (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
13703  
13704          //Cache the former DOM position
13705          this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
13706  
13707          //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
13708          if(this.helper[0] !== this.currentItem[0]) {
13709              this.currentItem.hide();
13710          }
13711  
13712          //Create the placeholder
13713          this._createPlaceholder();
13714  
13715          //Set a containment if given in the options
13716          if(o.containment) {
13717              this._setContainment();
13718          }
13719  
13720          if( o.cursor && o.cursor !== "auto" ) { // cursor option
13721              body = this.document.find( "body" );
13722  
13723              // support: IE
13724              this.storedCursor = body.css( "cursor" );
13725              body.css( "cursor", o.cursor );
13726  
13727              this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
13728          }
13729  
13730          if(o.opacity) { // opacity option
13731              if (this.helper.css("opacity")) {
13732                  this._storedOpacity = this.helper.css("opacity");
13733              }
13734              this.helper.css("opacity", o.opacity);
13735          }
13736  
13737          if(o.zIndex) { // zIndex option
13738              if (this.helper.css("zIndex")) {
13739                  this._storedZIndex = this.helper.css("zIndex");
13740              }
13741              this.helper.css("zIndex", o.zIndex);
13742          }
13743  
13744          //Prepare scrolling
13745          if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
13746              this.overflowOffset = this.scrollParent.offset();
13747          }
13748  
13749          //Call callbacks
13750          this._trigger("start", event, this._uiHash());
13751  
13752          //Recache the helper size
13753          if(!this._preserveHelperProportions) {
13754              this._cacheHelperProportions();
13755          }
13756  
13757  
13758          //Post "activate" events to possible containers
13759          if( !noActivation ) {
13760              for ( i = this.containers.length - 1; i >= 0; i-- ) {
13761                  this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
13762              }
13763          }
13764  
13765          //Prepare possible droppables
13766          if($.ui.ddmanager) {
13767              $.ui.ddmanager.current = this;
13768          }
13769  
13770          if ($.ui.ddmanager && !o.dropBehaviour) {
13771              $.ui.ddmanager.prepareOffsets(this, event);
13772          }
13773  
13774          this.dragging = true;
13775  
13776          this.helper.addClass("ui-sortable-helper");
13777          this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
13778          return true;
13779  
13780      },
13781  
13782      _mouseDrag: function(event) {
13783          var i, item, itemElement, intersection,
13784              o = this.options,
13785              scrolled = false;
13786  
13787          //Compute the helpers position
13788          this.position = this._generatePosition(event);
13789          this.positionAbs = this._convertPositionTo("absolute");
13790  
13791          if (!this.lastPositionAbs) {
13792              this.lastPositionAbs = this.positionAbs;
13793          }
13794  
13795          //Do scrolling
13796          if(this.options.scroll) {
13797              if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
13798  
13799                  if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
13800                      this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
13801                  } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
13802                      this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
13803                  }
13804  
13805                  if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
13806                      this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
13807                  } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
13808                      this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
13809                  }
13810  
13811              } else {
13812  
13813                  if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) {
13814                      scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);
13815                  } else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {
13816                      scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);
13817                  }
13818  
13819                  if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {
13820                      scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);
13821                  } else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {
13822                      scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);
13823                  }
13824  
13825              }
13826  
13827              if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
13828                  $.ui.ddmanager.prepareOffsets(this, event);
13829              }
13830          }
13831  
13832          //Regenerate the absolute position used for position checks
13833          this.positionAbs = this._convertPositionTo("absolute");
13834  
13835          //Set the helper position
13836          if(!this.options.axis || this.options.axis !== "y") {
13837              this.helper[0].style.left = this.position.left+"px";
13838          }
13839          if(!this.options.axis || this.options.axis !== "x") {
13840              this.helper[0].style.top = this.position.top+"px";
13841          }
13842  
13843          //Rearrange
13844          for (i = this.items.length - 1; i >= 0; i--) {
13845  
13846              //Cache variables and intersection, continue if no intersection
13847              item = this.items[i];
13848              itemElement = item.item[0];
13849              intersection = this._intersectsWithPointer(item);
13850              if (!intersection) {
13851                  continue;
13852              }
13853  
13854              // Only put the placeholder inside the current Container, skip all
13855              // items from other containers. This works because when moving
13856              // an item from one container to another the
13857              // currentContainer is switched before the placeholder is moved.
13858              //
13859              // Without this, moving items in "sub-sortables" can cause
13860              // the placeholder to jitter between the outer and inner container.
13861              if (item.instance !== this.currentContainer) {
13862                  continue;
13863              }
13864  
13865              // cannot intersect with itself
13866              // no useless actions that have been done before
13867              // no action if the item moved is the parent of the item checked
13868              if (itemElement !== this.currentItem[0] &&
13869                  this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
13870                  !$.contains(this.placeholder[0], itemElement) &&
13871                  (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
13872              ) {
13873  
13874                  this.direction = intersection === 1 ? "down" : "up";
13875  
13876                  if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
13877                      this._rearrange(event, item);
13878                  } else {
13879                      break;
13880                  }
13881  
13882                  this._trigger("change", event, this._uiHash());
13883                  break;
13884              }
13885          }
13886  
13887          //Post events to containers
13888          this._contactContainers(event);
13889  
13890          //Interconnect with droppables
13891          if($.ui.ddmanager) {
13892              $.ui.ddmanager.drag(this, event);
13893          }
13894  
13895          //Call callbacks
13896          this._trigger("sort", event, this._uiHash());
13897  
13898          this.lastPositionAbs = this.positionAbs;
13899          return false;
13900  
13901      },
13902  
13903      _mouseStop: function(event, noPropagation) {
13904  
13905          if(!event) {
13906              return;
13907          }
13908  
13909          //If we are using droppables, inform the manager about the drop
13910          if ($.ui.ddmanager && !this.options.dropBehaviour) {
13911              $.ui.ddmanager.drop(this, event);
13912          }
13913  
13914          if(this.options.revert) {
13915              var that = this,
13916                  cur = this.placeholder.offset(),
13917                  axis = this.options.axis,
13918                  animation = {};
13919  
13920              if ( !axis || axis === "x" ) {
13921                  animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);
13922              }
13923              if ( !axis || axis === "y" ) {
13924                  animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);
13925              }
13926              this.reverting = true;
13927              $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
13928                  that._clear(event);
13929              });
13930          } else {
13931              this._clear(event, noPropagation);
13932          }
13933  
13934          return false;
13935  
13936      },
13937  
13938      cancel: function() {
13939  
13940          if(this.dragging) {
13941  
13942              this._mouseUp({ target: null });
13943  
13944              if(this.options.helper === "original") {
13945                  this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
13946              } else {
13947                  this.currentItem.show();
13948              }
13949  
13950              //Post deactivating events to containers
13951              for (var i = this.containers.length - 1; i >= 0; i--){
13952                  this.containers[i]._trigger("deactivate", null, this._uiHash(this));
13953                  if(this.containers[i].containerCache.over) {
13954                      this.containers[i]._trigger("out", null, this._uiHash(this));
13955                      this.containers[i].containerCache.over = 0;
13956                  }
13957              }
13958  
13959          }
13960  
13961          if (this.placeholder) {
13962              //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
13963              if(this.placeholder[0].parentNode) {
13964                  this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
13965              }
13966              if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
13967                  this.helper.remove();
13968              }
13969  
13970              $.extend(this, {
13971                  helper: null,
13972                  dragging: false,
13973                  reverting: false,
13974                  _noFinalSort: null
13975              });
13976  
13977              if(this.domPosition.prev) {
13978                  $(this.domPosition.prev).after(this.currentItem);
13979              } else {
13980                  $(this.domPosition.parent).prepend(this.currentItem);
13981              }
13982          }
13983  
13984          return this;
13985  
13986      },
13987  
13988      serialize: function(o) {
13989  
13990          var items = this._getItemsAsjQuery(o && o.connected),
13991              str = [];
13992          o = o || {};
13993  
13994          $(items).each(function() {
13995              var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
13996              if (res) {
13997                  str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
13998              }
13999          });
14000  
14001          if(!str.length && o.key) {
14002              str.push(o.key + "=");
14003          }
14004  
14005          return str.join("&");
14006  
14007      },
14008  
14009      toArray: function(o) {
14010  
14011          var items = this._getItemsAsjQuery(o && o.connected),
14012              ret = [];
14013  
14014          o = o || {};
14015  
14016          items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
14017          return ret;
14018  
14019      },
14020  
14021      /* Be careful with the following core functions */
14022      _intersectsWith: function(item) {
14023  
14024          var x1 = this.positionAbs.left,
14025              x2 = x1 + this.helperProportions.width,
14026              y1 = this.positionAbs.top,
14027              y2 = y1 + this.helperProportions.height,
14028              l = item.left,
14029              r = l + item.width,
14030              t = item.top,
14031              b = t + item.height,
14032              dyClick = this.offset.click.top,
14033              dxClick = this.offset.click.left,
14034              isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
14035              isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
14036              isOverElement = isOverElementHeight && isOverElementWidth;
14037  
14038          if ( this.options.tolerance === "pointer" ||
14039              this.options.forcePointerForContainers ||
14040              (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
14041          ) {
14042              return isOverElement;
14043          } else {
14044  
14045              return (l < x1 + (this.helperProportions.width / 2) && // Right Half
14046                  x2 - (this.helperProportions.width / 2) < r && // Left Half
14047                  t < y1 + (this.helperProportions.height / 2) && // Bottom Half
14048                  y2 - (this.helperProportions.height / 2) < b ); // Top Half
14049  
14050          }
14051      },
14052  
14053      _intersectsWithPointer: function(item) {
14054  
14055          var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
14056              isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
14057              isOverElement = isOverElementHeight && isOverElementWidth,
14058              verticalDirection = this._getDragVerticalDirection(),
14059              horizontalDirection = this._getDragHorizontalDirection();
14060  
14061          if (!isOverElement) {
14062              return false;
14063          }
14064  
14065          return this.floating ?
14066              ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
14067              : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
14068  
14069      },
14070  
14071      _intersectsWithSides: function(item) {
14072  
14073          var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
14074              isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
14075              verticalDirection = this._getDragVerticalDirection(),
14076              horizontalDirection = this._getDragHorizontalDirection();
14077  
14078          if (this.floating && horizontalDirection) {
14079              return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
14080          } else {
14081              return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
14082          }
14083  
14084      },
14085  
14086      _getDragVerticalDirection: function() {
14087          var delta = this.positionAbs.top - this.lastPositionAbs.top;
14088          return delta !== 0 && (delta > 0 ? "down" : "up");
14089      },
14090  
14091      _getDragHorizontalDirection: function() {
14092          var delta = this.positionAbs.left - this.lastPositionAbs.left;
14093          return delta !== 0 && (delta > 0 ? "right" : "left");
14094      },
14095  
14096      refresh: function(event) {
14097          this._refreshItems(event);
14098          this._setHandleClassName();
14099          this.refreshPositions();
14100          return this;
14101      },
14102  
14103      _connectWith: function() {
14104          var options = this.options;
14105          return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
14106      },
14107  
14108      _getItemsAsjQuery: function(connected) {
14109  
14110          var i, j, cur, inst,
14111              items = [],
14112              queries = [],
14113              connectWith = this._connectWith();
14114  
14115          if(connectWith && connected) {
14116              for (i = connectWith.length - 1; i >= 0; i--){
14117                  cur = $(connectWith[i], this.document[0]);
14118                  for ( j = cur.length - 1; j >= 0; j--){
14119                      inst = $.data(cur[j], this.widgetFullName);
14120                      if(inst && inst !== this && !inst.options.disabled) {
14121                          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]);
14122                      }
14123                  }
14124              }
14125          }
14126  
14127          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]);
14128  
14129  		function addItems() {
14130              items.push( this );
14131          }
14132          for (i = queries.length - 1; i >= 0; i--){
14133              queries[i][0].each( addItems );
14134          }
14135  
14136          return $(items);
14137  
14138      },
14139  
14140      _removeCurrentsFromItems: function() {
14141  
14142          var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
14143  
14144          this.items = $.grep(this.items, function (item) {
14145              for (var j=0; j < list.length; j++) {
14146                  if(list[j] === item.item[0]) {
14147                      return false;
14148                  }
14149              }
14150              return true;
14151          });
14152  
14153      },
14154  
14155      _refreshItems: function(event) {
14156  
14157          this.items = [];
14158          this.containers = [this];
14159  
14160          var i, j, cur, inst, targetData, _queries, item, queriesLength,
14161              items = this.items,
14162              queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
14163              connectWith = this._connectWith();
14164  
14165          if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
14166              for (i = connectWith.length - 1; i >= 0; i--){
14167                  cur = $(connectWith[i], this.document[0]);
14168                  for (j = cur.length - 1; j >= 0; j--){
14169                      inst = $.data(cur[j], this.widgetFullName);
14170                      if(inst && inst !== this && !inst.options.disabled) {
14171                          queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
14172                          this.containers.push(inst);
14173                      }
14174                  }
14175              }
14176          }
14177  
14178          for (i = queries.length - 1; i >= 0; i--) {
14179              targetData = queries[i][1];
14180              _queries = queries[i][0];
14181  
14182              for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
14183                  item = $(_queries[j]);
14184  
14185                  item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
14186  
14187                  items.push({
14188                      item: item,
14189                      instance: targetData,
14190                      width: 0, height: 0,
14191                      left: 0, top: 0
14192                  });
14193              }
14194          }
14195  
14196      },
14197  
14198      refreshPositions: function(fast) {
14199  
14200          // Determine whether items are being displayed horizontally
14201          this.floating = this.items.length ?
14202              this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
14203              false;
14204  
14205          //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
14206          if(this.offsetParent && this.helper) {
14207              this.offset.parent = this._getParentOffset();
14208          }
14209  
14210          var i, item, t, p;
14211  
14212          for (i = this.items.length - 1; i >= 0; i--){
14213              item = this.items[i];
14214  
14215              //We ignore calculating positions of all connected containers when we're not over them
14216              if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
14217                  continue;
14218              }
14219  
14220              t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
14221  
14222              if (!fast) {
14223                  item.width = t.outerWidth();
14224                  item.height = t.outerHeight();
14225              }
14226  
14227              p = t.offset();
14228              item.left = p.left;
14229              item.top = p.top;
14230          }
14231  
14232          if(this.options.custom && this.options.custom.refreshContainers) {
14233              this.options.custom.refreshContainers.call(this);
14234          } else {
14235              for (i = this.containers.length - 1; i >= 0; i--){
14236                  p = this.containers[i].element.offset();
14237                  this.containers[i].containerCache.left = p.left;
14238                  this.containers[i].containerCache.top = p.top;
14239                  this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
14240                  this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
14241              }
14242          }
14243  
14244          return this;
14245      },
14246  
14247      _createPlaceholder: function(that) {
14248          that = that || this;
14249          var className,
14250              o = that.options;
14251  
14252          if(!o.placeholder || o.placeholder.constructor === String) {
14253              className = o.placeholder;
14254              o.placeholder = {
14255                  element: function() {
14256  
14257                      var nodeName = that.currentItem[0].nodeName.toLowerCase(),
14258                          element = $( "<" + nodeName + ">", that.document[0] )
14259                              .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
14260                              .removeClass("ui-sortable-helper");
14261  
14262                      if ( nodeName === "tbody" ) {
14263                          that._createTrPlaceholder(
14264                              that.currentItem.find( "tr" ).eq( 0 ),
14265                              $( "<tr>", that.document[ 0 ] ).appendTo( element )
14266                          );
14267                      } else if ( nodeName === "tr" ) {
14268                          that._createTrPlaceholder( that.currentItem, element );
14269                      } else if ( nodeName === "img" ) {
14270                          element.attr( "src", that.currentItem.attr( "src" ) );
14271                      }
14272  
14273                      if ( !className ) {
14274                          element.css( "visibility", "hidden" );
14275                      }
14276  
14277                      return element;
14278                  },
14279                  update: function(container, p) {
14280  
14281                      // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
14282                      // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
14283                      if(className && !o.forcePlaceholderSize) {
14284                          return;
14285                      }
14286  
14287                      //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
14288                      if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
14289                      if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
14290                  }
14291              };
14292          }
14293  
14294          //Create the placeholder
14295          that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
14296  
14297          //Append it after the actual current item
14298          that.currentItem.after(that.placeholder);
14299  
14300          //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
14301          o.placeholder.update(that, that.placeholder);
14302  
14303      },
14304  
14305      _createTrPlaceholder: function( sourceTr, targetTr ) {
14306          var that = this;
14307  
14308          sourceTr.children().each(function() {
14309              $( "<td>&#160;</td>", that.document[ 0 ] )
14310                  .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
14311                  .appendTo( targetTr );
14312          });
14313      },
14314  
14315      _contactContainers: function(event) {
14316          var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
14317              innermostContainer = null,
14318              innermostIndex = null;
14319  
14320          // get innermost container that intersects with item
14321          for (i = this.containers.length - 1; i >= 0; i--) {
14322  
14323              // never consider a container that's located within the item itself
14324              if($.contains(this.currentItem[0], this.containers[i].element[0])) {
14325                  continue;
14326              }
14327  
14328              if(this._intersectsWith(this.containers[i].containerCache)) {
14329  
14330                  // if we've already found a container and it's more "inner" than this, then continue
14331                  if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
14332                      continue;
14333                  }
14334  
14335                  innermostContainer = this.containers[i];
14336                  innermostIndex = i;
14337  
14338              } else {
14339                  // container doesn't intersect. trigger "out" event if necessary
14340                  if(this.containers[i].containerCache.over) {
14341                      this.containers[i]._trigger("out", event, this._uiHash(this));
14342                      this.containers[i].containerCache.over = 0;
14343                  }
14344              }
14345  
14346          }
14347  
14348          // if no intersecting containers found, return
14349          if(!innermostContainer) {
14350              return;
14351          }
14352  
14353          // move the item into the container if it's not there already
14354          if(this.containers.length === 1) {
14355              if (!this.containers[innermostIndex].containerCache.over) {
14356                  this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
14357                  this.containers[innermostIndex].containerCache.over = 1;
14358              }
14359          } else {
14360  
14361              //When entering a new container, we will find the item with the least distance and append our item near it
14362              dist = 10000;
14363              itemWithLeastDistance = null;
14364              floating = innermostContainer.floating || this._isFloating(this.currentItem);
14365              posProperty = floating ? "left" : "top";
14366              sizeProperty = floating ? "width" : "height";
14367              axis = floating ? "clientX" : "clientY";
14368  
14369              for (j = this.items.length - 1; j >= 0; j--) {
14370                  if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
14371                      continue;
14372                  }
14373                  if(this.items[j].item[0] === this.currentItem[0]) {
14374                      continue;
14375                  }
14376  
14377                  cur = this.items[j].item.offset()[posProperty];
14378                  nearBottom = false;
14379                  if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
14380                      nearBottom = true;
14381                  }
14382  
14383                  if ( Math.abs( event[ axis ] - cur ) < dist ) {
14384                      dist = Math.abs( event[ axis ] - cur );
14385                      itemWithLeastDistance = this.items[ j ];
14386                      this.direction = nearBottom ? "up": "down";
14387                  }
14388              }
14389  
14390              //Check if dropOnEmpty is enabled
14391              if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
14392                  return;
14393              }
14394  
14395              if(this.currentContainer === this.containers[innermostIndex]) {
14396                  if ( !this.currentContainer.containerCache.over ) {
14397                      this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
14398                      this.currentContainer.containerCache.over = 1;
14399                  }
14400                  return;
14401              }
14402  
14403              itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
14404              this._trigger("change", event, this._uiHash());
14405              this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
14406              this.currentContainer = this.containers[innermostIndex];
14407  
14408              //Update the placeholder
14409              this.options.placeholder.update(this.currentContainer, this.placeholder);
14410  
14411              this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
14412              this.containers[innermostIndex].containerCache.over = 1;
14413          }
14414  
14415  
14416      },
14417  
14418      _createHelper: function(event) {
14419  
14420          var o = this.options,
14421              helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
14422  
14423          //Add the helper to the DOM if that didn't happen already
14424          if(!helper.parents("body").length) {
14425              $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
14426          }
14427  
14428          if(helper[0] === this.currentItem[0]) {
14429              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") };
14430          }
14431  
14432          if(!helper[0].style.width || o.forceHelperSize) {
14433              helper.width(this.currentItem.width());
14434          }
14435          if(!helper[0].style.height || o.forceHelperSize) {
14436              helper.height(this.currentItem.height());
14437          }
14438  
14439          return helper;
14440  
14441      },
14442  
14443      _adjustOffsetFromHelper: function(obj) {
14444          if (typeof obj === "string") {
14445              obj = obj.split(" ");
14446          }
14447          if ($.isArray(obj)) {
14448              obj = {left: +obj[0], top: +obj[1] || 0};
14449          }
14450          if ("left" in obj) {
14451              this.offset.click.left = obj.left + this.margins.left;
14452          }
14453          if ("right" in obj) {
14454              this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
14455          }
14456          if ("top" in obj) {
14457              this.offset.click.top = obj.top + this.margins.top;
14458          }
14459          if ("bottom" in obj) {
14460              this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
14461          }
14462      },
14463  
14464      _getParentOffset: function() {
14465  
14466  
14467          //Get the offsetParent and cache its position
14468          this.offsetParent = this.helper.offsetParent();
14469          var po = this.offsetParent.offset();
14470  
14471          // This is a special case where we need to modify a offset calculated on start, since the following happened:
14472          // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
14473          // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
14474          //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
14475          if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) {
14476              po.left += this.scrollParent.scrollLeft();
14477              po.top += this.scrollParent.scrollTop();
14478          }
14479  
14480          // This needs to be actually done for all browsers, since pageX/pageY includes this information
14481          // with an ugly IE fix
14482          if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
14483              po = { top: 0, left: 0 };
14484          }
14485  
14486          return {
14487              top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
14488              left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
14489          };
14490  
14491      },
14492  
14493      _getRelativeOffset: function() {
14494  
14495          if(this.cssPosition === "relative") {
14496              var p = this.currentItem.position();
14497              return {
14498                  top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
14499                  left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
14500              };
14501          } else {
14502              return { top: 0, left: 0 };
14503          }
14504  
14505      },
14506  
14507      _cacheMargins: function() {
14508          this.margins = {
14509              left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
14510              top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
14511          };
14512      },
14513  
14514      _cacheHelperProportions: function() {
14515          this.helperProportions = {
14516              width: this.helper.outerWidth(),
14517              height: this.helper.outerHeight()
14518          };
14519      },
14520  
14521      _setContainment: function() {
14522  
14523          var ce, co, over,
14524              o = this.options;
14525          if(o.containment === "parent") {
14526              o.containment = this.helper[0].parentNode;
14527          }
14528          if(o.containment === "document" || o.containment === "window") {
14529              this.containment = [
14530                  0 - this.offset.relative.left - this.offset.parent.left,
14531                  0 - this.offset.relative.top - this.offset.parent.top,
14532                  o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left,
14533                  (o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
14534              ];
14535          }
14536  
14537          if(!(/^(document|window|parent)$/).test(o.containment)) {
14538              ce = $(o.containment)[0];
14539              co = $(o.containment).offset();
14540              over = ($(ce).css("overflow") !== "hidden");
14541  
14542              this.containment = [
14543                  co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
14544                  co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
14545                  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,
14546                  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
14547              ];
14548          }
14549  
14550      },
14551  
14552      _convertPositionTo: function(d, pos) {
14553  
14554          if(!pos) {
14555              pos = this.position;
14556          }
14557          var mod = d === "absolute" ? 1 : -1,
14558              scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
14559              scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
14560  
14561          return {
14562              top: (
14563                  pos.top    +                                                                // The absolute mouse position
14564                  this.offset.relative.top * mod +                                        // Only for relative positioned nodes: Relative offset from element to offset parent
14565                  this.offset.parent.top * mod -                                            // The offsetParent's offset without borders (offset + border)
14566                  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
14567              ),
14568              left: (
14569                  pos.left +                                                                // The absolute mouse position
14570                  this.offset.relative.left * mod +                                        // Only for relative positioned nodes: Relative offset from element to offset parent
14571                  this.offset.parent.left * mod    -                                        // The offsetParent's offset without borders (offset + border)
14572                  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
14573              )
14574          };
14575  
14576      },
14577  
14578      _generatePosition: function(event) {
14579  
14580          var top, left,
14581              o = this.options,
14582              pageX = event.pageX,
14583              pageY = event.pageY,
14584              scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
14585  
14586          // This is another very weird special case that only happens for relative elements:
14587          // 1. If the css position is relative
14588          // 2. and the scroll parent is the document or similar to the offset parent
14589          // we have to refresh the relative offset during the scroll so there are no jumps
14590          if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) {
14591              this.offset.relative = this._getRelativeOffset();
14592          }
14593  
14594          /*
14595           * - Position constraining -
14596           * Constrain the position to a mix of grid, containment.
14597           */
14598  
14599          if(this.originalPosition) { //If we are not dragging yet, we won't check for options
14600  
14601              if(this.containment) {
14602                  if(event.pageX - this.offset.click.left < this.containment[0]) {
14603                      pageX = this.containment[0] + this.offset.click.left;
14604                  }
14605                  if(event.pageY - this.offset.click.top < this.containment[1]) {
14606                      pageY = this.containment[1] + this.offset.click.top;
14607                  }
14608                  if(event.pageX - this.offset.click.left > this.containment[2]) {
14609                      pageX = this.containment[2] + this.offset.click.left;
14610                  }
14611                  if(event.pageY - this.offset.click.top > this.containment[3]) {
14612                      pageY = this.containment[3] + this.offset.click.top;
14613                  }
14614              }
14615  
14616              if(o.grid) {
14617                  top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
14618                  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;
14619  
14620                  left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
14621                  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;
14622              }
14623  
14624          }
14625  
14626          return {
14627              top: (
14628                  pageY -                                                                // The absolute mouse position
14629                  this.offset.click.top -                                                    // Click offset (relative to the element)
14630                  this.offset.relative.top    -                                            // Only for relative positioned nodes: Relative offset from element to offset parent
14631                  this.offset.parent.top +                                                // The offsetParent's offset without borders (offset + border)
14632                  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
14633              ),
14634              left: (
14635                  pageX -                                                                // The absolute mouse position
14636                  this.offset.click.left -                                                // Click offset (relative to the element)
14637                  this.offset.relative.left    -                                            // Only for relative positioned nodes: Relative offset from element to offset parent
14638                  this.offset.parent.left +                                                // The offsetParent's offset without borders (offset + border)
14639                  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
14640              )
14641          };
14642  
14643      },
14644  
14645      _rearrange: function(event, i, a, hardRefresh) {
14646  
14647          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));
14648  
14649          //Various things done here to improve the performance:
14650          // 1. we create a setTimeout, that calls refreshPositions
14651          // 2. on the instance, we have a counter variable, that get's higher after every append
14652          // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
14653          // 4. this lets only the last addition to the timeout stack through
14654          this.counter = this.counter ? ++this.counter : 1;
14655          var counter = this.counter;
14656  
14657          this._delay(function() {
14658              if(counter === this.counter) {
14659                  this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
14660              }
14661          });
14662  
14663      },
14664  
14665      _clear: function(event, noPropagation) {
14666  
14667          this.reverting = false;
14668          // We delay all events that have to be triggered to after the point where the placeholder has been removed and
14669          // everything else normalized again
14670          var i,
14671              delayedTriggers = [];
14672  
14673          // We first have to update the dom position of the actual currentItem
14674          // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
14675          if(!this._noFinalSort && this.currentItem.parent().length) {
14676              this.placeholder.before(this.currentItem);
14677          }
14678          this._noFinalSort = null;
14679  
14680          if(this.helper[0] === this.currentItem[0]) {
14681              for(i in this._storedCSS) {
14682                  if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
14683                      this._storedCSS[i] = "";
14684                  }
14685              }
14686              this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
14687          } else {
14688              this.currentItem.show();
14689          }
14690  
14691          if(this.fromOutside && !noPropagation) {
14692              delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
14693          }
14694          if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
14695              delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
14696          }
14697  
14698          // Check if the items Container has Changed and trigger appropriate
14699          // events.
14700          if (this !== this.currentContainer) {
14701              if(!noPropagation) {
14702                  delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
14703                  delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
14704                  delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
14705              }
14706          }
14707  
14708  
14709          //Post events to containers
14710  		function delayEvent( type, instance, container ) {
14711              return function( event ) {
14712                  container._trigger( type, event, instance._uiHash( instance ) );
14713              };
14714          }
14715          for (i = this.containers.length - 1; i >= 0; i--){
14716              if (!noPropagation) {
14717                  delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
14718              }
14719              if(this.containers[i].containerCache.over) {
14720                  delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
14721                  this.containers[i].containerCache.over = 0;
14722              }
14723          }
14724  
14725          //Do what was originally in plugins
14726          if ( this.storedCursor ) {
14727              this.document.find( "body" ).css( "cursor", this.storedCursor );
14728              this.storedStylesheet.remove();
14729          }
14730          if(this._storedOpacity) {
14731              this.helper.css("opacity", this._storedOpacity);
14732          }
14733          if(this._storedZIndex) {
14734              this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
14735          }
14736  
14737          this.dragging = false;
14738  
14739          if(!noPropagation) {
14740              this._trigger("beforeStop", event, this._uiHash());
14741          }
14742  
14743          //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
14744          this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
14745  
14746          if ( !this.cancelHelperRemoval ) {
14747              if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
14748                  this.helper.remove();
14749              }
14750              this.helper = null;
14751          }
14752  
14753          if(!noPropagation) {
14754              for (i=0; i < delayedTriggers.length; i++) {
14755                  delayedTriggers[i].call(this, event);
14756              } //Trigger all delayed events
14757              this._trigger("stop", event, this._uiHash());
14758          }
14759  
14760          this.fromOutside = false;
14761          return !this.cancelHelperRemoval;
14762  
14763      },
14764  
14765      _trigger: function() {
14766          if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
14767              this.cancel();
14768          }
14769      },
14770  
14771      _uiHash: function(_inst) {
14772          var inst = _inst || this;
14773          return {
14774              helper: inst.helper,
14775              placeholder: inst.placeholder || $([]),
14776              position: inst.position,
14777              originalPosition: inst.originalPosition,
14778              offset: inst.positionAbs,
14779              item: inst.currentItem,
14780              sender: _inst ? _inst.element : null
14781          };
14782      }
14783  
14784  });
14785  
14786  
14787  /*!
14788   * jQuery UI Spinner 1.11.4
14789   * http://jqueryui.com
14790   *
14791   * Copyright jQuery Foundation and other contributors
14792   * Released under the MIT license.
14793   * http://jquery.org/license
14794   *
14795   * http://api.jqueryui.com/spinner/
14796   */
14797  
14798  
14799  function spinner_modifier( fn ) {
14800      return function() {
14801          var previous = this.element.val();
14802          fn.apply( this, arguments );
14803          this._refresh();
14804          if ( previous !== this.element.val() ) {
14805              this._trigger( "change" );
14806          }
14807      };
14808  }
14809  
14810  var spinner = $.widget( "ui.spinner", {
14811      version: "1.11.4",
14812      defaultElement: "<input>",
14813      widgetEventPrefix: "spin",
14814      options: {
14815          culture: null,
14816          icons: {
14817              down: "ui-icon-triangle-1-s",
14818              up: "ui-icon-triangle-1-n"
14819          },
14820          incremental: true,
14821          max: null,
14822          min: null,
14823          numberFormat: null,
14824          page: 10,
14825          step: 1,
14826  
14827          change: null,
14828          spin: null,
14829          start: null,
14830          stop: null
14831      },
14832  
14833      _create: function() {
14834          // handle string values that need to be parsed
14835          this._setOption( "max", this.options.max );
14836          this._setOption( "min", this.options.min );
14837          this._setOption( "step", this.options.step );
14838  
14839          // Only format if there is a value, prevents the field from being marked
14840          // as invalid in Firefox, see #9573.
14841          if ( this.value() !== "" ) {
14842              // Format the value, but don't constrain.
14843              this._value( this.element.val(), true );
14844          }
14845  
14846          this._draw();
14847          this._on( this._events );
14848          this._refresh();
14849  
14850          // turning off autocomplete prevents the browser from remembering the
14851          // value when navigating through history, so we re-enable autocomplete
14852          // if the page is unloaded before the widget is destroyed. #7790
14853          this._on( this.window, {
14854              beforeunload: function() {
14855                  this.element.removeAttr( "autocomplete" );
14856              }
14857          });
14858      },
14859  
14860      _getCreateOptions: function() {
14861          var options = {},
14862              element = this.element;
14863  
14864          $.each( [ "min", "max", "step" ], function( i, option ) {
14865              var value = element.attr( option );
14866              if ( value !== undefined && value.length ) {
14867                  options[ option ] = value;
14868              }
14869          });
14870  
14871          return options;
14872      },
14873  
14874      _events: {
14875          keydown: function( event ) {
14876              if ( this._start( event ) && this._keydown( event ) ) {
14877                  event.preventDefault();
14878              }
14879          },
14880          keyup: "_stop",
14881          focus: function() {
14882              this.previous = this.element.val();
14883          },
14884          blur: function( event ) {
14885              if ( this.cancelBlur ) {
14886                  delete this.cancelBlur;
14887                  return;
14888              }
14889  
14890              this._stop();
14891              this._refresh();
14892              if ( this.previous !== this.element.val() ) {
14893                  this._trigger( "change", event );
14894              }
14895          },
14896          mousewheel: function( event, delta ) {
14897              if ( !delta ) {
14898                  return;
14899              }
14900              if ( !this.spinning && !this._start( event ) ) {
14901                  return false;
14902              }
14903  
14904              this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
14905              clearTimeout( this.mousewheelTimer );
14906              this.mousewheelTimer = this._delay(function() {
14907                  if ( this.spinning ) {
14908                      this._stop( event );
14909                  }
14910              }, 100 );
14911              event.preventDefault();
14912          },
14913          "mousedown .ui-spinner-button": function( event ) {
14914              var previous;
14915  
14916              // We never want the buttons to have focus; whenever the user is
14917              // interacting with the spinner, the focus should be on the input.
14918              // If the input is focused then this.previous is properly set from
14919              // when the input first received focus. If the input is not focused
14920              // then we need to set this.previous based on the value before spinning.
14921              previous = this.element[0] === this.document[0].activeElement ?
14922                  this.previous : this.element.val();
14923  			function checkFocus() {
14924                  var isActive = this.element[0] === this.document[0].activeElement;
14925                  if ( !isActive ) {
14926                      this.element.focus();
14927                      this.previous = previous;
14928                      // support: IE
14929                      // IE sets focus asynchronously, so we need to check if focus
14930                      // moved off of the input because the user clicked on the button.
14931                      this._delay(function() {
14932                          this.previous = previous;
14933                      });
14934                  }
14935              }
14936  
14937              // ensure focus is on (or stays on) the text field
14938              event.preventDefault();
14939              checkFocus.call( this );
14940  
14941              // support: IE
14942              // IE doesn't prevent moving focus even with event.preventDefault()
14943              // so we set a flag to know when we should ignore the blur event
14944              // and check (again) if focus moved off of the input.
14945              this.cancelBlur = true;
14946              this._delay(function() {
14947                  delete this.cancelBlur;
14948                  checkFocus.call( this );
14949              });
14950  
14951              if ( this._start( event ) === false ) {
14952                  return;
14953              }
14954  
14955              this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14956          },
14957          "mouseup .ui-spinner-button": "_stop",
14958          "mouseenter .ui-spinner-button": function( event ) {
14959              // button will add ui-state-active if mouse was down while mouseleave and kept down
14960              if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
14961                  return;
14962              }
14963  
14964              if ( this._start( event ) === false ) {
14965                  return false;
14966              }
14967              this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14968          },
14969          // TODO: do we really want to consider this a stop?
14970          // shouldn't we just stop the repeater and wait until mouseup before
14971          // we trigger the stop event?
14972          "mouseleave .ui-spinner-button": "_stop"
14973      },
14974  
14975      _draw: function() {
14976          var uiSpinner = this.uiSpinner = this.element
14977              .addClass( "ui-spinner-input" )
14978              .attr( "autocomplete", "off" )
14979              .wrap( this._uiSpinnerHtml() )
14980              .parent()
14981                  // add buttons
14982                  .append( this._buttonHtml() );
14983  
14984          this.element.attr( "role", "spinbutton" );
14985  
14986          // button bindings
14987          this.buttons = uiSpinner.find( ".ui-spinner-button" )
14988              .attr( "tabIndex", -1 )
14989              .button()
14990              .removeClass( "ui-corner-all" );
14991  
14992          // IE 6 doesn't understand height: 50% for the buttons
14993          // unless the wrapper has an explicit height
14994          if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
14995                  uiSpinner.height() > 0 ) {
14996              uiSpinner.height( uiSpinner.height() );
14997          }
14998  
14999          // disable spinner if element was already disabled
15000          if ( this.options.disabled ) {
15001              this.disable();
15002          }
15003      },
15004  
15005      _keydown: function( event ) {
15006          var options = this.options,
15007              keyCode = $.ui.keyCode;
15008  
15009          switch ( event.keyCode ) {
15010          case keyCode.UP:
15011              this._repeat( null, 1, event );
15012              return true;
15013          case keyCode.DOWN:
15014              this._repeat( null, -1, event );
15015              return true;
15016          case keyCode.PAGE_UP:
15017              this._repeat( null, options.page, event );
15018              return true;
15019          case keyCode.PAGE_DOWN:
15020              this._repeat( null, -options.page, event );
15021              return true;
15022          }
15023  
15024          return false;
15025      },
15026  
15027      _uiSpinnerHtml: function() {
15028          return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
15029      },
15030  
15031      _buttonHtml: function() {
15032          return "" +
15033              "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
15034                  "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
15035              "</a>" +
15036              "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
15037                  "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
15038              "</a>";
15039      },
15040  
15041      _start: function( event ) {
15042          if ( !this.spinning && this._trigger( "start", event ) === false ) {
15043              return false;
15044          }
15045  
15046          if ( !this.counter ) {
15047              this.counter = 1;
15048          }
15049          this.spinning = true;
15050          return true;
15051      },
15052  
15053      _repeat: function( i, steps, event ) {
15054          i = i || 500;
15055  
15056          clearTimeout( this.timer );
15057          this.timer = this._delay(function() {
15058              this._repeat( 40, steps, event );
15059          }, i );
15060  
15061          this._spin( steps * this.options.step, event );
15062      },
15063  
15064      _spin: function( step, event ) {
15065          var value = this.value() || 0;
15066  
15067          if ( !this.counter ) {
15068              this.counter = 1;
15069          }
15070  
15071          value = this._adjustValue( value + step * this._increment( this.counter ) );
15072  
15073          if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
15074              this._value( value );
15075              this.counter++;
15076          }
15077      },
15078  
15079      _increment: function( i ) {
15080          var incremental = this.options.incremental;
15081  
15082          if ( incremental ) {
15083              return $.isFunction( incremental ) ?
15084                  incremental( i ) :
15085                  Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
15086          }
15087  
15088          return 1;
15089      },
15090  
15091      _precision: function() {
15092          var precision = this._precisionOf( this.options.step );
15093          if ( this.options.min !== null ) {
15094              precision = Math.max( precision, this._precisionOf( this.options.min ) );
15095          }
15096          return precision;
15097      },
15098  
15099      _precisionOf: function( num ) {
15100          var str = num.toString(),
15101              decimal = str.indexOf( "." );
15102          return decimal === -1 ? 0 : str.length - decimal - 1;
15103      },
15104  
15105      _adjustValue: function( value ) {
15106          var base, aboveMin,
15107              options = this.options;
15108  
15109          // make sure we're at a valid step
15110          // - find out where we are relative to the base (min or 0)
15111          base = options.min !== null ? options.min : 0;
15112          aboveMin = value - base;
15113          // - round to the nearest step
15114          aboveMin = Math.round(aboveMin / options.step) * options.step;
15115          // - rounding is based on 0, so adjust back to our base
15116          value = base + aboveMin;
15117  
15118          // fix precision from bad JS floating point math
15119          value = parseFloat( value.toFixed( this._precision() ) );
15120  
15121          // clamp the value
15122          if ( options.max !== null && value > options.max) {
15123              return options.max;
15124          }
15125          if ( options.min !== null && value < options.min ) {
15126              return options.min;
15127          }
15128  
15129          return value;
15130      },
15131  
15132      _stop: function( event ) {
15133          if ( !this.spinning ) {
15134              return;
15135          }
15136  
15137          clearTimeout( this.timer );
15138          clearTimeout( this.mousewheelTimer );
15139          this.counter = 0;
15140          this.spinning = false;
15141          this._trigger( "stop", event );
15142      },
15143  
15144      _setOption: function( key, value ) {
15145          if ( key === "culture" || key === "numberFormat" ) {
15146              var prevValue = this._parse( this.element.val() );
15147              this.options[ key ] = value;
15148              this.element.val( this._format( prevValue ) );
15149              return;
15150          }
15151  
15152          if ( key === "max" || key === "min" || key === "step" ) {
15153              if ( typeof value === "string" ) {
15154                  value = this._parse( value );
15155              }
15156          }
15157          if ( key === "icons" ) {
15158              this.buttons.first().find( ".ui-icon" )
15159                  .removeClass( this.options.icons.up )
15160                  .addClass( value.up );
15161              this.buttons.last().find( ".ui-icon" )
15162                  .removeClass( this.options.icons.down )
15163                  .addClass( value.down );
15164          }
15165  
15166          this._super( key, value );
15167  
15168          if ( key === "disabled" ) {
15169              this.widget().toggleClass( "ui-state-disabled", !!value );
15170              this.element.prop( "disabled", !!value );
15171              this.buttons.button( value ? "disable" : "enable" );
15172          }
15173      },
15174  
15175      _setOptions: spinner_modifier(function( options ) {
15176          this._super( options );
15177      }),
15178  
15179      _parse: function( val ) {
15180          if ( typeof val === "string" && val !== "" ) {
15181              val = window.Globalize && this.options.numberFormat ?
15182                  Globalize.parseFloat( val, 10, this.options.culture ) : +val;
15183          }
15184          return val === "" || isNaN( val ) ? null : val;
15185      },
15186  
15187      _format: function( value ) {
15188          if ( value === "" ) {
15189              return "";
15190          }
15191          return window.Globalize && this.options.numberFormat ?
15192              Globalize.format( value, this.options.numberFormat, this.options.culture ) :
15193              value;
15194      },
15195  
15196      _refresh: function() {
15197          this.element.attr({
15198              "aria-valuemin": this.options.min,
15199              "aria-valuemax": this.options.max,
15200              // TODO: what should we do with values that can't be parsed?
15201              "aria-valuenow": this._parse( this.element.val() )
15202          });
15203      },
15204  
15205      isValid: function() {
15206          var value = this.value();
15207  
15208          // null is invalid
15209          if ( value === null ) {
15210              return false;
15211          }
15212  
15213          // if value gets adjusted, it's invalid
15214          return value === this._adjustValue( value );
15215      },
15216  
15217      // update the value without triggering change
15218      _value: function( value, allowAny ) {
15219          var parsed;
15220          if ( value !== "" ) {
15221              parsed = this._parse( value );
15222              if ( parsed !== null ) {
15223                  if ( !allowAny ) {
15224                      parsed = this._adjustValue( parsed );
15225                  }
15226                  value = this._format( parsed );
15227              }
15228          }
15229          this.element.val( value );
15230          this._refresh();
15231      },
15232  
15233      _destroy: function() {
15234          this.element
15235              .removeClass( "ui-spinner-input" )
15236              .prop( "disabled", false )
15237              .removeAttr( "autocomplete" )
15238              .removeAttr( "role" )
15239              .removeAttr( "aria-valuemin" )
15240              .removeAttr( "aria-valuemax" )
15241              .removeAttr( "aria-valuenow" );
15242          this.uiSpinner.replaceWith( this.element );
15243      },
15244  
15245      stepUp: spinner_modifier(function( steps ) {
15246          this._stepUp( steps );
15247      }),
15248      _stepUp: function( steps ) {
15249          if ( this._start() ) {
15250              this._spin( (steps || 1) * this.options.step );
15251              this._stop();
15252          }
15253      },
15254  
15255      stepDown: spinner_modifier(function( steps ) {
15256          this._stepDown( steps );
15257      }),
15258      _stepDown: function( steps ) {
15259          if ( this._start() ) {
15260              this._spin( (steps || 1) * -this.options.step );
15261              this._stop();
15262          }
15263      },
15264  
15265      pageUp: spinner_modifier(function( pages ) {
15266          this._stepUp( (pages || 1) * this.options.page );
15267      }),
15268  
15269      pageDown: spinner_modifier(function( pages ) {
15270          this._stepDown( (pages || 1) * this.options.page );
15271      }),
15272  
15273      value: function( newVal ) {
15274          if ( !arguments.length ) {
15275              return this._parse( this.element.val() );
15276          }
15277          spinner_modifier( this._value ).call( this, newVal );
15278      },
15279  
15280      widget: function() {
15281          return this.uiSpinner;
15282      }
15283  });
15284  
15285  
15286  /*!
15287   * jQuery UI Tabs 1.11.4
15288   * http://jqueryui.com
15289   *
15290   * Copyright jQuery Foundation and other contributors
15291   * Released under the MIT license.
15292   * http://jquery.org/license
15293   *
15294   * http://api.jqueryui.com/tabs/
15295   */
15296  
15297  
15298  var tabs = $.widget( "ui.tabs", {
15299      version: "1.11.4",
15300      delay: 300,
15301      options: {
15302          active: null,
15303          collapsible: false,
15304          event: "click",
15305          heightStyle: "content",
15306          hide: null,
15307          show: null,
15308  
15309          // callbacks
15310          activate: null,
15311          beforeActivate: null,
15312          beforeLoad: null,
15313          load: null
15314      },
15315  
15316      _isLocal: (function() {
15317          var rhash = /#.*$/;
15318  
15319          return function( anchor ) {
15320              var anchorUrl, locationUrl;
15321  
15322              // support: IE7
15323              // IE7 doesn't normalize the href property when set via script (#9317)
15324              anchor = anchor.cloneNode( false );
15325  
15326              anchorUrl = anchor.href.replace( rhash, "" );
15327              locationUrl = location.href.replace( rhash, "" );
15328  
15329              // decoding may throw an error if the URL isn't UTF-8 (#9518)
15330              try {
15331                  anchorUrl = decodeURIComponent( anchorUrl );
15332              } catch ( error ) {}
15333              try {
15334                  locationUrl = decodeURIComponent( locationUrl );
15335              } catch ( error ) {}
15336  
15337              return anchor.hash.length > 1 && anchorUrl === locationUrl;
15338          };
15339      })(),
15340  
15341      _create: function() {
15342          var that = this,
15343              options = this.options;
15344  
15345          this.running = false;
15346  
15347          this.element
15348              .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
15349              .toggleClass( "ui-tabs-collapsible", options.collapsible );
15350  
15351          this._processTabs();
15352          options.active = this._initialActive();
15353  
15354          // Take disabling tabs via class attribute from HTML
15355          // into account and update option properly.
15356          if ( $.isArray( options.disabled ) ) {
15357              options.disabled = $.unique( options.disabled.concat(
15358                  $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
15359                      return that.tabs.index( li );
15360                  })
15361              ) ).sort();
15362          }
15363  
15364          // check for length avoids error when initializing empty list
15365          if ( this.options.active !== false && this.anchors.length ) {
15366              this.active = this._findActive( options.active );
15367          } else {
15368              this.active = $();
15369          }
15370  
15371          this._refresh();
15372  
15373          if ( this.active.length ) {
15374              this.load( options.active );
15375          }
15376      },
15377  
15378      _initialActive: function() {
15379          var active = this.options.active,
15380              collapsible = this.options.collapsible,
15381              locationHash = location.hash.substring( 1 );
15382  
15383          if ( active === null ) {
15384              // check the fragment identifier in the URL
15385              if ( locationHash ) {
15386                  this.tabs.each(function( i, tab ) {
15387                      if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
15388                          active = i;
15389                          return false;
15390                      }
15391                  });
15392              }
15393  
15394              // check for a tab marked active via a class
15395              if ( active === null ) {
15396                  active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
15397              }
15398  
15399              // no active tab, set to false
15400              if ( active === null || active === -1 ) {
15401                  active = this.tabs.length ? 0 : false;
15402              }
15403          }
15404  
15405          // handle numbers: negative, out of range
15406          if ( active !== false ) {
15407              active = this.tabs.index( this.tabs.eq( active ) );
15408              if ( active === -1 ) {
15409                  active = collapsible ? false : 0;
15410              }
15411          }
15412  
15413          // don't allow collapsible: false and active: false
15414          if ( !collapsible && active === false && this.anchors.length ) {
15415              active = 0;
15416          }
15417  
15418          return active;
15419      },
15420  
15421      _getCreateEventData: function() {
15422          return {
15423              tab: this.active,
15424              panel: !this.active.length ? $() : this._getPanelForTab( this.active )
15425          };
15426      },
15427  
15428      _tabKeydown: function( event ) {
15429          var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
15430              selectedIndex = this.tabs.index( focusedTab ),
15431              goingForward = true;
15432  
15433          if ( this._handlePageNav( event ) ) {
15434              return;
15435          }
15436  
15437          switch ( event.keyCode ) {
15438              case $.ui.keyCode.RIGHT:
15439              case $.ui.keyCode.DOWN:
15440                  selectedIndex++;
15441                  break;
15442              case $.ui.keyCode.UP:
15443              case $.ui.keyCode.LEFT:
15444                  goingForward = false;
15445                  selectedIndex--;
15446                  break;
15447              case $.ui.keyCode.END:
15448                  selectedIndex = this.anchors.length - 1;
15449                  break;
15450              case $.ui.keyCode.HOME:
15451                  selectedIndex = 0;
15452                  break;
15453              case $.ui.keyCode.SPACE:
15454                  // Activate only, no collapsing
15455                  event.preventDefault();
15456                  clearTimeout( this.activating );
15457                  this._activate( selectedIndex );
15458                  return;
15459              case $.ui.keyCode.ENTER:
15460                  // Toggle (cancel delayed activation, allow collapsing)
15461                  event.preventDefault();
15462                  clearTimeout( this.activating );
15463                  // Determine if we should collapse or activate
15464                  this._activate( selectedIndex === this.options.active ? false : selectedIndex );
15465                  return;
15466              default:
15467                  return;
15468          }
15469  
15470          // Focus the appropriate tab, based on which key was pressed
15471          event.preventDefault();
15472          clearTimeout( this.activating );
15473          selectedIndex = this._focusNextTab( selectedIndex, goingForward );
15474  
15475          // Navigating with control/command key will prevent automatic activation
15476          if ( !event.ctrlKey && !event.metaKey ) {
15477  
15478              // Update aria-selected immediately so that AT think the tab is already selected.
15479              // Otherwise AT may confuse the user by stating that they need to activate the tab,
15480              // but the tab will already be activated by the time the announcement finishes.
15481              focusedTab.attr( "aria-selected", "false" );
15482              this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
15483  
15484              this.activating = this._delay(function() {
15485                  this.option( "active", selectedIndex );
15486              }, this.delay );
15487          }
15488      },
15489  
15490      _panelKeydown: function( event ) {
15491          if ( this._handlePageNav( event ) ) {
15492              return;
15493          }
15494  
15495          // Ctrl+up moves focus to the current tab
15496          if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
15497              event.preventDefault();
15498              this.active.focus();
15499          }
15500      },
15501  
15502      // Alt+page up/down moves focus to the previous/next tab (and activates)
15503      _handlePageNav: function( event ) {
15504          if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
15505              this._activate( this._focusNextTab( this.options.active - 1, false ) );
15506              return true;
15507          }
15508          if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
15509              this._activate( this._focusNextTab( this.options.active + 1, true ) );
15510              return true;
15511          }
15512      },
15513  
15514      _findNextTab: function( index, goingForward ) {
15515          var lastTabIndex = this.tabs.length - 1;
15516  
15517  		function constrain() {
15518              if ( index > lastTabIndex ) {
15519                  index = 0;
15520              }
15521              if ( index < 0 ) {
15522                  index = lastTabIndex;
15523              }
15524              return index;
15525          }
15526  
15527          while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
15528              index = goingForward ? index + 1 : index - 1;
15529          }
15530  
15531          return index;
15532      },
15533  
15534      _focusNextTab: function( index, goingForward ) {
15535          index = this._findNextTab( index, goingForward );
15536          this.tabs.eq( index ).focus();
15537          return index;
15538      },
15539  
15540      _setOption: function( key, value ) {
15541          if ( key === "active" ) {
15542              // _activate() will handle invalid values and update this.options
15543              this._activate( value );
15544              return;
15545          }
15546  
15547          if ( key === "disabled" ) {
15548              // don't use the widget factory's disabled handling
15549              this._setupDisabled( value );
15550              return;
15551          }
15552  
15553          this._super( key, value);
15554  
15555          if ( key === "collapsible" ) {
15556              this.element.toggleClass( "ui-tabs-collapsible", value );
15557              // Setting collapsible: false while collapsed; open first panel
15558              if ( !value && this.options.active === false ) {
15559                  this._activate( 0 );
15560              }
15561          }
15562  
15563          if ( key === "event" ) {
15564              this._setupEvents( value );
15565          }
15566  
15567          if ( key === "heightStyle" ) {
15568              this._setupHeightStyle( value );
15569          }
15570      },
15571  
15572      _sanitizeSelector: function( hash ) {
15573          return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
15574      },
15575  
15576      refresh: function() {
15577          var options = this.options,
15578              lis = this.tablist.children( ":has(a[href])" );
15579  
15580          // get disabled tabs from class attribute from HTML
15581          // this will get converted to a boolean if needed in _refresh()
15582          options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
15583              return lis.index( tab );
15584          });
15585  
15586          this._processTabs();
15587  
15588          // was collapsed or no tabs
15589          if ( options.active === false || !this.anchors.length ) {
15590              options.active = false;
15591              this.active = $();
15592          // was active, but active tab is gone
15593          } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
15594              // all remaining tabs are disabled
15595              if ( this.tabs.length === options.disabled.length ) {
15596                  options.active = false;
15597                  this.active = $();
15598              // activate previous tab
15599              } else {
15600                  this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
15601              }
15602          // was active, active tab still exists
15603          } else {
15604              // make sure active index is correct
15605              options.active = this.tabs.index( this.active );
15606          }
15607  
15608          this._refresh();
15609      },
15610  
15611      _refresh: function() {
15612          this._setupDisabled( this.options.disabled );
15613          this._setupEvents( this.options.event );
15614          this._setupHeightStyle( this.options.heightStyle );
15615  
15616          this.tabs.not( this.active ).attr({
15617              "aria-selected": "false",
15618              "aria-expanded": "false",
15619              tabIndex: -1
15620          });
15621          this.panels.not( this._getPanelForTab( this.active ) )
15622              .hide()
15623              .attr({
15624                  "aria-hidden": "true"
15625              });
15626  
15627          // Make sure one tab is in the tab order
15628          if ( !this.active.length ) {
15629              this.tabs.eq( 0 ).attr( "tabIndex", 0 );
15630          } else {
15631              this.active
15632                  .addClass( "ui-tabs-active ui-state-active" )
15633                  .attr({
15634                      "aria-selected": "true",
15635                      "aria-expanded": "true",
15636                      tabIndex: 0
15637                  });
15638              this._getPanelForTab( this.active )
15639                  .show()
15640                  .attr({
15641                      "aria-hidden": "false"
15642                  });
15643          }
15644      },
15645  
15646      _processTabs: function() {
15647          var that = this,
15648              prevTabs = this.tabs,
15649              prevAnchors = this.anchors,
15650              prevPanels = this.panels;
15651  
15652          this.tablist = this._getList()
15653              .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
15654              .attr( "role", "tablist" )
15655  
15656              // Prevent users from focusing disabled tabs via click
15657              .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
15658                  if ( $( this ).is( ".ui-state-disabled" ) ) {
15659                      event.preventDefault();
15660                  }
15661              })
15662  
15663              // support: IE <9
15664              // Preventing the default action in mousedown doesn't prevent IE
15665              // from focusing the element, so if the anchor gets focused, blur.
15666              // We don't have to worry about focusing the previously focused
15667              // element since clicking on a non-focusable element should focus
15668              // the body anyway.
15669              .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
15670                  if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
15671                      this.blur();
15672                  }
15673              });
15674  
15675          this.tabs = this.tablist.find( "> li:has(a[href])" )
15676              .addClass( "ui-state-default ui-corner-top" )
15677              .attr({
15678                  role: "tab",
15679                  tabIndex: -1
15680              });
15681  
15682          this.anchors = this.tabs.map(function() {
15683                  return $( "a", this )[ 0 ];
15684              })
15685              .addClass( "ui-tabs-anchor" )
15686              .attr({
15687                  role: "presentation",
15688                  tabIndex: -1
15689              });
15690  
15691          this.panels = $();
15692  
15693          this.anchors.each(function( i, anchor ) {
15694              var selector, panel, panelId,
15695                  anchorId = $( anchor ).uniqueId().attr( "id" ),
15696                  tab = $( anchor ).closest( "li" ),
15697                  originalAriaControls = tab.attr( "aria-controls" );
15698  
15699              // inline tab
15700              if ( that._isLocal( anchor ) ) {
15701                  selector = anchor.hash;
15702                  panelId = selector.substring( 1 );
15703                  panel = that.element.find( that._sanitizeSelector( selector ) );
15704              // remote tab
15705              } else {
15706                  // If the tab doesn't already have aria-controls,
15707                  // generate an id by using a throw-away element
15708                  panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
15709                  selector = "#" + panelId;
15710                  panel = that.element.find( selector );
15711                  if ( !panel.length ) {
15712                      panel = that._createPanel( panelId );
15713                      panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
15714                  }
15715                  panel.attr( "aria-live", "polite" );
15716              }
15717  
15718              if ( panel.length) {
15719                  that.panels = that.panels.add( panel );
15720              }
15721              if ( originalAriaControls ) {
15722                  tab.data( "ui-tabs-aria-controls", originalAriaControls );
15723              }
15724              tab.attr({
15725                  "aria-controls": panelId,
15726                  "aria-labelledby": anchorId
15727              });
15728              panel.attr( "aria-labelledby", anchorId );
15729          });
15730  
15731          this.panels
15732              .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
15733              .attr( "role", "tabpanel" );
15734  
15735          // Avoid memory leaks (#10056)
15736          if ( prevTabs ) {
15737              this._off( prevTabs.not( this.tabs ) );
15738              this._off( prevAnchors.not( this.anchors ) );
15739              this._off( prevPanels.not( this.panels ) );
15740          }
15741      },
15742  
15743      // allow overriding how to find the list for rare usage scenarios (#7715)
15744      _getList: function() {
15745          return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
15746      },
15747  
15748      _createPanel: function( id ) {
15749          return $( "<div>" )
15750              .attr( "id", id )
15751              .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
15752              .data( "ui-tabs-destroy", true );
15753      },
15754  
15755      _setupDisabled: function( disabled ) {
15756          if ( $.isArray( disabled ) ) {
15757              if ( !disabled.length ) {
15758                  disabled = false;
15759              } else if ( disabled.length === this.anchors.length ) {
15760                  disabled = true;
15761              }
15762          }
15763  
15764          // disable tabs
15765          for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
15766              if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
15767                  $( li )
15768                      .addClass( "ui-state-disabled" )
15769                      .attr( "aria-disabled", "true" );
15770              } else {
15771                  $( li )
15772                      .removeClass( "ui-state-disabled" )
15773                      .removeAttr( "aria-disabled" );
15774              }
15775          }
15776  
15777          this.options.disabled = disabled;
15778      },
15779  
15780      _setupEvents: function( event ) {
15781          var events = {};
15782          if ( event ) {
15783              $.each( event.split(" "), function( index, eventName ) {
15784                  events[ eventName ] = "_eventHandler";
15785              });
15786          }
15787  
15788          this._off( this.anchors.add( this.tabs ).add( this.panels ) );
15789          // Always prevent the default action, even when disabled
15790          this._on( true, this.anchors, {
15791              click: function( event ) {
15792                  event.preventDefault();
15793              }
15794          });
15795          this._on( this.anchors, events );
15796          this._on( this.tabs, { keydown: "_tabKeydown" } );
15797          this._on( this.panels, { keydown: "_panelKeydown" } );
15798  
15799          this._focusable( this.tabs );
15800          this._hoverable( this.tabs );
15801      },
15802  
15803      _setupHeightStyle: function( heightStyle ) {
15804          var maxHeight,
15805              parent = this.element.parent();
15806  
15807          if ( heightStyle === "fill" ) {
15808              maxHeight = parent.height();
15809              maxHeight -= this.element.outerHeight() - this.element.height();
15810  
15811              this.element.siblings( ":visible" ).each(function() {
15812                  var elem = $( this ),
15813                      position = elem.css( "position" );
15814  
15815                  if ( position === "absolute" || position === "fixed" ) {
15816                      return;
15817                  }
15818                  maxHeight -= elem.outerHeight( true );
15819              });
15820  
15821              this.element.children().not( this.panels ).each(function() {
15822                  maxHeight -= $( this ).outerHeight( true );
15823              });
15824  
15825              this.panels.each(function() {
15826                  $( this ).height( Math.max( 0, maxHeight -
15827                      $( this ).innerHeight() + $( this ).height() ) );
15828              })
15829              .css( "overflow", "auto" );
15830          } else if ( heightStyle === "auto" ) {
15831              maxHeight = 0;
15832              this.panels.each(function() {
15833                  maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
15834              }).height( maxHeight );
15835          }
15836      },
15837  
15838      _eventHandler: function( event ) {
15839          var options = this.options,
15840              active = this.active,
15841              anchor = $( event.currentTarget ),
15842              tab = anchor.closest( "li" ),
15843              clickedIsActive = tab[ 0 ] === active[ 0 ],
15844              collapsing = clickedIsActive && options.collapsible,
15845              toShow = collapsing ? $() : this._getPanelForTab( tab ),
15846              toHide = !active.length ? $() : this._getPanelForTab( active ),
15847              eventData = {
15848                  oldTab: active,
15849                  oldPanel: toHide,
15850                  newTab: collapsing ? $() : tab,
15851                  newPanel: toShow
15852              };
15853  
15854          event.preventDefault();
15855  
15856          if ( tab.hasClass( "ui-state-disabled" ) ||
15857                  // tab is already loading
15858                  tab.hasClass( "ui-tabs-loading" ) ||
15859                  // can't switch durning an animation
15860                  this.running ||
15861                  // click on active header, but not collapsible
15862                  ( clickedIsActive && !options.collapsible ) ||
15863                  // allow canceling activation
15864                  ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
15865              return;
15866          }
15867  
15868          options.active = collapsing ? false : this.tabs.index( tab );
15869  
15870          this.active = clickedIsActive ? $() : tab;
15871          if ( this.xhr ) {
15872              this.xhr.abort();
15873          }
15874  
15875          if ( !toHide.length && !toShow.length ) {
15876              $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
15877          }
15878  
15879          if ( toShow.length ) {
15880              this.load( this.tabs.index( tab ), event );
15881          }
15882          this._toggle( event, eventData );
15883      },
15884  
15885      // handles show/hide for selecting tabs
15886      _toggle: function( event, eventData ) {
15887          var that = this,
15888              toShow = eventData.newPanel,
15889              toHide = eventData.oldPanel;
15890  
15891          this.running = true;
15892  
15893  		function complete() {
15894              that.running = false;
15895              that._trigger( "activate", event, eventData );
15896          }
15897  
15898  		function show() {
15899              eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
15900  
15901              if ( toShow.length && that.options.show ) {
15902                  that._show( toShow, that.options.show, complete );
15903              } else {
15904                  toShow.show();
15905                  complete();
15906              }
15907          }
15908  
15909          // start out by hiding, then showing, then completing
15910          if ( toHide.length && this.options.hide ) {
15911              this._hide( toHide, this.options.hide, function() {
15912                  eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
15913                  show();
15914              });
15915          } else {
15916              eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
15917              toHide.hide();
15918              show();
15919          }
15920  
15921          toHide.attr( "aria-hidden", "true" );
15922          eventData.oldTab.attr({
15923              "aria-selected": "false",
15924              "aria-expanded": "false"
15925          });
15926          // If we're switching tabs, remove the old tab from the tab order.
15927          // If we're opening from collapsed state, remove the previous tab from the tab order.
15928          // If we're collapsing, then keep the collapsing tab in the tab order.
15929          if ( toShow.length && toHide.length ) {
15930              eventData.oldTab.attr( "tabIndex", -1 );
15931          } else if ( toShow.length ) {
15932              this.tabs.filter(function() {
15933                  return $( this ).attr( "tabIndex" ) === 0;
15934              })
15935              .attr( "tabIndex", -1 );
15936          }
15937  
15938          toShow.attr( "aria-hidden", "false" );
15939          eventData.newTab.attr({
15940              "aria-selected": "true",
15941              "aria-expanded": "true",
15942              tabIndex: 0
15943          });
15944      },
15945  
15946      _activate: function( index ) {
15947          var anchor,
15948              active = this._findActive( index );
15949  
15950          // trying to activate the already active panel
15951          if ( active[ 0 ] === this.active[ 0 ] ) {
15952              return;
15953          }
15954  
15955          // trying to collapse, simulate a click on the current active header
15956          if ( !active.length ) {
15957              active = this.active;
15958          }
15959  
15960          anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
15961          this._eventHandler({
15962              target: anchor,
15963              currentTarget: anchor,
15964              preventDefault: $.noop
15965          });
15966      },
15967  
15968      _findActive: function( index ) {
15969          return index === false ? $() : this.tabs.eq( index );
15970      },
15971  
15972      _getIndex: function( index ) {
15973          // meta-function to give users option to provide a href string instead of a numerical index.
15974          if ( typeof index === "string" ) {
15975              index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
15976          }
15977  
15978          return index;
15979      },
15980  
15981      _destroy: function() {
15982          if ( this.xhr ) {
15983              this.xhr.abort();
15984          }
15985  
15986          this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
15987  
15988          this.tablist
15989              .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
15990              .removeAttr( "role" );
15991  
15992          this.anchors
15993              .removeClass( "ui-tabs-anchor" )
15994              .removeAttr( "role" )
15995              .removeAttr( "tabIndex" )
15996              .removeUniqueId();
15997  
15998          this.tablist.unbind( this.eventNamespace );
15999  
16000          this.tabs.add( this.panels ).each(function() {
16001              if ( $.data( this, "ui-tabs-destroy" ) ) {
16002                  $( this ).remove();
16003              } else {
16004                  $( this )
16005                      .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
16006                          "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
16007                      .removeAttr( "tabIndex" )
16008                      .removeAttr( "aria-live" )
16009                      .removeAttr( "aria-busy" )
16010                      .removeAttr( "aria-selected" )
16011                      .removeAttr( "aria-labelledby" )
16012                      .removeAttr( "aria-hidden" )
16013                      .removeAttr( "aria-expanded" )
16014                      .removeAttr( "role" );
16015              }
16016          });
16017  
16018          this.tabs.each(function() {
16019              var li = $( this ),
16020                  prev = li.data( "ui-tabs-aria-controls" );
16021              if ( prev ) {
16022                  li
16023                      .attr( "aria-controls", prev )
16024                      .removeData( "ui-tabs-aria-controls" );
16025              } else {
16026                  li.removeAttr( "aria-controls" );
16027              }
16028          });
16029  
16030          this.panels.show();
16031  
16032          if ( this.options.heightStyle !== "content" ) {
16033              this.panels.css( "height", "" );
16034          }
16035      },
16036  
16037      enable: function( index ) {
16038          var disabled = this.options.disabled;
16039          if ( disabled === false ) {
16040              return;
16041          }
16042  
16043          if ( index === undefined ) {
16044              disabled = false;
16045          } else {
16046              index = this._getIndex( index );
16047              if ( $.isArray( disabled ) ) {
16048                  disabled = $.map( disabled, function( num ) {
16049                      return num !== index ? num : null;
16050                  });
16051              } else {
16052                  disabled = $.map( this.tabs, function( li, num ) {
16053                      return num !== index ? num : null;
16054                  });
16055              }
16056          }
16057          this._setupDisabled( disabled );
16058      },
16059  
16060      disable: function( index ) {
16061          var disabled = this.options.disabled;
16062          if ( disabled === true ) {
16063              return;
16064          }
16065  
16066          if ( index === undefined ) {
16067              disabled = true;
16068          } else {
16069              index = this._getIndex( index );
16070              if ( $.inArray( index, disabled ) !== -1 ) {
16071                  return;
16072              }
16073              if ( $.isArray( disabled ) ) {
16074                  disabled = $.merge( [ index ], disabled ).sort();
16075              } else {
16076                  disabled = [ index ];
16077              }
16078          }
16079          this._setupDisabled( disabled );
16080      },
16081  
16082      load: function( index, event ) {
16083          index = this._getIndex( index );
16084          var that = this,
16085              tab = this.tabs.eq( index ),
16086              anchor = tab.find( ".ui-tabs-anchor" ),
16087              panel = this._getPanelForTab( tab ),
16088              eventData = {
16089                  tab: tab,
16090                  panel: panel
16091              },
16092              complete = function( jqXHR, status ) {
16093                  if ( status === "abort" ) {
16094                      that.panels.stop( false, true );
16095                  }
16096  
16097                  tab.removeClass( "ui-tabs-loading" );
16098                  panel.removeAttr( "aria-busy" );
16099  
16100                  if ( jqXHR === that.xhr ) {
16101                      delete that.xhr;
16102                  }
16103              };
16104  
16105          // not remote
16106          if ( this._isLocal( anchor[ 0 ] ) ) {
16107              return;
16108          }
16109  
16110          this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
16111  
16112          // support: jQuery <1.8
16113          // jQuery <1.8 returns false if the request is canceled in beforeSend,
16114          // but as of 1.8, $.ajax() always returns a jqXHR object.
16115          if ( this.xhr && this.xhr.statusText !== "canceled" ) {
16116              tab.addClass( "ui-tabs-loading" );
16117              panel.attr( "aria-busy", "true" );
16118  
16119              this.xhr
16120                  .done(function( response, status, jqXHR ) {
16121                      // support: jQuery <1.8
16122                      // http://bugs.jquery.com/ticket/11778
16123                      setTimeout(function() {
16124                          panel.html( response );
16125                          that._trigger( "load", event, eventData );
16126  
16127                          complete( jqXHR, status );
16128                      }, 1 );
16129                  })
16130                  .fail(function( jqXHR, status ) {
16131                      // support: jQuery <1.8
16132                      // http://bugs.jquery.com/ticket/11778
16133                      setTimeout(function() {
16134                          complete( jqXHR, status );
16135                      }, 1 );
16136                  });
16137          }
16138      },
16139  
16140      _ajaxSettings: function( anchor, event, eventData ) {
16141          var that = this;
16142          return {
16143              url: anchor.attr( "href" ),
16144              beforeSend: function( jqXHR, settings ) {
16145                  return that._trigger( "beforeLoad", event,
16146                      $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
16147              }
16148          };
16149      },
16150  
16151      _getPanelForTab: function( tab ) {
16152          var id = $( tab ).attr( "aria-controls" );
16153          return this.element.find( this._sanitizeSelector( "#" + id ) );
16154      }
16155  });
16156  
16157  
16158  /*!
16159   * jQuery UI Tooltip 1.11.4
16160   * http://jqueryui.com
16161   *
16162   * Copyright jQuery Foundation and other contributors
16163   * Released under the MIT license.
16164   * http://jquery.org/license
16165   *
16166   * http://api.jqueryui.com/tooltip/
16167   */
16168  
16169  
16170  var tooltip = $.widget( "ui.tooltip", {
16171      version: "1.11.4",
16172      options: {
16173          content: function() {
16174              // support: IE<9, Opera in jQuery <1.7
16175              // .text() can't accept undefined, so coerce to a string
16176              var title = $( this ).attr( "title" ) || "";
16177              // Escape title, since we're going from an attribute to raw HTML
16178              return $( "<a>" ).text( title ).html();
16179          },
16180          hide: true,
16181          // Disabled elements have inconsistent behavior across browsers (#8661)
16182          items: "[title]:not([disabled])",
16183          position: {
16184              my: "left top+15",
16185              at: "left bottom",
16186              collision: "flipfit flip"
16187          },
16188          show: true,
16189          tooltipClass: null,
16190          track: false,
16191  
16192          // callbacks
16193          close: null,
16194          open: null
16195      },
16196  
16197      _addDescribedBy: function( elem, id ) {
16198          var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
16199          describedby.push( id );
16200          elem
16201              .data( "ui-tooltip-id", id )
16202              .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
16203      },
16204  
16205      _removeDescribedBy: function( elem ) {
16206          var id = elem.data( "ui-tooltip-id" ),
16207              describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
16208              index = $.inArray( id, describedby );
16209  
16210          if ( index !== -1 ) {
16211              describedby.splice( index, 1 );
16212          }
16213  
16214          elem.removeData( "ui-tooltip-id" );
16215          describedby = $.trim( describedby.join( " " ) );
16216          if ( describedby ) {
16217              elem.attr( "aria-describedby", describedby );
16218          } else {
16219              elem.removeAttr( "aria-describedby" );
16220          }
16221      },
16222  
16223      _create: function() {
16224          this._on({
16225              mouseover: "open",
16226              focusin: "open"
16227          });
16228  
16229          // IDs of generated tooltips, needed for destroy
16230          this.tooltips = {};
16231  
16232          // IDs of parent tooltips where we removed the title attribute
16233          this.parents = {};
16234  
16235          if ( this.options.disabled ) {
16236              this._disable();
16237          }
16238  
16239          // Append the aria-live region so tooltips announce correctly
16240          this.liveRegion = $( "<div>" )
16241              .attr({
16242                  role: "log",
16243                  "aria-live": "assertive",
16244                  "aria-relevant": "additions"
16245              })
16246              .addClass( "ui-helper-hidden-accessible" )
16247              .appendTo( this.document[ 0 ].body );
16248      },
16249  
16250      _setOption: function( key, value ) {
16251          var that = this;
16252  
16253          if ( key === "disabled" ) {
16254              this[ value ? "_disable" : "_enable" ]();
16255              this.options[ key ] = value;
16256              // disable element style changes
16257              return;
16258          }
16259  
16260          this._super( key, value );
16261  
16262          if ( key === "content" ) {
16263              $.each( this.tooltips, function( id, tooltipData ) {
16264                  that._updateContent( tooltipData.element );
16265              });
16266          }
16267      },
16268  
16269      _disable: function() {
16270          var that = this;
16271  
16272          // close open tooltips
16273          $.each( this.tooltips, function( id, tooltipData ) {
16274              var event = $.Event( "blur" );
16275              event.target = event.currentTarget = tooltipData.element[ 0 ];
16276              that.close( event, true );
16277          });
16278  
16279          // remove title attributes to prevent native tooltips
16280          this.element.find( this.options.items ).addBack().each(function() {
16281              var element = $( this );
16282              if ( element.is( "[title]" ) ) {
16283                  element
16284                      .data( "ui-tooltip-title", element.attr( "title" ) )
16285                      .removeAttr( "title" );
16286              }
16287          });
16288      },
16289  
16290      _enable: function() {
16291          // restore title attributes
16292          this.element.find( this.options.items ).addBack().each(function() {
16293              var element = $( this );
16294              if ( element.data( "ui-tooltip-title" ) ) {
16295                  element.attr( "title", element.data( "ui-tooltip-title" ) );
16296              }
16297          });
16298      },
16299  
16300      open: function( event ) {
16301          var that = this,
16302              target = $( event ? event.target : this.element )
16303                  // we need closest here due to mouseover bubbling,
16304                  // but always pointing at the same event target
16305                  .closest( this.options.items );
16306  
16307          // No element to show a tooltip for or the tooltip is already open
16308          if ( !target.length || target.data( "ui-tooltip-id" ) ) {
16309              return;
16310          }
16311  
16312          if ( target.attr( "title" ) ) {
16313              target.data( "ui-tooltip-title", target.attr( "title" ) );
16314          }
16315  
16316          target.data( "ui-tooltip-open", true );
16317  
16318          // kill parent tooltips, custom or native, for hover
16319          if ( event && event.type === "mouseover" ) {
16320              target.parents().each(function() {
16321                  var parent = $( this ),
16322                      blurEvent;
16323                  if ( parent.data( "ui-tooltip-open" ) ) {
16324                      blurEvent = $.Event( "blur" );
16325                      blurEvent.target = blurEvent.currentTarget = this;
16326                      that.close( blurEvent, true );
16327                  }
16328                  if ( parent.attr( "title" ) ) {
16329                      parent.uniqueId();
16330                      that.parents[ this.id ] = {
16331                          element: this,
16332                          title: parent.attr( "title" )
16333                      };
16334                      parent.attr( "title", "" );
16335                  }
16336              });
16337          }
16338  
16339          this._registerCloseHandlers( event, target );
16340          this._updateContent( target, event );
16341      },
16342  
16343      _updateContent: function( target, event ) {
16344          var content,
16345              contentOption = this.options.content,
16346              that = this,
16347              eventType = event ? event.type : null;
16348  
16349          if ( typeof contentOption === "string" ) {
16350              return this._open( event, target, contentOption );
16351          }
16352  
16353          content = contentOption.call( target[0], function( response ) {
16354  
16355              // IE may instantly serve a cached response for ajax requests
16356              // delay this call to _open so the other call to _open runs first
16357              that._delay(function() {
16358  
16359                  // Ignore async response if tooltip was closed already
16360                  if ( !target.data( "ui-tooltip-open" ) ) {
16361                      return;
16362                  }
16363  
16364                  // jQuery creates a special event for focusin when it doesn't
16365                  // exist natively. To improve performance, the native event
16366                  // object is reused and the type is changed. Therefore, we can't
16367                  // rely on the type being correct after the event finished
16368                  // bubbling, so we set it back to the previous value. (#8740)
16369                  if ( event ) {
16370                      event.type = eventType;
16371                  }
16372                  this._open( event, target, response );
16373              });
16374          });
16375          if ( content ) {
16376              this._open( event, target, content );
16377          }
16378      },
16379  
16380      _open: function( event, target, content ) {
16381          var tooltipData, tooltip, delayedShow, a11yContent,
16382              positionOption = $.extend( {}, this.options.position );
16383  
16384          if ( !content ) {
16385              return;
16386          }
16387  
16388          // Content can be updated multiple times. If the tooltip already
16389          // exists, then just update the content and bail.
16390          tooltipData = this._find( target );
16391          if ( tooltipData ) {
16392              tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
16393              return;
16394          }
16395  
16396          // if we have a title, clear it to prevent the native tooltip
16397          // we have to check first to avoid defining a title if none exists
16398          // (we don't want to cause an element to start matching [title])
16399          //
16400          // We use removeAttr only for key events, to allow IE to export the correct
16401          // accessible attributes. For mouse events, set to empty string to avoid
16402          // native tooltip showing up (happens only when removing inside mouseover).
16403          if ( target.is( "[title]" ) ) {
16404              if ( event && event.type === "mouseover" ) {
16405                  target.attr( "title", "" );
16406              } else {
16407                  target.removeAttr( "title" );
16408              }
16409          }
16410  
16411          tooltipData = this._tooltip( target );
16412          tooltip = tooltipData.tooltip;
16413          this._addDescribedBy( target, tooltip.attr( "id" ) );
16414          tooltip.find( ".ui-tooltip-content" ).html( content );
16415  
16416          // Support: Voiceover on OS X, JAWS on IE <= 9
16417          // JAWS announces deletions even when aria-relevant="additions"
16418          // Voiceover will sometimes re-read the entire log region's contents from the beginning
16419          this.liveRegion.children().hide();
16420          if ( content.clone ) {
16421              a11yContent = content.clone();
16422              a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
16423          } else {
16424              a11yContent = content;
16425          }
16426          $( "<div>" ).html( a11yContent ).appendTo( this.liveRegion );
16427  
16428  		function position( event ) {
16429              positionOption.of = event;
16430              if ( tooltip.is( ":hidden" ) ) {
16431                  return;
16432              }
16433              tooltip.position( positionOption );
16434          }
16435          if ( this.options.track && event && /^mouse/.test( event.type ) ) {
16436              this._on( this.document, {
16437                  mousemove: position
16438              });
16439              // trigger once to override element-relative positioning
16440              position( event );
16441          } else {
16442              tooltip.position( $.extend({
16443                  of: target
16444              }, this.options.position ) );
16445          }
16446  
16447          tooltip.hide();
16448  
16449          this._show( tooltip, this.options.show );
16450          // Handle tracking tooltips that are shown with a delay (#8644). As soon
16451          // as the tooltip is visible, position the tooltip using the most recent
16452          // event.
16453          if ( this.options.show && this.options.show.delay ) {
16454              delayedShow = this.delayedShow = setInterval(function() {
16455                  if ( tooltip.is( ":visible" ) ) {
16456                      position( positionOption.of );
16457                      clearInterval( delayedShow );
16458                  }
16459              }, $.fx.interval );
16460          }
16461  
16462          this._trigger( "open", event, { tooltip: tooltip } );
16463      },
16464  
16465      _registerCloseHandlers: function( event, target ) {
16466          var events = {
16467              keyup: function( event ) {
16468                  if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
16469                      var fakeEvent = $.Event(event);
16470                      fakeEvent.currentTarget = target[0];
16471                      this.close( fakeEvent, true );
16472                  }
16473              }
16474          };
16475  
16476          // Only bind remove handler for delegated targets. Non-delegated
16477          // tooltips will handle this in destroy.
16478          if ( target[ 0 ] !== this.element[ 0 ] ) {
16479              events.remove = function() {
16480                  this._removeTooltip( this._find( target ).tooltip );
16481              };
16482          }
16483  
16484          if ( !event || event.type === "mouseover" ) {
16485              events.mouseleave = "close";
16486          }
16487          if ( !event || event.type === "focusin" ) {
16488              events.focusout = "close";
16489          }
16490          this._on( true, target, events );
16491      },
16492  
16493      close: function( event ) {
16494          var tooltip,
16495              that = this,
16496              target = $( event ? event.currentTarget : this.element ),
16497              tooltipData = this._find( target );
16498  
16499          // The tooltip may already be closed
16500          if ( !tooltipData ) {
16501  
16502              // We set ui-tooltip-open immediately upon open (in open()), but only set the
16503              // additional data once there's actually content to show (in _open()). So even if the
16504              // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
16505              // the period between open() and _open().
16506              target.removeData( "ui-tooltip-open" );
16507              return;
16508          }
16509  
16510          tooltip = tooltipData.tooltip;
16511  
16512          // disabling closes the tooltip, so we need to track when we're closing
16513          // to avoid an infinite loop in case the tooltip becomes disabled on close
16514          if ( tooltipData.closing ) {
16515              return;
16516          }
16517  
16518          // Clear the interval for delayed tracking tooltips
16519          clearInterval( this.delayedShow );
16520  
16521          // only set title if we had one before (see comment in _open())
16522          // If the title attribute has changed since open(), don't restore
16523          if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
16524              target.attr( "title", target.data( "ui-tooltip-title" ) );
16525          }
16526  
16527          this._removeDescribedBy( target );
16528  
16529          tooltipData.hiding = true;
16530          tooltip.stop( true );
16531          this._hide( tooltip, this.options.hide, function() {
16532              that._removeTooltip( $( this ) );
16533          });
16534  
16535          target.removeData( "ui-tooltip-open" );
16536          this._off( target, "mouseleave focusout keyup" );
16537  
16538          // Remove 'remove' binding only on delegated targets
16539          if ( target[ 0 ] !== this.element[ 0 ] ) {
16540              this._off( target, "remove" );
16541          }
16542          this._off( this.document, "mousemove" );
16543  
16544          if ( event && event.type === "mouseleave" ) {
16545              $.each( this.parents, function( id, parent ) {
16546                  $( parent.element ).attr( "title", parent.title );
16547                  delete that.parents[ id ];
16548              });
16549          }
16550  
16551          tooltipData.closing = true;
16552          this._trigger( "close", event, { tooltip: tooltip } );
16553          if ( !tooltipData.hiding ) {
16554              tooltipData.closing = false;
16555          }
16556      },
16557  
16558      _tooltip: function( element ) {
16559          var tooltip = $( "<div>" )
16560                  .attr( "role", "tooltip" )
16561                  .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
16562                      ( this.options.tooltipClass || "" ) ),
16563              id = tooltip.uniqueId().attr( "id" );
16564  
16565          $( "<div>" )
16566              .addClass( "ui-tooltip-content" )
16567              .appendTo( tooltip );
16568  
16569          tooltip.appendTo( this.document[0].body );
16570  
16571          return this.tooltips[ id ] = {
16572              element: element,
16573              tooltip: tooltip
16574          };
16575      },
16576  
16577      _find: function( target ) {
16578          var id = target.data( "ui-tooltip-id" );
16579          return id ? this.tooltips[ id ] : null;
16580      },
16581  
16582      _removeTooltip: function( tooltip ) {
16583          tooltip.remove();
16584          delete this.tooltips[ tooltip.attr( "id" ) ];
16585      },
16586  
16587      _destroy: function() {
16588          var that = this;
16589  
16590          // close open tooltips
16591          $.each( this.tooltips, function( id, tooltipData ) {
16592              // Delegate to close method to handle common cleanup
16593              var event = $.Event( "blur" ),
16594                  element = tooltipData.element;
16595              event.target = event.currentTarget = element[ 0 ];
16596              that.close( event, true );
16597  
16598              // Remove immediately; destroying an open tooltip doesn't use the
16599              // hide animation
16600              $( "#" + id ).remove();
16601  
16602              // Restore the title
16603              if ( element.data( "ui-tooltip-title" ) ) {
16604                  // If the title attribute has changed since open(), don't restore
16605                  if ( !element.attr( "title" ) ) {
16606                      element.attr( "title", element.data( "ui-tooltip-title" ) );
16607                  }
16608                  element.removeData( "ui-tooltip-title" );
16609              }
16610          });
16611          this.liveRegion.remove();
16612      }
16613  });
16614  
16615  
16616  
16617  }));