function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
/*
 * jQuery Tooltip plugin 1.3
 *
 * http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
 * http://docs.jquery.com/Plugins/Tooltip
 *
 * Copyright (c) 2006 - 2008 Jörn Zaefferer
 *
 * $Id: jquery.tooltip.js 5741 2008-06-21 15:22:16Z joern.zaefferer $
 * 
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */

;
(function ($) {
  // the tooltip element
  var helper = {},
    // the current tooltipped element
    current,
    // the title of the current element, used for restoring
    title,
    // timeout id for delayed tooltips
    tID,
    // IE 5.5 or 6
    IE = false,
    // flag for mouse tracking
    track = false;
  $.tooltip = {
    blocked: false,
    defaults: {
      delay: 200,
      fade: false,
      showURL: true,
      extraClass: "",
      top: 15,
      left: 15,
      id: "tooltip"
    },
    block: function block() {
      $.tooltip.blocked = !$.tooltip.blocked;
    }
  };
  $.fn.extend({
    tooltip: function tooltip(settings) {
      settings = $.extend({}, $.tooltip.defaults, settings);
      createHelper(settings);
      return this.each(function () {
        $.data(this, "tooltip", settings);
        this.tOpacity = helper.parent.css("opacity");
        // copy tooltip into its own expando and remove the title
        this.tooltipText = this.title;
        $(this).removeAttr("title");
        // also remove alt attribute to prevent default tooltip in IE
        this.alt = "";
      }).mouseover(save).mouseout(hide).click(hide);
    },
    fixPNG: IE ? function () {
      return this.each(function () {
        var image = $(this).css('backgroundImage');
        if (image.match(/^url\(["']?(.*\.png)["']?\)$/i)) {
          image = RegExp.$1;
          $(this).css({
            'backgroundImage': 'none',
            'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
          }).each(function () {
            var position = $(this).css('position');
            if (position != 'absolute' && position != 'relative') $(this).css('position', 'relative');
          });
        }
      });
    } : function () {
      return this;
    },
    unfixPNG: IE ? function () {
      return this.each(function () {
        $(this).css({
          'filter': '',
          backgroundImage: ''
        });
      });
    } : function () {
      return this;
    },
    hideWhenEmpty: function hideWhenEmpty() {
      return this.each(function () {
        $(this)[$(this).html() ? "show" : "hide"]();
      });
    },
    url: function url() {
      return this.attr('href') || this.attr('src');
    }
  });
  function createHelper(settings) {
    // there can be only one tooltip helper
    if (helper.parent) return;
    // create the helper, h3 for title, div for url
    helper.parent = $('<div id="' + settings.id + '"><h3></h3><div class="body"></div><div class="url"></div></div>')
    // add to document
    .appendTo(document.body)
    // hide it at first
    .hide();

    // apply bgiframe if available
    if ($.fn.bgiframe) helper.parent.bgiframe();

    // save references to title and url elements
    helper.title = $('h3', helper.parent);
    helper.body = $('div.body', helper.parent);
    helper.url = $('div.url', helper.parent);
  }
  function settings(element) {
    return $.data(element, "tooltip");
  }

  // main event handler to start showing tooltips
  function handle(event) {
    // show helper, either with timeout or on instant
    if (settings(this).delay) tID = setTimeout(show, settings(this).delay);else show();

    // if selected, update the helper position when the mouse moves
    track = !!settings(this).track;
    $(document.body).bind('mousemove', update);

    // update at least once
    update(event);
  }

  // save elements title before the tooltip is displayed
  function save() {
    // if this is the current source, or it has no title (occurs with click event), stop
    if ($.tooltip.blocked || this == current || !this.tooltipText && !settings(this).bodyHandler) return;

    // save current
    current = this;
    title = this.tooltipText;
    if (settings(this).bodyHandler) {
      helper.title.hide();
      var bodyContent = settings(this).bodyHandler.call(this);
      if (bodyContent.nodeType || bodyContent.jquery) {
        helper.body.empty().append(bodyContent);
      } else {
        helper.body.html(bodyContent);
      }
      helper.body.show();
    } else if (settings(this).showBody) {
      var parts = title.split(settings(this).showBody);
      helper.title.html(parts.shift()).show();
      helper.body.empty();
      for (var i = 0, part; part = parts[i]; i++) {
        if (i > 0) helper.body.append("<br/>");
        helper.body.append(part);
      }
      helper.body.hideWhenEmpty();
    } else {
      helper.title.html(title).show();
      helper.body.hide();
    }

    // if element has href or src, add and show it, otherwise hide it
    if (settings(this).showURL && $(this).url()) helper.url.html($(this).url().replace('http://', '')).show();else helper.url.hide();

    // add an optional class for this tip
    helper.parent.addClass(settings(this).extraClass);

    // fix PNG background for IE
    if (settings(this).fixPNG) helper.parent.fixPNG();
    handle.apply(this, arguments);
  }

  // delete timeout and show helper
  function show() {
    tID = null;
    if ((!IE || !$.fn.bgiframe) && settings(current).fade) {
      if (helper.parent.is(":animated")) helper.parent.stop().show().fadeTo(settings(current).fade, current.tOpacity);else helper.parent.is(':visible') ? helper.parent.fadeTo(settings(current).fade, current.tOpacity) : helper.parent.fadeIn(settings(current).fade);
    } else {
      helper.parent.show();
    }
    update();
  }

  /**
   * callback for mousemove
   * updates the helper position
   * removes itself when no current element
   */
  function update(event) {
    if ($.tooltip.blocked) return;
    if (event && event.target.tagName == "OPTION") {
      return;
    }

    // stop updating when tracking is disabled and the tooltip is visible
    if (!track && helper.parent.is(":visible")) {
      $(document.body).unbind('mousemove', update);
    }

    // if no current element is available, remove this listener
    if (current == null) {
      $(document.body).unbind('mousemove', update);
      return;
    }

    // remove position helper classes
    helper.parent.removeClass("viewport-right").removeClass("viewport-bottom");
    var left = helper.parent[0].offsetLeft;
    var top = helper.parent[0].offsetTop;
    if (event) {
      // position the helper 15 pixel to bottom right, starting from mouse position
      left = event.pageX + settings(current).left;
      top = event.pageY + settings(current).top;
      var right = 'auto';
      if (settings(current).positionLeft) {
        right = $(window).width() - left;
        left = 'auto';
      }
      helper.parent.css({
        left: left,
        right: right,
        top: top
      });
    }
    var v = viewport(),
      h = helper.parent[0];
    // check horizontal position
    if (v.x + v.cx < h.offsetLeft + h.offsetWidth) {
      left -= h.offsetWidth + 20 + settings(current).left;
      helper.parent.css({
        left: left + 'px'
      }).addClass("viewport-right");
    }
    // check vertical position
    if (v.y + v.cy < h.offsetTop + h.offsetHeight) {
      top -= h.offsetHeight + 20 + settings(current).top;
      helper.parent.css({
        top: top + 'px'
      }).addClass("viewport-bottom");
    }
  }
  function viewport() {
    return {
      x: $(window).scrollLeft(),
      y: $(window).scrollTop(),
      cx: $(window).width(),
      cy: $(window).height()
    };
  }

  // hide helper and restore added classes and the title
  function hide(event) {
    if ($.tooltip.blocked) return;
    // clear timeout if possible
    if (tID) clearTimeout(tID);
    // no more current element
    current = null;
    var tsettings = settings(this);
    function complete() {
      helper.parent.removeClass(tsettings.extraClass).hide().css("opacity", "");
    }
    if ((!IE || !$.fn.bgiframe) && tsettings.fade) {
      if (helper.parent.is(':animated')) helper.parent.stop().fadeTo(tsettings.fade, 0, complete);else helper.parent.stop().fadeOut(tsettings.fade, complete);
    } else complete();
    if (settings(this).fixPNG) helper.parent.unfixPNG();
  }
})(jQuery);
var backupbuddy_destinations_advanced_toggle;
jQuery(function ($) {
  $('.backupbuddy-do_bulk_action').on('click', function () {
    var items = $('input[type="checkbox"][name^="items["]').length;
    if (items) {
      if (!$('input[type="checkbox"][name^="items["]:checked').length) {
        alert('Select some items first.');
        return false;
      }
    }
    return confirm('Are you sure you want to do this to all selected items?');
  });
  $('.pb_debug_show').on('click', function (e) {
    var $btn = $(this),
      $parent = $btn.parent();
    $btn.hide();
    $parent.children('.pb_debug_hide').show();
    $parent.css('float', 'left');
    $parent.css('width', '80%');
    $parent.children('div').show();
  });
  $('.pb_debug_hide').on('click', function (e) {
    var $btn = $(this),
      $parent = $btn.parent();
    $btn.hide();
    $parent.children('.pb_debug_show').show();
    $parent.css('float', 'right');
    $parent.css('width', '40px');
    $parent.children('div').hide();
  });
  backupbuddy_destinations_advanced_toggle = function backupbuddy_destinations_advanced_toggle() {
    $('.advanced-toggle-title').on('click', function (e) {
      e.preventDefault();
      var $containerWrap = $(this).closest('form'),
        $titleToggle = $containerWrap.find('.advanced-toggle-title');
      if ($titleToggle.hasClass('advanced-toggle-open')) {
        $containerWrap.find('.advanced-toggle').addClass('advanced-toggle-hidden');
        $titleToggle.removeClass('advanced-toggle-open');
      } else {
        $containerWrap.find('.advanced-toggle').removeClass('advanced-toggle-hidden');
        $titleToggle.addClass('advanced-toggle-open');
      }
    });
  };
  backupbuddy_destinations_advanced_toggle();
  if ('undefined' !== typeof $.tableDnD) {
    // If tableDnD function loaded.
    $('.pb_reorder').tableDnD({
      onDrop: function onDrop(tbody, row) {
        var new_order = new Array(),
          rows = tbody.rows;
        for (var i = 0; i < rows.length; i++) {
          new_order.push(rows[i].id.substring(11));
        }
        new_order = new_order.join(',');
        $('#pb_order').val(new_order);
      },
      dragHandle: "pb_draghandle"
    });
  }
  $('.pb_toggle').on('click', function (e) {
    $('#pb_toggle-' + $(this).attr('id')).slideToggle();
  });
  $('.itbub-edits-summary .itbub-summary-item').on('click', function (e) {
    var $el = $(this);
    $el.toggleClass('itbub-active');
    $('#' + $el.attr('rel')).toggleClass('itbub-active');
  });
});
jQuery(document).ready(function () {
  // Change tab on click.
  jQuery('.backupbuddy-tabs-wrap .nav-tab[href^="#"]').click(function (e) {
    /* ignores any non hashtag links since they go direct to a URL... */
    e.preventDefault();

    // Hide all tab blocks.
    thisTabBlock = jQuery(this).closest('.backupbuddy-tabs-wrap');
    thisTabBlock.find('.backupbuddy-tab').hide();

    // Update selected tab.
    thisTabBlock.find('.nav-tab-active').removeClass('nav-tab-active');
    jQuery(this).addClass('nav-tab-active');

    // Show the correct tab block.
    //targetDivID = jQuery(this).attr( 'href' ).substring(1);
    thisTabBlock.find(jQuery(this).attr('href')).show();
  });

  // Change tab on click -- AJAX version.
  jQuery('.backupbuddy-tabs-wrap .nav-tab[href^="javascript"]').click(function (e) {
    /* ignores any non hashtag links since they go direct to a URL... */
    // Hide all tab blocks.
    thisTabBlock = jQuery(this).closest('.backupbuddy-tabs-wrap');
    thisTabBlock.find('.backupbuddy-tab').hide();

    // Update selected tab.
    thisTabBlock.find('.nav-tab-active').removeClass('nav-tab-active');
    jQuery(this).addClass('nav-tab-active');

    // Show the correct tab block.
    //targetDivID = jQuery(this).attr( 'href' ).substring(1);
    thisTabBlock.find(jQuery(this).attr('data-ajax')).show();
  });

  // Auto-display the correct tab on load if specifying a non-default.
  jQuery('.nav-tab-active').each(function () {
    jQuery(this).click();
  });
});
//
// jQuery MiniColors: A tiny color picker built on jQuery
//
// Developed by Cory LaViska for A Beautiful Site, LLC
//
// Licensed under the MIT license: http://opensource.org/licenses/MIT
//
(function (factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(['jquery'], factory);
  } else if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === 'object') {
    // Node/CommonJS
    module.exports = factory(require('jquery'));
  } else {
    // Browser globals
    factory(jQuery);
  }
})(function ($) {
  'use strict';

  // Defaults
  $.minicolors = {
    defaults: {
      animationSpeed: 50,
      animationEasing: 'swing',
      change: null,
      changeDelay: 0,
      control: 'hue',
      defaultValue: '',
      format: 'hex',
      hide: null,
      hideSpeed: 100,
      inline: false,
      keywords: '',
      letterCase: 'lowercase',
      opacity: false,
      position: 'bottom',
      show: null,
      showSpeed: 100,
      theme: 'default',
      swatches: []
    }
  };

  // Public methods
  $.extend($.fn, {
    minicolors: function minicolors(method, data) {
      switch (method) {
        // Destroy the control
        case 'destroy':
          $(this).each(function () {
            destroy($(this));
          });
          return $(this);

        // Hide the color picker
        case 'hide':
          hide();
          return $(this);

        // Get/set opacity
        case 'opacity':
          // Getter
          if (data === undefined) {
            // Getter
            return $(this).attr('data-opacity');
          } else {
            // Setter
            $(this).each(function () {
              updateFromInput($(this).attr('data-opacity', data));
            });
          }
          return $(this);

        // Get an RGB(A) object based on the current color/opacity
        case 'rgbObject':
          return rgbObject($(this), method === 'rgbaObject');

        // Get an RGB(A) string based on the current color/opacity
        case 'rgbString':
        case 'rgbaString':
          return rgbString($(this), method === 'rgbaString');

        // Get/set settings on the fly
        case 'settings':
          if (data === undefined) {
            return $(this).data('minicolors-settings');
          } else {
            // Setter
            $(this).each(function () {
              var settings = $(this).data('minicolors-settings') || {};
              destroy($(this));
              $(this).minicolors($.extend(true, settings, data));
            });
          }
          return $(this);

        // Show the color picker
        case 'show':
          show($(this).eq(0));
          return $(this);

        // Get/set the hex color value
        case 'value':
          if (data === undefined) {
            // Getter
            return $(this).val();
          } else {
            // Setter
            $(this).each(function () {
              if (_typeof(data) === 'object' && data !== null) {
                if (data.opacity !== undefined) {
                  $(this).attr('data-opacity', keepWithin(data.opacity, 0, 1));
                }
                if (data.color) {
                  $(this).val(data.color);
                }
              } else {
                $(this).val(data);
              }
              updateFromInput($(this));
            });
          }
          return $(this);

        // Initializes the control
        default:
          if (method !== 'create') data = method;
          $(this).each(function () {
            init($(this), data);
          });
          return $(this);
      }
    }
  });

  // Initialize input elements
  function init(input, settings) {
    var minicolors = $('<div class="minicolors" />');
    var defaults = $.minicolors.defaults;
    var name;
    var size;
    var swatches;
    var swatch;
    var swatchString;
    var panel;
    var i;

    // Do nothing if already initialized
    if (input.data('minicolors-initialized')) return;

    // Handle settings
    settings = $.extend(true, {}, defaults, settings);

    // The wrapper
    minicolors.addClass('minicolors-theme-' + settings.theme).toggleClass('minicolors-with-opacity', settings.opacity);

    // Custom positioning
    if (settings.position !== undefined) {
      $.each(settings.position.split(' '), function () {
        minicolors.addClass('minicolors-position-' + this);
      });
    }

    // Input size
    if (settings.format === 'rgb') {
      size = settings.opacity ? '25' : '20';
    } else {
      size = settings.keywords ? '11' : '7';
    }

    // The input
    input.addClass('minicolors-input').data('minicolors-initialized', false).data('minicolors-settings', settings).prop('size', size).wrap(minicolors).after('<div class="minicolors-panel minicolors-slider-' + settings.control + '">' + '<div class="minicolors-slider minicolors-sprite">' + '<div class="minicolors-picker"></div>' + '</div>' + '<div class="minicolors-opacity-slider minicolors-sprite">' + '<div class="minicolors-picker"></div>' + '</div>' + '<div class="minicolors-grid minicolors-sprite">' + '<div class="minicolors-grid-inner"></div>' + '<div class="minicolors-picker"><div></div></div>' + '</div>' + '</div>');

    // The swatch
    if (!settings.inline) {
      input.after('<span class="minicolors-swatch minicolors-sprite minicolors-input-swatch"><span class="minicolors-swatch-color"></span></span>');
      input.next('.minicolors-input-swatch').on('click', function (event) {
        event.preventDefault();
        input.trigger('focus');
      });
    }

    // Prevent text selection in IE
    panel = input.parent().find('.minicolors-panel');
    panel.on('selectstart', function () {
      return false;
    }).end();

    // Swatches
    if (settings.swatches && settings.swatches.length !== 0) {
      panel.addClass('minicolors-with-swatches');
      swatches = $('<ul class="minicolors-swatches"></ul>').appendTo(panel);
      for (i = 0; i < settings.swatches.length; ++i) {
        // allow for custom objects as swatches
        if (_typeof(settings.swatches[i]) === 'object') {
          name = settings.swatches[i].name;
          swatch = settings.swatches[i].color;
        } else {
          name = '';
          swatch = settings.swatches[i];
        }
        swatchString = swatch;
        swatch = isRgb(swatch) ? parseRgb(swatch, true) : hex2rgb(parseHex(swatch, true));
        $('<li class="minicolors-swatch minicolors-sprite"><span class="minicolors-swatch-color"></span></li>').attr("title", name).appendTo(swatches).data('swatch-color', swatchString).find('.minicolors-swatch-color').css({
          backgroundColor: swatchString !== 'transparent' ? rgb2hex(swatch) : 'transparent',
          opacity: String(swatch.a)
        });
        settings.swatches[i] = swatch;
      }
    }

    // Inline controls
    if (settings.inline) input.parent().addClass('minicolors-inline');
    updateFromInput(input, false);
    input.data('minicolors-initialized', true);
  }

  // Returns the input back to its original state
  function destroy(input) {
    var minicolors = input.parent();

    // Revert the input element
    input.removeData('minicolors-initialized').removeData('minicolors-settings').removeProp('size').removeClass('minicolors-input');

    // Remove the wrap and destroy whatever remains
    minicolors.before(input).remove();
  }

  // Shows the specified dropdown panel
  function show(input) {
    var minicolors = input.parent();
    var panel = minicolors.find('.minicolors-panel');
    var settings = input.data('minicolors-settings');

    // Do nothing if uninitialized, disabled, inline, or already open
    if (!input.data('minicolors-initialized') || input.prop('disabled') || minicolors.hasClass('minicolors-inline') || minicolors.hasClass('minicolors-focus')) return;
    hide();
    minicolors.addClass('minicolors-focus');
    if (panel.animate) {
      panel.stop(true, true).fadeIn(settings.showSpeed, function () {
        if (settings.show) settings.show.call(input.get(0));
      });
    } else {
      panel.show();
      if (settings.show) settings.show.call(input.get(0));
    }
  }

  // Hides all dropdown panels
  function hide() {
    $('.minicolors-focus').each(function () {
      var minicolors = $(this);
      var input = minicolors.find('.minicolors-input');
      var panel = minicolors.find('.minicolors-panel');
      var settings = input.data('minicolors-settings');
      if (panel.animate) {
        panel.fadeOut(settings.hideSpeed, function () {
          if (settings.hide) settings.hide.call(input.get(0));
          minicolors.removeClass('minicolors-focus');
        });
      } else {
        panel.hide();
        if (settings.hide) settings.hide.call(input.get(0));
        minicolors.removeClass('minicolors-focus');
      }
    });
  }

  // Moves the selected picker
  function move(target, event, animate) {
    var input = target.parents('.minicolors').find('.minicolors-input');
    var settings = input.data('minicolors-settings');
    var picker = target.find('[class$=-picker]');
    var offsetX = target.offset().left;
    var offsetY = target.offset().top;
    var x = Math.round(event.pageX - offsetX);
    var y = Math.round(event.pageY - offsetY);
    var duration = animate ? settings.animationSpeed : 0;
    var wx, wy, r, phi, styles;

    // Touch support
    if (event.originalEvent.changedTouches) {
      x = event.originalEvent.changedTouches[0].pageX - offsetX;
      y = event.originalEvent.changedTouches[0].pageY - offsetY;
    }

    // Constrain picker to its container
    if (x < 0) x = 0;
    if (y < 0) y = 0;
    if (x > target.width()) x = target.width();
    if (y > target.height()) y = target.height();

    // Constrain color wheel values to the wheel
    if (target.parent().is('.minicolors-slider-wheel') && picker.parent().is('.minicolors-grid')) {
      wx = 75 - x;
      wy = 75 - y;
      r = Math.sqrt(wx * wx + wy * wy);
      phi = Math.atan2(wy, wx);
      if (phi < 0) phi += Math.PI * 2;
      if (r > 75) {
        r = 75;
        x = 75 - 75 * Math.cos(phi);
        y = 75 - 75 * Math.sin(phi);
      }
      x = Math.round(x);
      y = Math.round(y);
    }

    // Move the picker
    styles = {
      top: y + 'px'
    };
    if (target.is('.minicolors-grid')) {
      styles.left = x + 'px';
    }
    if (picker.animate) {
      picker.stop(true).animate(styles, duration, settings.animationEasing, function () {
        updateFromControl(input, target);
      });
    } else {
      picker.css(styles);
      updateFromControl(input, target);
    }
  }

  // Sets the input based on the color picker values
  function updateFromControl(input, target) {
    function getCoords(picker, container) {
      var left, top;
      if (!picker.length || !container) return null;
      left = picker.offset().left;
      top = picker.offset().top;
      return {
        x: left - container.offset().left + picker.outerWidth() / 2,
        y: top - container.offset().top + picker.outerHeight() / 2
      };
    }
    var hue, saturation, brightness, x, y, r, phi;
    var hex = input.val();
    var opacity = input.attr('data-opacity');

    // Helpful references
    var minicolors = input.parent();
    var settings = input.data('minicolors-settings');
    var swatch = minicolors.find('.minicolors-input-swatch');

    // Panel objects
    var grid = minicolors.find('.minicolors-grid');
    var slider = minicolors.find('.minicolors-slider');
    var opacitySlider = minicolors.find('.minicolors-opacity-slider');

    // Picker objects
    var gridPicker = grid.find('[class$=-picker]');
    var sliderPicker = slider.find('[class$=-picker]');
    var opacityPicker = opacitySlider.find('[class$=-picker]');

    // Picker positions
    var gridPos = getCoords(gridPicker, grid);
    var sliderPos = getCoords(sliderPicker, slider);
    var opacityPos = getCoords(opacityPicker, opacitySlider);

    // Handle colors
    if (target.is('.minicolors-grid, .minicolors-slider, .minicolors-opacity-slider')) {
      // Determine HSB values
      switch (settings.control) {
        case 'wheel':
          // Calculate hue, saturation, and brightness
          x = grid.width() / 2 - gridPos.x;
          y = grid.height() / 2 - gridPos.y;
          r = Math.sqrt(x * x + y * y);
          phi = Math.atan2(y, x);
          if (phi < 0) phi += Math.PI * 2;
          if (r > 75) {
            r = 75;
            gridPos.x = 69 - 75 * Math.cos(phi);
            gridPos.y = 69 - 75 * Math.sin(phi);
          }
          saturation = keepWithin(r / 0.75, 0, 100);
          hue = keepWithin(phi * 180 / Math.PI, 0, 360);
          brightness = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100);
          hex = hsb2hex({
            h: hue,
            s: saturation,
            b: brightness
          });

          // Update UI
          slider.css('backgroundColor', hsb2hex({
            h: hue,
            s: saturation,
            b: 100
          }));
          break;
        case 'saturation':
          // Calculate hue, saturation, and brightness
          hue = keepWithin(parseInt(gridPos.x * (360 / grid.width()), 10), 0, 360);
          saturation = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100);
          brightness = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100);
          hex = hsb2hex({
            h: hue,
            s: saturation,
            b: brightness
          });

          // Update UI
          slider.css('backgroundColor', hsb2hex({
            h: hue,
            s: 100,
            b: brightness
          }));
          minicolors.find('.minicolors-grid-inner').css('opacity', saturation / 100);
          break;
        case 'brightness':
          // Calculate hue, saturation, and brightness
          hue = keepWithin(parseInt(gridPos.x * (360 / grid.width()), 10), 0, 360);
          saturation = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100);
          brightness = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100);
          hex = hsb2hex({
            h: hue,
            s: saturation,
            b: brightness
          });

          // Update UI
          slider.css('backgroundColor', hsb2hex({
            h: hue,
            s: saturation,
            b: 100
          }));
          minicolors.find('.minicolors-grid-inner').css('opacity', 1 - brightness / 100);
          break;
        default:
          // Calculate hue, saturation, and brightness
          hue = keepWithin(360 - parseInt(sliderPos.y * (360 / slider.height()), 10), 0, 360);
          saturation = keepWithin(Math.floor(gridPos.x * (100 / grid.width())), 0, 100);
          brightness = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100);
          hex = hsb2hex({
            h: hue,
            s: saturation,
            b: brightness
          });

          // Update UI
          grid.css('backgroundColor', hsb2hex({
            h: hue,
            s: 100,
            b: 100
          }));
          break;
      }

      // Handle opacity
      if (settings.opacity) {
        opacity = parseFloat(1 - opacityPos.y / opacitySlider.height()).toFixed(2);
      } else {
        opacity = 1;
      }
      updateInput(input, hex, opacity);
    } else {
      // Set swatch color
      swatch.find('span').css({
        backgroundColor: hex,
        opacity: String(opacity)
      });

      // Handle change event
      doChange(input, hex, opacity);
    }
  }

  // Sets the value of the input and does the appropriate conversions
  // to respect settings, also updates the swatch
  function updateInput(input, value, opacity) {
    var rgb;

    // Helpful references
    var minicolors = input.parent();
    var settings = input.data('minicolors-settings');
    var swatch = minicolors.find('.minicolors-input-swatch');
    if (settings.opacity) input.attr('data-opacity', opacity);

    // Set color string
    if (settings.format === 'rgb') {
      // Returns RGB(A) string

      // Checks for input format and does the conversion
      if (isRgb(value)) {
        rgb = parseRgb(value, true);
      } else {
        rgb = hex2rgb(parseHex(value, true));
      }
      opacity = input.attr('data-opacity') === '' ? 1 : keepWithin(parseFloat(input.attr('data-opacity')).toFixed(2), 0, 1);
      if (isNaN(opacity) || !settings.opacity) opacity = 1;
      if (input.minicolors('rgbObject').a <= 1 && rgb && settings.opacity) {
        // Set RGBA string if alpha
        value = 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + parseFloat(opacity) + ')';
      } else {
        // Set RGB string (alpha = 1)
        value = 'rgb(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ')';
      }
    } else {
      // Returns hex color

      // Checks for input format and does the conversion
      if (isRgb(value)) {
        value = rgbString2hex(value);
      }
      value = convertCase(value, settings.letterCase);
    }

    // Update value from picker
    input.val(value);

    // Set swatch color
    swatch.find('span').css({
      backgroundColor: value,
      opacity: String(opacity)
    });

    // Handle change event
    doChange(input, value, opacity);
  }

  // Sets the color picker values from the input
  function updateFromInput(input, preserveInputValue) {
    var hex, hsb, opacity, keywords, alpha, value, x, y, r, phi;

    // Helpful references
    var minicolors = input.parent();
    var settings = input.data('minicolors-settings');
    var swatch = minicolors.find('.minicolors-input-swatch');

    // Panel objects
    var grid = minicolors.find('.minicolors-grid');
    var slider = minicolors.find('.minicolors-slider');
    var opacitySlider = minicolors.find('.minicolors-opacity-slider');

    // Picker objects
    var gridPicker = grid.find('[class$=-picker]');
    var sliderPicker = slider.find('[class$=-picker]');
    var opacityPicker = opacitySlider.find('[class$=-picker]');

    // Determine hex/HSB values
    if (isRgb(input.val())) {
      // If input value is a rgb(a) string, convert it to hex color and update opacity
      hex = rgbString2hex(input.val());
      alpha = keepWithin(parseFloat(getAlpha(input.val())).toFixed(2), 0, 1);
      if (alpha) {
        input.attr('data-opacity', alpha);
      }
    } else {
      hex = convertCase(parseHex(input.val(), true), settings.letterCase);
    }
    if (!hex) {
      hex = convertCase(parseInput(settings.defaultValue, true), settings.letterCase);
    }
    hsb = hex2hsb(hex);

    // Get array of lowercase keywords
    keywords = !settings.keywords ? [] : $.map(settings.keywords.split(','), function (a) {
      return a.toLowerCase().trim();
    });

    // Set color string
    if (input.val() !== '' && $.inArray(input.val().toLowerCase(), keywords) > -1) {
      value = convertCase(input.val());
    } else {
      value = isRgb(input.val()) ? parseRgb(input.val()) : hex;
    }

    // Update input value
    if (!preserveInputValue) input.val(value);

    // Determine opacity value
    if (settings.opacity) {
      // Get from data-opacity attribute and keep within 0-1 range
      opacity = input.attr('data-opacity') === '' ? 1 : keepWithin(parseFloat(input.attr('data-opacity')).toFixed(2), 0, 1);
      if (isNaN(opacity)) opacity = 1;
      input.attr('data-opacity', opacity);
      swatch.find('span').css('opacity', String(opacity));

      // Set opacity picker position
      y = keepWithin(opacitySlider.height() - opacitySlider.height() * opacity, 0, opacitySlider.height());
      opacityPicker.css('top', y + 'px');
    }

    // Set opacity to zero if input value is transparent
    if (input.val().toLowerCase() === 'transparent') {
      swatch.find('span').css('opacity', String(0));
    }

    // Update swatch
    swatch.find('span').css('backgroundColor', hex);

    // Determine picker locations
    switch (settings.control) {
      case 'wheel':
        // Set grid position
        r = keepWithin(Math.ceil(hsb.s * 0.75), 0, grid.height() / 2);
        phi = hsb.h * Math.PI / 180;
        x = keepWithin(75 - Math.cos(phi) * r, 0, grid.width());
        y = keepWithin(75 - Math.sin(phi) * r, 0, grid.height());
        gridPicker.css({
          top: y + 'px',
          left: x + 'px'
        });

        // Set slider position
        y = 150 - hsb.b / (100 / grid.height());
        if (hex === '') y = 0;
        sliderPicker.css('top', y + 'px');

        // Update panel color
        slider.css('backgroundColor', hsb2hex({
          h: hsb.h,
          s: hsb.s,
          b: 100
        }));
        break;
      case 'saturation':
        // Set grid position
        x = keepWithin(5 * hsb.h / 12, 0, 150);
        y = keepWithin(grid.height() - Math.ceil(hsb.b / (100 / grid.height())), 0, grid.height());
        gridPicker.css({
          top: y + 'px',
          left: x + 'px'
        });

        // Set slider position
        y = keepWithin(slider.height() - hsb.s * (slider.height() / 100), 0, slider.height());
        sliderPicker.css('top', y + 'px');

        // Update UI
        slider.css('backgroundColor', hsb2hex({
          h: hsb.h,
          s: 100,
          b: hsb.b
        }));
        minicolors.find('.minicolors-grid-inner').css('opacity', hsb.s / 100);
        break;
      case 'brightness':
        // Set grid position
        x = keepWithin(5 * hsb.h / 12, 0, 150);
        y = keepWithin(grid.height() - Math.ceil(hsb.s / (100 / grid.height())), 0, grid.height());
        gridPicker.css({
          top: y + 'px',
          left: x + 'px'
        });

        // Set slider position
        y = keepWithin(slider.height() - hsb.b * (slider.height() / 100), 0, slider.height());
        sliderPicker.css('top', y + 'px');

        // Update UI
        slider.css('backgroundColor', hsb2hex({
          h: hsb.h,
          s: hsb.s,
          b: 100
        }));
        minicolors.find('.minicolors-grid-inner').css('opacity', 1 - hsb.b / 100);
        break;
      default:
        // Set grid position
        x = keepWithin(Math.ceil(hsb.s / (100 / grid.width())), 0, grid.width());
        y = keepWithin(grid.height() - Math.ceil(hsb.b / (100 / grid.height())), 0, grid.height());
        gridPicker.css({
          top: y + 'px',
          left: x + 'px'
        });

        // Set slider position
        y = keepWithin(slider.height() - hsb.h / (360 / slider.height()), 0, slider.height());
        sliderPicker.css('top', y + 'px');

        // Update panel color
        grid.css('backgroundColor', hsb2hex({
          h: hsb.h,
          s: 100,
          b: 100
        }));
        break;
    }

    // Fire change event, but only if minicolors is fully initialized
    if (input.data('minicolors-initialized')) {
      doChange(input, value, opacity);
    }
  }

  // Runs the change and changeDelay callbacks
  function doChange(input, value, opacity) {
    var settings = input.data('minicolors-settings');
    var lastChange = input.data('minicolors-lastChange');
    var obj, sel, i;

    // Only run if it actually changed
    if (!lastChange || lastChange.value !== value || lastChange.opacity !== opacity) {
      // Remember last-changed value
      input.data('minicolors-lastChange', {
        value: value,
        opacity: opacity
      });

      // Check and select applicable swatch
      if (settings.swatches && settings.swatches.length !== 0) {
        if (!isRgb(value)) {
          obj = hex2rgb(value);
        } else {
          obj = parseRgb(value, true);
        }
        sel = -1;
        for (i = 0; i < settings.swatches.length; ++i) {
          if (obj.r === settings.swatches[i].r && obj.g === settings.swatches[i].g && obj.b === settings.swatches[i].b && obj.a === settings.swatches[i].a) {
            sel = i;
            break;
          }
        }
        input.parent().find('.minicolors-swatches .minicolors-swatch').removeClass('selected');
        if (sel !== -1) {
          input.parent().find('.minicolors-swatches .minicolors-swatch').eq(i).addClass('selected');
        }
      }

      // Fire change event
      if (settings.change) {
        if (settings.changeDelay) {
          // Call after a delay
          clearTimeout(input.data('minicolors-changeTimeout'));
          input.data('minicolors-changeTimeout', setTimeout(function () {
            settings.change.call(input.get(0), value, opacity);
          }, settings.changeDelay));
        } else {
          // Call immediately
          settings.change.call(input.get(0), value, opacity);
        }
      }
      input.trigger('change').trigger('input');
    }
  }

  // Generates an RGB(A) object based on the input's value
  function rgbObject(input) {
    var rgb,
      opacity = $(input).attr('data-opacity');
    if (isRgb($(input).val())) {
      rgb = parseRgb($(input).val(), true);
    } else {
      var hex = parseHex($(input).val(), true);
      rgb = hex2rgb(hex);
    }
    if (!rgb) return null;
    if (opacity !== undefined) $.extend(rgb, {
      a: parseFloat(opacity)
    });
    return rgb;
  }

  // Generates an RGB(A) string based on the input's value
  function rgbString(input, alpha) {
    var rgb,
      opacity = $(input).attr('data-opacity');
    if (isRgb($(input).val())) {
      rgb = parseRgb($(input).val(), true);
    } else {
      var hex = parseHex($(input).val(), true);
      rgb = hex2rgb(hex);
    }
    if (!rgb) return null;
    if (opacity === undefined) opacity = 1;
    if (alpha) {
      return 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + parseFloat(opacity) + ')';
    } else {
      return 'rgb(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ')';
    }
  }

  // Converts to the letter case specified in settings
  function convertCase(string, letterCase) {
    return letterCase === 'uppercase' ? string.toUpperCase() : string.toLowerCase();
  }

  // Parses a string and returns a valid hex string when possible
  function parseHex(string, expand) {
    string = string.replace(/^#/g, '');
    if (!string.match(/^[A-F0-9]{3,6}/ig)) return '';
    if (string.length !== 3 && string.length !== 6) return '';
    if (string.length === 3 && expand) {
      string = string[0] + string[0] + string[1] + string[1] + string[2] + string[2];
    }
    return '#' + string;
  }

  // Parses a string and returns a valid RGB(A) string when possible
  function parseRgb(string, obj) {
    var values = string.replace(/[^\d,.]/g, '');
    var rgba = values.split(',');
    rgba[0] = keepWithin(parseInt(rgba[0], 10), 0, 255);
    rgba[1] = keepWithin(parseInt(rgba[1], 10), 0, 255);
    rgba[2] = keepWithin(parseInt(rgba[2], 10), 0, 255);
    if (rgba[3] !== undefined) {
      rgba[3] = keepWithin(parseFloat(rgba[3], 10), 0, 1);
    }

    // Return RGBA object
    if (obj) {
      if (rgba[3] !== undefined) {
        return {
          r: rgba[0],
          g: rgba[1],
          b: rgba[2],
          a: rgba[3]
        };
      } else {
        return {
          r: rgba[0],
          g: rgba[1],
          b: rgba[2]
        };
      }
    }

    // Return RGBA string
    if (typeof rgba[3] !== 'undefined' && rgba[3] <= 1) {
      return 'rgba(' + rgba[0] + ', ' + rgba[1] + ', ' + rgba[2] + ', ' + rgba[3] + ')';
    } else {
      return 'rgb(' + rgba[0] + ', ' + rgba[1] + ', ' + rgba[2] + ')';
    }
  }

  // Parses a string and returns a valid color string when possible
  function parseInput(string, expand) {
    if (isRgb(string)) {
      // Returns a valid rgb(a) string
      return parseRgb(string);
    } else {
      return parseHex(string, expand);
    }
  }

  // Keeps value within min and max
  function keepWithin(value, min, max) {
    if (value < min) value = min;
    if (value > max) value = max;
    return value;
  }

  // Checks if a string is a valid RGB(A) string
  function isRgb(string) {
    var rgb = string.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
    return rgb && rgb.length === 4 ? true : false;
  }

  // Function to get alpha from a RGB(A) string
  function getAlpha(rgba) {
    rgba = rgba.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+(\.\d{1,2})?|\.\d{1,2})[\s+]?/i);
    return rgba && rgba.length === 6 ? rgba[4] : '1';
  }

  // Converts an HSB object to an RGB object
  function hsb2rgb(hsb) {
    var rgb = {};
    var h = Math.round(hsb.h);
    var s = Math.round(hsb.s * 255 / 100);
    var v = Math.round(hsb.b * 255 / 100);
    if (s === 0) {
      rgb.r = rgb.g = rgb.b = v;
    } else {
      var t1 = v;
      var t2 = (255 - s) * v / 255;
      var t3 = (t1 - t2) * (h % 60) / 60;
      if (h === 360) h = 0;
      if (h < 60) {
        rgb.r = t1;
        rgb.b = t2;
        rgb.g = t2 + t3;
      } else if (h < 120) {
        rgb.g = t1;
        rgb.b = t2;
        rgb.r = t1 - t3;
      } else if (h < 180) {
        rgb.g = t1;
        rgb.r = t2;
        rgb.b = t2 + t3;
      } else if (h < 240) {
        rgb.b = t1;
        rgb.r = t2;
        rgb.g = t1 - t3;
      } else if (h < 300) {
        rgb.b = t1;
        rgb.g = t2;
        rgb.r = t2 + t3;
      } else if (h < 360) {
        rgb.r = t1;
        rgb.g = t2;
        rgb.b = t1 - t3;
      } else {
        rgb.r = 0;
        rgb.g = 0;
        rgb.b = 0;
      }
    }
    return {
      r: Math.round(rgb.r),
      g: Math.round(rgb.g),
      b: Math.round(rgb.b)
    };
  }

  // Converts an RGB string to a hex string
  function rgbString2hex(rgb) {
    rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
    return rgb && rgb.length === 4 ? '#' + ('0' + parseInt(rgb[1], 10).toString(16)).slice(-2) + ('0' + parseInt(rgb[2], 10).toString(16)).slice(-2) + ('0' + parseInt(rgb[3], 10).toString(16)).slice(-2) : '';
  }

  // Converts an RGB object to a hex string
  function rgb2hex(rgb) {
    var hex = [rgb.r.toString(16), rgb.g.toString(16), rgb.b.toString(16)];
    $.each(hex, function (nr, val) {
      if (val.length === 1) hex[nr] = '0' + val;
    });
    return '#' + hex.join('');
  }

  // Converts an HSB object to a hex string
  function hsb2hex(hsb) {
    return rgb2hex(hsb2rgb(hsb));
  }

  // Converts a hex string to an HSB object
  function hex2hsb(hex) {
    var hsb = rgb2hsb(hex2rgb(hex));
    if (hsb.s === 0) hsb.h = 360;
    return hsb;
  }

  // Converts an RGB object to an HSB object
  function rgb2hsb(rgb) {
    var hsb = {
      h: 0,
      s: 0,
      b: 0
    };
    var min = Math.min(rgb.r, rgb.g, rgb.b);
    var max = Math.max(rgb.r, rgb.g, rgb.b);
    var delta = max - min;
    hsb.b = max;
    hsb.s = max !== 0 ? 255 * delta / max : 0;
    if (hsb.s !== 0) {
      if (rgb.r === max) {
        hsb.h = (rgb.g - rgb.b) / delta;
      } else if (rgb.g === max) {
        hsb.h = 2 + (rgb.b - rgb.r) / delta;
      } else {
        hsb.h = 4 + (rgb.r - rgb.g) / delta;
      }
    } else {
      hsb.h = -1;
    }
    hsb.h *= 60;
    if (hsb.h < 0) {
      hsb.h += 360;
    }
    hsb.s *= 100 / 255;
    hsb.b *= 100 / 255;
    return hsb;
  }

  // Converts a hex string to an RGB object
  function hex2rgb(hex) {
    hex = parseInt(hex.indexOf('#') > -1 ? hex.substring(1) : hex, 16);
    return {
      r: hex >> 16,
      g: (hex & 0x00FF00) >> 8,
      b: hex & 0x0000FF
    };
  }

  // Handle events
  $([document])
  // Hide on clicks outside of the control
  .on('mousedown.minicolors touchstart.minicolors', function (event) {
    if (!$(event.target).parents().add(event.target).hasClass('minicolors')) {
      hide();
    }
  })
  // Start moving
  .on('mousedown.minicolors touchstart.minicolors', '.minicolors-grid, .minicolors-slider, .minicolors-opacity-slider', function (event) {
    var target = $(this);
    event.preventDefault();
    $(event.delegateTarget).data('minicolors-target', target);
    move(target, event, true);
  })
  // Move pickers
  .on('mousemove.minicolors touchmove.minicolors', function (event) {
    var target = $(event.delegateTarget).data('minicolors-target');
    if (target) move(target, event);
  })
  // Stop moving
  .on('mouseup.minicolors touchend.minicolors', function () {
    $(this).removeData('minicolors-target');
  })
  // Selected a swatch
  .on('click.minicolors', '.minicolors-swatches li', function (event) {
    event.preventDefault();
    var target = $(this),
      input = target.parents('.minicolors').find('.minicolors-input'),
      color = target.data('swatch-color');
    updateInput(input, color, getAlpha(color));
    updateFromInput(input);
  })
  // Show panel when swatch is clicked
  .on('mousedown.minicolors touchstart.minicolors', '.minicolors-input-swatch', function (event) {
    var input = $(this).parent().find('.minicolors-input');
    event.preventDefault();
    show(input);
  })
  // Show on focus
  .on('focus.minicolors', '.minicolors-input', function () {
    var input = $(this);
    if (!input.data('minicolors-initialized')) return;
    show(input);
  })
  // Update value on blur
  .on('blur.minicolors', '.minicolors-input', function () {
    var input = $(this);
    var settings = input.data('minicolors-settings');
    var keywords;
    var hex;
    var rgba;
    var swatchOpacity;
    var value;
    if (!input.data('minicolors-initialized')) return;

    // Get array of lowercase keywords
    keywords = !settings.keywords ? [] : $.map(settings.keywords.split(','), function (a) {
      return a.toLowerCase().trim();
    });

    // Set color string
    if (input.val() !== '' && $.inArray(input.val().toLowerCase(), keywords) > -1) {
      value = input.val();
    } else {
      // Get RGBA values for easy conversion
      if (isRgb(input.val())) {
        rgba = parseRgb(input.val(), true);
      } else {
        hex = parseHex(input.val(), true);
        rgba = hex ? hex2rgb(hex) : null;
      }

      // Convert to format
      if (rgba === null) {
        value = settings.defaultValue;
      } else if (settings.format === 'rgb') {
        value = settings.opacity ? parseRgb('rgba(' + rgba.r + ',' + rgba.g + ',' + rgba.b + ',' + input.attr('data-opacity') + ')') : parseRgb('rgb(' + rgba.r + ',' + rgba.g + ',' + rgba.b + ')');
      } else {
        value = rgb2hex(rgba);
      }
    }

    // Update swatch opacity
    swatchOpacity = settings.opacity ? input.attr('data-opacity') : 1;
    if (value.toLowerCase() === 'transparent') swatchOpacity = 0;
    input.closest('.minicolors').find('.minicolors-input-swatch > span').css('opacity', String(swatchOpacity));

    // Set input value
    input.val(value);

    // Is it blank?
    if (input.val() === '') input.val(parseInput(settings.defaultValue, true));

    // Adjust case
    input.val(convertCase(input.val(), settings.letterCase));
  })
  // Handle keypresses
  .on('keydown.minicolors', '.minicolors-input', function (event) {
    var input = $(this);
    if (!input.data('minicolors-initialized')) return;
    switch (event.which) {
      case 9:
        // tab
        hide();
        break;
      case 13: // enter
      case 27:
        // esc
        hide();
        input.blur();
        break;
    }
  })
  // Update on keyup
  .on('keyup.minicolors', '.minicolors-input', function () {
    var input = $(this);
    if (!input.data('minicolors-initialized')) return;
    updateFromInput(input, true);
  })
  // Update on paste
  .on('paste.minicolors', '.minicolors-input', function () {
    var input = $(this);
    if (!input.data('minicolors-initialized')) return;
    setTimeout(function () {
      updateFromInput(input, true);
    }, 1);
  });
});
