text: /*
   * jQuery selectBox - A cosmetic, styleable replacement for SELECT elements
   *
   * Licensed under the MIT license: http://opensource.org/licenses/MIT
   *
   * v1.2.0
   *
   * https://github.com/marcj/jquery-selectBox
   */
  ;(function ($) {
  
      /**
       * SelectBox class.
       *
       * @param {HTMLElement|jQuery} select If it's a jQuery object, we use the first element.
       * @param {Object}             options
       * @constructor
       */
      var SelectBox = this.SelectBox = function (select, options) {
          if (select instanceof jQuery) {
              if (select.length > 0) {
                  select = select[0];
              } else {
                  return;
              }
          }
  
          this.typeTimer     = null;
          this.typeSearch    = '';
          this.isMac         = navigator.platform.match(/mac/i);
          options            = 'object' === typeof options ? options :  {};
          this.selectElement = select;
  
          // Disable for iOS devices (their native controls are more suitable for a touch device)
          if (!options.mobile && navigator.userAgent.match(/iPad|iPhone|Android|IEMobile|BlackBerry/i)) {
              return false;
          }
  
          // Element must be a select control
          if ('select' !== select.tagName.toLowerCase()) {
              return false;
          }
  
          this.init(options);
      }
  
      /**
       * @type {String}
       */
      SelectBox.prototype.version = '1.2.0';
  
      /**
       * @param {Object} options
       *
       * @returns {Boolean}
       */
      SelectBox.prototype.init = function (options) {
          var select = $(this.selectElement);
          if (select.data('selectBox-control')) {
              return false;
          }
  
          var control    = $('<a class="selectBox" />')
              , inline   = select.attr('multiple') || parseInt(select.attr('size')) > 1
              , settings = options || {}
              , tabIndex = parseInt(select.prop('tabindex')) || 0
              , self     = this;
  
          control
              // .width(select.outerWidth())
              .addClass(select.attr('class'))
              .attr('title', select.attr('title') || '')
              .attr('tabindex', tabIndex)
              .css('display', 'inline-block')
              .bind('focus.selectBox', function () {
                  if (this !== document.activeElement && document.body !== document.activeElement) {
                      $(document.activeElement).blur();
                  }
                  if (control.hasClass('selectBox-active')) {
                      return;
                  }
                  control.addClass('selectBox-active');
                  select.trigger('focus');
              })
              .bind('blur.selectBox', function () {
                  if (!control.hasClass('selectBox-active')) {
                      return;
                  }
                  control.removeClass('selectBox-active');
                  select.trigger('blur');
              });
  
          if (!$(window).data('selectBox-bindings')) {
              $(window)
                  .data('selectBox-bindings', true)
                  .bind('scroll.selectBox', this.hideMenus)
                  .bind('resize.selectBox', this.hideMenus);
          }
  
          if (select.attr('disabled')) {
              control.addClass('selectBox-disabled');
          }
  
          // Focus on control when label is clicked
          select.bind('click.selectBox', function (event) {
              control.focus();
              event.preventDefault();
          });
  
          // Generate control
          if (inline) {
              // Inline controls
              options = this.getOptions('inline');
  
              control
                  .append(options)
                  .data('selectBox-options', options).addClass('selectBox-inline selectBox-menuShowing')
                  .bind('keydown.selectBox', function (event) {
                      self.handleKeyDown(event);
                  })
                  .bind('keypress.selectBox',function (event) {
                      self.handleKeyPress(event);
                  })
                  .bind('mousedown.selectBox',function (event) {
                      if (1 !== event.which) {
                          return;
                      }
                      if ($(event.target).is('A.selectBox-inline')) {
                          event.preventDefault();
                      }
                      if (!control.hasClass('selectBox-focus')) {
                          control.focus();
                      }
                  })
                  .insertAfter(select);
  
              // Auto-height based on size attribute
              if (!select[0].style.height) {
                  var size = select.attr('size') ? parseInt(select.attr('size')) : 5;
                  // Draw a dummy control off-screen, measure, and remove it
                  var tmp = control
                      .clone()
                      .removeAttr('id')
                      .css({
                          position: 'absolute',
                          top: '-9999em'
                      })
                      .show()
                      .appendTo('body');
                  tmp.find('.selectBox-options').html('<li><a>\u00A0</a></li>');
                  var optionHeight = parseInt(tmp.find('.selectBox-options A:first').html('&nbsp;').outerHeight());
                  tmp.remove();
                  control.height(optionHeight * size);
              }
              this.disableSelection(control);
          } else {
              // Dropdown controls
              var label = $('<span class="selectBox-label" />'),
                  arrow = $('<span class="selectBox-arrow" />');
  
              // Update label
              label.attr('class', this.getLabelClass()).text(this.getLabelText());
              options = this.getOptions('dropdown');
              options.appendTo('BODY');
  
              control
                  .data('selectBox-options', options)
                  .addClass('selectBox-dropdown')
                  .append(label)
                  .append(arrow)
                  .bind('mousedown.selectBox', function (event) {
                      if (1 === event.which) {
                          if (control.hasClass('selectBox-menuShowing')) {
                              self.hideMenus();
                          } else {
                              event.stopPropagation();
                              // Webkit fix to prevent premature selection of options
                              options
                                  .data('selectBox-down-at-x', event.screenX)
                                  .data('selectBox-down-at-y', event.screenY);
                              self.showMenu();
                          }
                      }
                  })
                  .bind('keydown.selectBox', function (event) {
                      self.handleKeyDown(event);
                  })
                  .bind('keypress.selectBox', function (event) {
                      self.handleKeyPress(event);
                  })
                  .bind('open.selectBox',function (event, triggerData) {
                      if (triggerData && triggerData._selectBox === true) {
                          return;
                      }
                      self.showMenu();
                  })
                  .bind('close.selectBox', function (event, triggerData) {
                      if (triggerData && triggerData._selectBox === true) {
                          return;
                      }
                      self.hideMenus();
                  })
                  .insertAfter(select);
  
              // Set label width
              var labelWidth =
                      control.width()
                    - arrow.outerWidth()
                    - (parseInt(label.css('paddingLeft')) || 0)
                    - (parseInt(label.css('paddingRight')) || 0);
  
              label.width(labelWidth);
              this.disableSelection(control);
          }
          // Store data for later use and show the control
          select
              .addClass('selectBox')
              .data('selectBox-control', control)
              .data('selectBox-settings', settings)
              .hide();
      };
  
      /**
       * @param {String} type 'inline'|'dropdown'
       * @returns {jQuery}
       */
      SelectBox.prototype.getOptions = function (type) {
          var options;
          var select = $(this.selectElement);
          var self   = this;
          // Private function to handle recursion in the getOptions function.
          var _getOptions = function (select, options) {
              // Loop through the set in order of element children.
              select.children('OPTION, OPTGROUP').each(function () {
                  // If the element is an option, add it to the list.
                  if ($(this).is('OPTION')) {
                      // Check for a value in the option found.
                      if ($(this).length > 0) {
                          // Create an option form the found element.
                          self.generateOptions($(this), options);
                      } else {
                          // No option information found, so add an empty.
                          options.append('<li>\u00A0</li>');
                      }
                  } else {
                      // If the element is an option group, add the group and call this function on it.
                      var optgroup = $('<li class="selectBox-optgroup" />');
                      optgroup.text($(this).attr('label'));
                      options.append(optgroup);
                      options = _getOptions($(this), options);
                  }
              });
              // Return the built strin
              return options;
          };
  
          switch (type) {
              case 'inline':
                  options = $('<ul class="selectBox-options" />');
                  options = _getOptions(select, options);
                  options
                      .find('A')
                      .bind('mouseover.selectBox', function (event) {
                          self.addHover($(this).parent());
                      })
                      .bind('mouseout.selectBox',function (event) {
                          self.removeHover($(this).parent());
                      })
                      .bind('mousedown.selectBox',function (event) {
                          if (1 !== event.which) {
                              return
                          }
                          event.preventDefault(); // Prevent options from being "dragged"
                          if (!select.selectBox('control').hasClass('selectBox-active')) {
                              select.selectBox('control').focus();
                          }
                      })
                      .bind('mouseup.selectBox', function (event) {
                          if (1 !== event.which) {
                              return;
                          }
                          self.hideMenus();
                          self.selectOption($(this).parent(), event);
                      });
  
                  this.disableSelection(options);
                  return options;
              case 'dropdown':
                  options = $('<ul class="selectBox-dropdown-menu selectBox-options" />');
                  options = _getOptions(select, options);
  
                  options
                      .data('selectBox-select', select)
                      .css('display', 'none')
                      .appendTo('BODY')
                      .find('A')
                      .bind('mousedown.selectBox', function (event) {
                          if (event.which === 1) {
                              event.preventDefault(); // Prevent options from being "dragged"
                              if (event.screenX === options.data('selectBox-down-at-x') &&
                                  event.screenY === options.data('selectBox-down-at-y')) {
                                  options.removeData('selectBox-down-at-x').removeData('selectBox-down-at-y');
                                  self.hideMenus();
                              }
                          }
                      })
                      .bind('mouseup.selectBox', function (event) {
                          if (1 !== event.which) {
                              return;
                          }
                          if (event.screenX === options.data('selectBox-down-at-x') &&
                              event.screenY === options.data('selectBox-down-at-y')) {
                              return;
                          } else {
                              options.removeData('selectBox-down-at-x').removeData('selectBox-down-at-y');
                          }
                          self.selectOption($(this).parent());
                          self.hideMenus();
                      })
                      .bind('mouseover.selectBox', function (event) {
                          self.addHover($(this).parent());
                      })
                      .bind('mouseout.selectBox', function (event) {
                          self.removeHover($(this).parent());
                      });
  
                  // Inherit classes for dropdown menu
                  var classes = select.attr('class') || '';
                  if ('' !== classes) {
                      classes = classes.split(' ');
                      for (var i in classes) {
                          options.addClass(classes[i] + '-selectBox-dropdown-menu');
                      }
                  }
                  this.disableSelection(options);
                  return options;
          }
      };
  
      /**
       * Returns the current class of the selected option.
       *
       * @returns {String}
       */
      SelectBox.prototype.getLabelClass = function () {
          var selected = $(this.selectElement).find('OPTION:selected');
          return ('selectBox-label ' + (selected.attr('class') || '')).replace(/\s+$/, '');
      };
  
      /**
       * Returns the current label of the selected option.
       *
       * @returns {String}
       */
      SelectBox.prototype.getLabelText = function () {
          var selected = $(this.selectElement).find('OPTION:selected');
          return selected.text() || '\u00A0';
      };
  
      /**
       * Sets the label.
       * This method uses the getLabelClass() and getLabelText() methods.
       */
      SelectBox.prototype.setLabel = function () {
          var select = $(this.selectElement);
          var control = select.data('selectBox-control');
          if (!control) {
              return;
          }
  
          control
              .find('.selectBox-label')
              .attr('class', this.getLabelClass())
              .text(this.getLabelText());
      };
  
      /**
       * Destroys the SelectBox instance and shows the origin select element.
       *
       */
      SelectBox.prototype.destroy = function () {
          var select = $(this.selectElement);
          var control = select.data('selectBox-control');
          if (!control) {
              return;
          }
  
          var options = control.data('selectBox-options');
          options.remove();
          control.remove();
          select
              .removeClass('selectBox')
              .removeData('selectBox-control')
              .data('selectBox-control', null)
              .removeData('selectBox-settings')
              .data('selectBox-settings', null)
              .show();
      };
  
      /**
       * Refreshes the option elements.
       */
      SelectBox.prototype.refresh = function () {
          var select = $(this.selectElement)
              , control = select.data('selectBox-control')
              , type = control.hasClass('selectBox-dropdown') ? 'dropdown' : 'inline'
              , options;
  
          // Remove old options
          control.data('selectBox-options').remove();
  
          // Generate new options
          options  = this.getOptions(type);
          control.data('selectBox-options', options);
  
          switch (type) {
              case 'inline':
                  control.append(options);
                  break;
              case 'dropdown':
                  // Update label
                  this.setLabel();
                  $("BODY").append(options);
                  break;
          }
  
          // Restore opened dropdown state (original menu was trashed)
          if ('dropdown' === type && control.hasClass('selectBox-menuShowing')) {
              this.showMenu();
          }
      };
  
      /**
       * Shows the dropdown menu.
       */
      SelectBox.prototype.showMenu = function () {
          var self = this
              , select   = $(this.selectElement)
              , control  = select.data('selectBox-control')
              , settings = select.data('selectBox-settings')
              , options  = control.data('selectBox-options');
  
          if (control.hasClass('selectBox-disabled')) {
              return false;
          }
  
          this.hideMenus();
          
          // Get top and bottom width of selectBox
          var borderBottomWidth = parseInt(control.css('borderBottomWidth')) || 0;
          var borderTopWidth = parseInt(control.css('borderTopWidth')) || 0;
          
          // Get proper variables for keeping options in viewport
          var pos = control.offset()
              , optionsHeight = options.outerHeight()
              , controlHeight = control.outerHeight()
              , maxHeight = parseInt(options.css('max-height'))
              , scrollPos = $(window).scrollTop()
              , heightToTop = pos.top - scrollPos
              , heightToBottom = $(window).height() - ( heightToTop + controlHeight )
              , posTop = heightToTop > heightToBottom
              , top = posTop 
                    ? pos.top - optionsHeight + borderTopWidth
                    : pos.top + controlHeight - borderBottomWidth;        
          
          
          // If the height to top and height to bottom are less than the max-height
          if(heightToTop < maxHeight&& heightToBottom < maxHeight){
              
              // Set max-height and top
              if(posTop){
                  var maxHeightDiff = maxHeight - ( heightToTop - 5 );
                  options.css({'max-height': maxHeight - maxHeightDiff + 'px'});
                  top = top + maxHeightDiff;
              }else{
                  var maxHeightDiff = maxHeight - ( heightToBottom - 5 );
                  options.css({'max-height': maxHeight - maxHeightDiff + 'px'});
              }
              
          }
          
          // Save if position is top to options data
          options.data('posTop',posTop);
          
          
          // Menu position
          options
              .width(control.innerWidth())
              .css({
                  top: top,
                  left: control.offset().left
              })
              // Add Top and Bottom class based on position
              .addClass('selectBox-options selectBox-options-'+(posTop?'top':'bottom'));
  
  
          if (select.triggerHandler('beforeopen')) {
              return false;
          }
  
          var dispatchOpenEvent = function () {
              select.triggerHandler('open', {
                  _selectBox: true
              });
          };
  
          // Show menu
          switch (settings.menuTransition) {
              case 'fade':
                  options.fadeIn(settings.menuSpeed, dispatchOpenEvent);
                  break;
              case 'slide':
                  options.slideDown(settings.menuSpeed, dispatchOpenEvent);
                  break;
              default:
                  options.show(settings.menuSpeed, dispatchOpenEvent);
                  break;
          }
  
          if (!settings.menuSpeed) {
              dispatchOpenEvent();
          }
  
          // Center on selected option
          var li = options.find('.selectBox-selected:first');
          this.keepOptionInView(li, true);
          this.addHover(li);
          control.addClass('selectBox-menuShowing selectBox-menuShowing-'+(posTop?'top':'bottom'));
  
          $(document).bind('mousedown.selectBox', function (event) {
              if (1 === event.which) {
                  if ($(event.target).parents().andSelf().hasClass('selectBox-options')) {
                      return;
                  }
                  self.hideMenus();
              }
          });
      };
  
      /**
       * Hides the menu of all instances.
       */
      SelectBox.prototype.hideMenus = function () {
          if ($(".selectBox-dropdown-menu:visible").length === 0) {
              return;
          }
  
          $(document).unbind('mousedown.selectBox');
          $(".selectBox-dropdown-menu").each(function () {
              var options = $(this)
                  , select = options.data('selectBox-select')
                  , control = select.data('selectBox-control')
                  , settings = select.data('selectBox-settings')
                  , posTop = options.data('posTop');
  
              if (select.triggerHandler('beforeclose')) {
                  return false;
              }
  
              var dispatchCloseEvent = function () {
                  select.triggerHandler('close', {
                      _selectBox: true
                  });
              };
              if (settings) {
                  switch (settings.menuTransition) {
                      case 'fade':
                          options.fadeOut(settings.menuSpeed, dispatchCloseEvent);
                          break;
                      case 'slide':
                          options.slideUp(settings.menuSpeed, dispatchCloseEvent);
                          break;
                      default:
                          options.hide(settings.menuSpeed, dispatchCloseEvent);
                          break;
                  }
                  if (!settings.menuSpeed) {
                      dispatchCloseEvent();
                  }
                  control.removeClass('selectBox-menuShowing selectBox-menuShowing-'+(posTop?'top':'bottom'));
              } else {
                  $(this).hide();
                  $(this).triggerHandler('close', {
                      _selectBox: true
                  });
                  $(this).removeClass('selectBox-menuShowing selectBox-menuShowing-'+(posTop?'top':'bottom'));
              }
              
              options.css('max-height','')
              //Remove Top or Bottom class based on position
              options.removeClass('selectBox-options-'+(posTop?'top':'bottom'));
              options.data('posTop' , false);
          });
      };
  
      /**
       * Selects an option.
       *
       * @param {HTMLElement} li
       * @param {DOMEvent}    event
       * @returns {Boolean}
       */
      SelectBox.prototype.selectOption = function (li, event) {
          var select = $(this.selectElement);
          li         = $(li);
  
          var control    = select.data('selectBox-control')
              , settings = select.data('selectBox-settings');
  
          if (control.hasClass('selectBox-disabled')) {
              return false;
          }
  
          if (0 === li.length || li.hasClass('selectBox-disabled')) {
              return false;
          }
  
          if (select.attr('multiple')) {
              // If event.shiftKey is true, this will select all options between li and the last li selected
              if (event.shiftKey && control.data('selectBox-last-selected')) {
                  li.toggleClass('selectBox-selected');
                  var affectedOptions;
                  if (li.index() > control.data('selectBox-last-selected').index()) {
                      affectedOptions = li
                          .siblings()
                          .slice(control.data('selectBox-last-selected').index(), li.index());
                  } else {
                      affectedOptions = li
                          .siblings()
                          .slice(li.index(), control.data('selectBox-last-selected').index());
                  }
                  affectedOptions = affectedOptions.not('.selectBox-optgroup, .selectBox-disabled');
                  if (li.hasClass('selectBox-selected')) {
                      affectedOptions.addClass('selectBox-selected');
                  } else {
                      affectedOptions.removeClass('selectBox-selected');
                  }
              } else if ((this.isMac && event.metaKey) || (!this.isMac && event.ctrlKey)) {
                  li.toggleClass('selectBox-selected');
              } else {
                  li.siblings().removeClass('selectBox-selected');
                  li.addClass('selectBox-selected');
              }
          } else {
              li.siblings().removeClass('selectBox-selected');
              li.addClass('selectBox-selected');
          }
  
          if (control.hasClass('selectBox-dropdown')) {
              control.find('.selectBox-label').text(li.text());
          }
  
          // Update original control's value
          var i = 0, selection = [];
          if (select.attr('multiple')) {
              control.find('.selectBox-selected A').each(function () {
                  selection[i++] = $(this).attr('rel');
              });
          } else {
              selection = li.find('A').attr('rel');
          }
  
          // Remember most recently selected item
          control.data('selectBox-last-selected', li);
  
          // Change callback
          if (select.val() !== selection) {
              select.val(selection);
              this.setLabel();
              select.trigger('change');
          }
  
          return true;
      };
  
      /**
       * Adds the hover class.
       *
       * @param {HTMLElement} li
       */
      SelectBox.prototype.addHover = function (li) {
          li = $(li);
          var select = $(this.selectElement)
              , control   = select.data('selectBox-control')
              , options = control.data('selectBox-options');
  
          options.find('.selectBox-hover').removeClass('selectBox-hover');
          li.addClass('selectBox-hover');
      };
  
      /**
       * Returns the original HTML select element.
       *
       * @returns {HTMLElement}
       */
      SelectBox.prototype.getSelectElement = function () {
          return this.selectElement;
      };
  
      /**
       * Remove the hover class.
       *
       * @param {HTMLElement} li
       */
      SelectBox.prototype.removeHover = function (li) {
          li = $(li);
          var select = $(this.selectElement)
              , control = select.data('selectBox-control')
              , options = control.data('selectBox-options');
  
          options.find('.selectBox-hover').removeClass('selectBox-hover');
      };
  
      /**
       * Checks if the widget is in the view.
       *
       * @param {jQuery}      li
       * @param {Boolean}     center
       */
      SelectBox.prototype.keepOptionInView = function (li, center) {
          if (!li || li.length === 0) {
              return;
          }
  
          var select = $(this.selectElement)
              , control     = select.data('selectBox-control')
              , options   = control.data('selectBox-options')
              , scrollBox = control.hasClass('selectBox-dropdown') ? options : options.parent()
              , top       = parseInt(li.offset().top -scrollBox.position().top)
              , bottom    = parseInt(top + li.outerHeight());
  
          if (center) {
              scrollBox.scrollTop(li.offset().top - scrollBox.offset().top + scrollBox.scrollTop() -
                  (scrollBox.height() / 2));
          } else {
              if (top < 0) {
                  scrollBox.scrollTop(li.offset().top - scrollBox.offset().top + scrollBox.scrollTop());
              }
              if (bottom > scrollBox.height()) {
                  scrollBox.scrollTop((li.offset().top + li.outerHeight()) - scrollBox.offset().top +
                      scrollBox.scrollTop() - scrollBox.height());
              }
          }
      };
  
      /**
       * Handles the keyDown event.
       * Handles open/close and arrow key functionality
       *
       * @param {DOMEvent}    event
       */
      SelectBox.prototype.handleKeyDown = function (event) {
          var select = $(this.selectElement)
              , control        = select.data('selectBox-control')
              , options      = control.data('selectBox-options')
              , settings     = select.data('selectBox-settings')
              , totalOptions = 0, i = 0;
  
          if (control.hasClass('selectBox-disabled')) {
              return;
          }
  
          switch (event.keyCode) {
              case 8:
                  // backspace
                  event.preventDefault();
                  this.typeSearch = '';
                  break;
              case 9:
              // tab
              case 27:
                  // esc
                  this.hideMenus();
                  this.removeHover();
                  break;
              case 13:
                  // enter
                  if (control.hasClass('selectBox-menuShowing')) {
                      this.selectOption(options.find('LI.selectBox-hover:first'), event);
                      if (control.hasClass('selectBox-dropdown')) {
                          this.hideMenus();
                      }
                  } else {
                      this.showMenu();
                  }
                  break;
              case 38:
              // up
              case 37:
                  // left
                  event.preventDefault();
                  if (control.hasClass('selectBox-menuShowing')) {
                      var prev = options.find('.selectBox-hover').prev('LI');
                      totalOptions = options.find('LI:not(.selectBox-optgroup)').length;
                      i = 0;
                      while (prev.length === 0 || prev.hasClass('selectBox-disabled') ||
                          prev.hasClass('selectBox-optgroup')) {
                          prev = prev.prev('LI');
                          if (prev.length === 0) {
                              if (settings.loopOptions) {
                                  prev = options.find('LI:last');
                              } else {
                                  prev = options.find('LI:first');
                              }
                          }
                          if (++i >= totalOptions) {
                              break;
                          }
                      }
                      this.addHover(prev);
                      this.selectOption(prev, event);
                      this.keepOptionInView(prev);
                  } else {
                      this.showMenu();
                  }
                  break;
              case 40:
              // down
              case 39:
                  // right
                  event.preventDefault();
                  if (control.hasClass('selectBox-menuShowing')) {
                      var next = options.find('.selectBox-hover').next('LI');
                      totalOptions = options.find('LI:not(.selectBox-optgroup)').length;
                      i = 0;
                      while (0 === next.length || next.hasClass('selectBox-disabled') ||
                          next.hasClass('selectBox-optgroup')) {
                          next = next.next('LI');
                          if (next.length === 0) {
                              if (settings.loopOptions) {
                                  next = options.find('LI:first');
                              } else {
                                  next = options.find('LI:last');
                              }
                          }
                          if (++i >= totalOptions) {
                              break;
                          }
                      }
                      this.addHover(next);
                      this.selectOption(next, event);
                      this.keepOptionInView(next);
                  } else {
                      this.showMenu();
                  }
                  break;
          }
      };
  
      /**
       * Handles the keyPress event.
       * Handles type-to-find functionality
       *
       * @param {DOMEvent}    event
       */
      SelectBox.prototype.handleKeyPress = function (event) {
          var select = $(this.selectElement)
              , control = select.data('selectBox-control')
              , options = control.data('selectBox-options')
              , self    = this;
  
          if (control.hasClass('selectBox-disabled')) {
              return;
          }
  
          switch (event.keyCode) {
              case 9:
              // tab
              case 27:
              // esc
              case 13:
              // enter
              case 38:
              // up
              case 37:
              // left
              case 40:
              // down
              case 39:
                  // right
                  // Don't interfere with the keydown event!
                  break;
              default:
                  // Type to find
                  if (!control.hasClass('selectBox-menuShowing')) {
                      this.showMenu();
                  }
                  event.preventDefault();
                  clearTimeout(this.typeTimer);
                  this.typeSearch += String.fromCharCode(event.charCode || event.keyCode);
                  options.find('A').each(function () {
                      if ($(this).text().substr(0, self.typeSearch.length).toLowerCase() === self.typeSearch.toLowerCase()) {
                          self.addHover($(this).parent());
                          self.selectOption($(this).parent(), event);
                          self.keepOptionInView($(this).parent());
                          return false;
                      }
                  });
                  // Clear after a brief pause
                  this.typeTimer = setTimeout(function () {
                      self.typeSearch = '';
                  }, 1000);
                  break;
          }
      };
  
      /**
       * Enables the selectBox.
       */
      SelectBox.prototype.enable = function () {
          var select = $(this.selectElement);
          select.prop('disabled', false);
          var control = select.data('selectBox-control');
          if (!control) {
              return;
          }
          control.removeClass('selectBox-disabled');
      };
  
      /**
       * Disables the selectBox.
       */
      SelectBox.prototype.disable = function () {
          var select = $(this.selectElement);
          select.prop('disabled', true);
          var control = select.data('selectBox-control');
          if (!control) {
              return;
          }
          control.addClass('selectBox-disabled');
      };
  
      /**
       * Sets the current value.
       *
       * @param {String}      value
       */
      SelectBox.prototype.setValue = function (value) {
          var select = $(this.selectElement);
          select.val(value);
          value = select.val(); // IE9's select would be null if it was set with a non-exist options value
  
          if (null === value) { // So check it here and set it with the first option's value if possible
              value = select.children().first().val();
              select.val(value);
          }
  
          var control = select.data('selectBox-control');
          if (!control) {
              return;
          }
  
          var settings = select.data('selectBox-settings')
              , options = control.data('selectBox-options');
  
          // Update label
          this.setLabel();
  
          // Update control values
          options.find('.selectBox-selected').removeClass('selectBox-selected');
          options.find('A').each(function () {
              if (typeof(value) === 'object') {
                  for (var i = 0; i < value.length; i++) {
                      if ($(this).attr('rel') == value[i]) {
                          $(this).parent().addClass('selectBox-selected');
                      }
                  }
              } else {
                  if ($(this).attr('rel') == value) {
                      $(this).parent().addClass('selectBox-selected');
                  }
              }
          });
  
          if (settings.change) {
              settings.change.call(select);
          }
      };
  
      /**
       * Sets the option elements.
       *
       * @param {String|Object} options
       */
      SelectBox.prototype.setOptions = function (options) {
          var select = $(this.selectElement)
              , control = select.data('selectBox-control');
  
          switch (typeof(options)) {
              case 'string':
                  select.html(options);
                  break;
              case 'object':
                  select.html('');
                  for (var i in options) {
                      if (options[i] === null) {
                          continue;
                      }
                      if (typeof(options[i]) === 'object') {
                          var optgroup = $('<optgroup label="' + i + '" />');
                          for (var j in options[i]) {
                              optgroup.append('<option value="' + j + '">' + options[i][j] + '</option>');
                          }
                          select.append(optgroup);
                      } else {
                          var option = $('<option value="' + i + '">' + options[i] + '</option>');
                          select.append(option);
                      }
                  }
                  break;
          }
  
          if (control) {
              // Refresh the control
              this.refresh();
          }
      };
  
      /**
       * Disables the selection.
       *
       * @param {*} selector
       */
      SelectBox.prototype.disableSelection = function (selector) {
          $(selector).css('MozUserSelect', 'none').bind('selectstart', function (event) {
              event.preventDefault();
          });
      };
  
      /**
       * Generates the options.
       *
       * @param {jQuery} self
       * @param {jQuery} options
       */
      SelectBox.prototype.generateOptions = function (self, options) {
          var li = $('<li />'), a = $('<a />');
          li.addClass(self.attr('class'));
          li.data(self.data());
          a.attr('rel', self.val()).text(self.text());
          li.append(a);
          if (self.attr('disabled')) {
              li.addClass('selectBox-disabled');
          }
          if (self.attr('selected')) {
              li.addClass('selectBox-selected');
          }
          options.append(li);
      };
  
      /**
       * Extends the jQuery.fn object.
       */
      $.extend($.fn, {
          selectBox: function (method, options) {
              var selectBox;
  
              switch (method) {
                  case 'control':
                      return $(this).data('selectBox-control');
                  case 'settings':
                      if (!options) {
                          return $(this).data('selectBox-settings');
                      }
                      $(this).each(function () {
                          $(this).data('selectBox-settings', $.extend(true, $(this).data('selectBox-settings'), options));
                      });
                      break;
                  case 'options':
                      // Getter
                      if (undefined === options) {
                          return $(this).data('selectBox-control').data('selectBox-options');
                      }
                      // Setter
                      $(this).each(function () {
                          if (selectBox = $(this).data('selectBox')) {
                              selectBox.setOptions(options);
                          }
                      });
                      break;
                  case 'value':
                      // Empty string is a valid value
                      if (undefined === options) {
                          return $(this).val();
                      }
                      $(this).each(function () {
                          if (selectBox = $(this).data('selectBox')) {
                              selectBox.setValue(options);
                          }
                      });
                      break;
                  case 'refresh':
                      $(this).each(function () {
                          if (selectBox = $(this).data('selectBox')) {
                              selectBox.refresh();
                          }
                      });
                      break;
                  case 'enable':
                      $(this).each(function () {
                          if (selectBox = $(this).data('selectBox')) {
                              selectBox.enable(this);
                          }
                      });
                      break;
                  case 'disable':
                      $(this).each(function () {
                          if (selectBox = $(this).data('selectBox')) {
                              selectBox.disable();
                          }
                      });
                      break;
                  case 'destroy':
                      $(this).each(function () {
                          if (selectBox = $(this).data('selectBox')) {
                              selectBox.destroy();
                              $(this).data('selectBox', null);
                          }
                      });
                      break;
                  case 'instance':
                      return $(this).data('selectBox');
                  default:
                      $(this).each(function (idx, select) {
                          if (!$(select).data('selectBox')) {
                              $(select).data('selectBox', new SelectBox(select, method));
                          }
                      });
                      break;
              }
              return $(this);
          }
      });
  })(jQuery);