text: /**!
   * MixItUp v2.1.5
   *
   * @copyright Copyright 2014 KunkaLabs Limited.
   * @author    KunkaLabs Limited.
   * @link      https://mixitup.kunkalabs.com
   *
   * @license   Commercial use requires a commercial license.
   *            https://mixitup.kunkalabs.com/licenses/
   *
   *            Non-commercial use permitted under terms of CC-BY-NC license.
   *            http://creativecommons.org/licenses/by-nc/3.0/
   */
  
  (function($, undf) {
  
      /**
       * MixItUp Constructor Function
       * @constructor
       * @extends jQuery
       */
  
      $.MixItUp = function() {
          var self = this;
  
          self._execAction('_constructor', 0);
  
          $.extend(self, {
              /* Public Properties
               ---------------------------------------------------------------------- */
  
              selectors: {
                  target: '.mix',
                  filter: '.filter',
                  sort: '.sort'
              },
              animation: {
                  enable: true,
                  effects: 'fade scale',
                  duration: 600,
                  easing: 'ease',
                  perspectiveDistance: '3000',
                  perspectiveOrigin: '50% 50%',
                  queue: true,
                  queueLimit: 1,
                  animateChangeLayout: false,
                  animateResizeContainer: true,
                  animateResizeTargets: false,
                  staggerSequence: false,
                  reverseOut: false
              },
              callbacks: {
                  onMixLoad: false,
                  onMixStart: false,
                  onMixBusy: false,
                  onMixEnd: false,
                  onMixFail: false,
                  _user: false
              },
              controls: {
                  enable: true,
                  live: false,
                  toggleFilterButtons: false,
                  toggleLogic: 'or',
                  activeClass: 'active'
              },
              layout: {
                  display: 'inline-block',
                  containerClass: '',
                  containerClassFail: 'fail'
              },
              load: {
                  filter: 'all',
                  sort: false
              },
              /* Private Properties
               ---------------------------------------------------------------------- */
  
              _$body: null,
              _$container: null,
              _$targets: null,
              _$parent: null,
              _$sortButtons: null,
              _$filterButtons: null,
              _suckMode: false,
              _mixing: false,
              _sorting: false,
              _clicking: false,
              _loading: true,
              _changingLayout: false,
              _changingClass: false,
              _changingDisplay: false,
              _origOrder: [],
              _startOrder: [],
              _newOrder: [],
              _activeFilter: null,
              _toggleArray: [],
              _toggleString: '',
              _activeSort: 'default:asc',
              _newSort: null,
              _startHeight: null,
              _newHeight: null,
              _incPadding: true,
              _newDisplay: null,
              _newClass: null,
              _targetsBound: 0,
              _targetsDone: 0,
              _queue: [],
              _$show: $(),
              _$hide: $()
          });
  
          self._execAction('_constructor', 1);
      };
  
      /**
       * MixItUp Prototype
       * @override
       */
  
      $.MixItUp.prototype = {
          constructor: $.MixItUp,
          /* Static Properties
           ---------------------------------------------------------------------- */
  
          _instances: {},
          _handled: {
              _filter: {},
              _sort: {}
          },
          _bound: {
              _filter: {},
              _sort: {}
          },
          _actions: {},
          _filters: {},
          /* Static Methods
           ---------------------------------------------------------------------- */
  
          /**
           * Extend
           * @since 2.1.0
           * @param {object} new properties/methods
           * @extends {object} prototype
           */
  
          extend: function(extension) {
              for (var key in extension) {
                  $.MixItUp.prototype[key] = extension[key];
              }
          },
          /**
           * Add Action
           * @since 2.1.0
           * @param {string} hook name
           * @param {string} namespace
           * @param {function} function to execute
           * @param {number} priority
           * @extends {object} $.MixItUp.prototype._actions
           */
  
          addAction: function(hook, name, func, priority) {
              $.MixItUp.prototype._addHook('_actions', hook, name, func, priority);
          },
          /**
           * Add Filter
           * @since 2.1.0
           * @param {string} hook name
           * @param {string} namespace
           * @param {function} function to execute
           * @param {number} priority
           * @extends {object} $.MixItUp.prototype._filters
           */
  
          addFilter: function(hook, name, func, priority) {
              $.MixItUp.prototype._addHook('_filters', hook, name, func, priority);
          },
          /**
           * Add Hook
           * @since 2.1.0
           * @param {string} type of hook
           * @param {string} hook name
           * @param {function} function to execute
           * @param {number} priority
           * @extends {object} $.MixItUp.prototype._filters
           */
  
          _addHook: function(type, hook, name, func, priority) {
              var collection = $.MixItUp.prototype[type],
                      obj = {};
  
              priority = (priority === 1 || priority === 'post') ? 'post' : 'pre';
  
              obj[hook] = {};
              obj[hook][priority] = {};
              obj[hook][priority][name] = func;
  
              $.extend(true, collection, obj);
        },
          /* Private Methods
           ---------------------------------------------------------------------- */
  
          /**
           * Initialise
           * @since 2.0.0
           * @param {object} domNode
           * @param {object} config
           */
  
          _init: function(domNode, config) {
              var self = this;
  
              self._execAction('_init', 0, arguments);
  
              config && $.extend(true, self, config);
  
              self._$body = $('body');
              self._domNode = domNode;
              self._$container = $(domNode);
              self._$container.addClass(self.layout.containerClass);
              self._id = domNode.id;
  
              self._platformDetect();
  
              self._brake = self._getPrefixedCSS('transition', 'none');
  
              self._refresh(true);
  
              self._$parent = self._$targets.parent().length ? self._$targets.parent() : self._$container;
  
              if (self.load.sort) {
                  self._newSort = self._parseSort(self.load.sort);
                  self._newSortString = self.load.sort;
                  self._activeSort = self.load.sort;
                  self._sort();
                  self._printSort();
              }
  
              self._activeFilter = self.load.filter === 'all' ?
                      self.selectors.target :
                      self.load.filter === 'none' ?
                      '' :
                      self.load.filter;
  
              self.controls.enable && self._bindHandlers();
  
              if (self.controls.toggleFilterButtons) {
                  self._buildToggleArray();
  
                  for (var i = 0; i < self._toggleArray.length; i++) {
                      self._updateControls({filter: self._toggleArray[i], sort: self._activeSort}, true);
                  }
                  ;
              } else if (self.controls.enable) {
                  self._updateControls({filter: self._activeFilter, sort: self._activeSort});
              }
  
              self._filter();
  
              self._init = true;
  
              self._$container.data('mixItUp', self);
  
              self._execAction('_init', 1, arguments);
  
              self._buildState();
  
              self._$targets.css(self._brake);
  
              self._goMix(self.animation.enable);
          },
          /**
           * Platform Detect
           * @since 2.0.0
           */
  
          _platformDetect: function() {
              var self = this,
                      vendorsTrans = ['Webkit', 'Moz', 'O', 'ms'],
                      vendorsRAF = ['webkit', 'moz'],
                      chrome = window.navigator.appVersion.match(/Chrome\/(\d+)\./) || false,
                      ff = typeof InstallTrigger !== 'undefined',
                      prefix = function(el) {
                          for (var i = 0; i < vendorsTrans.length; i++) {
                              if (vendorsTrans[i] + 'Transition' in el.style) {
                                  return {
                                      prefix: '-' + vendorsTrans[i].toLowerCase() + '-',
                                      vendor: vendorsTrans[i]
                                  };
                              }
                              ;
                          }
                          ;
                          return 'transition' in el.style ? '' : false;
                      },
                      transPrefix = prefix(self._domNode);
  
              self._execAction('_platformDetect', 0);
  
              self._chrome = chrome ? parseInt(chrome[1], 10) : false;
              self._ff = ff ? parseInt(window.navigator.userAgent.match(/rv:([^)]+)\)/)[1]) : false;
              self._prefix = transPrefix.prefix;
              self._vendor = transPrefix.vendor;
              self._suckMode = window.atob && self._prefix ? false : true;
  
              self._suckMode && (self.animation.enable = false);
              (self._ff && self._ff <= 4) && (self.animation.enable = false);
  
              /* Polyfills
               ---------------------------------------------------------------------- */
  
              /**
               * window.requestAnimationFrame
               */
  
              for (var x = 0; x < vendorsRAF.length && !window.requestAnimationFrame; x++) {
                  window.requestAnimationFrame = window[vendorsRAF[x] + 'RequestAnimationFrame'];
              }
  
              /**
               * Object.getPrototypeOf
               */
  
              if (typeof Object.getPrototypeOf !== 'function') {
                  if (typeof 'test'.__proto__ === 'object') {
                      Object.getPrototypeOf = function(object) {
                          return object.__proto__;
                      };
                  } else {
                      Object.getPrototypeOf = function(object) {
                          return object.constructor.prototype;
                      };
                  }
              }
  
              /**
               * Element.nextElementSibling
               */
  
              if (self._domNode.nextElementSibling === undf) {
                  Object.defineProperty(Element.prototype, 'nextElementSibling', {
                      get: function() {
                          var el = this.nextSibling;
  
                          while (el) {
                              if (el.nodeType === 1) {
                                  return el;
                              }
                              el = el.nextSibling;
                          }
                          return null;
                      }
                  });
              }
  
              self._execAction('_platformDetect', 1);
          },
          /**
           * Refresh
           * @since 2.0.0
           * @param {boolean} init
           * @param {boolean} force
           */
  
          _refresh: function(init, force) {
              var self = this;
  
              self._execAction('_refresh', 0, arguments);
  
              self._$targets = self._$container.find(self.selectors.target);
  
              for (var i = 0; i < self._$targets.length; i++) {
                  var target = self._$targets[i];
  
                  if (target.dataset === undf || force) {
  
                      target.dataset = {};
  
                      for (var j = 0; j < target.attributes.length; j++) {
  
                          var attr = target.attributes[j],
                                  name = attr.name,
                                  val = attr.nodeValue;
  
                          if (name.indexOf('data-') > -1) {
                              var dataName = self._helpers._camelCase(name.substring(5, name.length));
                              target.dataset[dataName] = val;
                          }
                      }
                  }
  
                  if (target.mixParent === undf) {
                      target.mixParent = self._id;
                  }
              }
  
              if (
                      (self._$targets.length && init) ||
                      (!self._origOrder.length && self._$targets.length)
                      ) {
                  self._origOrder = [];
  
                  for (var i = 0; i < self._$targets.length; i++) {
                      var target = self._$targets[i];
  
                      self._origOrder.push(target);
                  }
              }
  
              self._execAction('_refresh', 1, arguments);
          },
          /**
           * Bind Handlers
           * @since 2.0.0
           */
  
          _bindHandlers: function() {
              var self = this,
                      filters = $.MixItUp.prototype._bound._filter,
                      sorts = $.MixItUp.prototype._bound._sort;
  
              self._execAction('_bindHandlers', 0);
  
              if (self.controls.live) {
                  self._$body
                          .on('click.mixItUp.' + self._id, self.selectors.sort, function() {
                              self._processClick($(this), 'sort');
                          })
                          .on('click.mixItUp.' + self._id, self.selectors.filter, function() {
                              self._processClick($(this), 'filter');
                          });
              } else {
                  self._$sortButtons = $(self.selectors.sort);
                  self._$filterButtons = $(self.selectors.filter);
  
                  self._$sortButtons.on('click.mixItUp.' + self._id, function() {
                      self._processClick($(this), 'sort');
                  });
  
                  self._$filterButtons.on('click.mixItUp.' + self._id, function() {
                      self._processClick($(this), 'filter');
                  });
              }
  
              filters[self.selectors.filter] = (filters[self.selectors.filter] === undf) ? 1 : filters[self.selectors.filter] + 1;
              sorts[self.selectors.sort] = (sorts[self.selectors.sort] === undf) ? 1 : sorts[self.selectors.sort] + 1;
  
              self._execAction('_bindHandlers', 1);
          },
          /**
           * Process Click
           * @since 2.0.0
           * @param {object} $button
           * @param {string} type
           */
  
          _processClick: function($button, type) {
              var self = this,
                      trackClick = function($button, type, off) {
                          var proto = $.MixItUp.prototype;
  
                          proto._handled['_' + type][self.selectors[type]] = (proto._handled['_' + type][self.selectors[type]] === undf) ?
                                  1 :
                                  proto._handled['_' + type][self.selectors[type]] + 1;
  
                          if (proto._handled['_' + type][self.selectors[type]] === proto._bound['_' + type][self.selectors[type]]) {
                              $button[(off ? 'remove' : 'add') + 'Class'](self.controls.activeClass);
                              delete proto._handled['_' + type][self.selectors[type]];
                          }
                      };
  
              self._execAction('_processClick', 0, arguments);
  
              if (!self._mixing || (self.animation.queue && self._queue.length < self.animation.queueLimit)) {
                  self._clicking = true;
  
                  if (type === 'sort') {
                      var sort = $button.attr('data-sort');
  
                      if (!$button.hasClass(self.controls.activeClass) || sort.indexOf('random') > -1) {
                          $(self.selectors.sort).removeClass(self.controls.activeClass);
                          trackClick($button, type);
                          self.sort(sort);
                      }
                  }
  
                  if (type === 'filter') {
                      var filter = $button.attr('data-filter'),
                              ndx,
                              seperator = self.controls.toggleLogic === 'or' ? ',' : '';
  
                      if (!self.controls.toggleFilterButtons) {
                          if (!$button.hasClass(self.controls.activeClass)) {
                              $(self.selectors.filter).removeClass(self.controls.activeClass);
                              trackClick($button, type);
                              self.filter(filter);
                          }
                      } else {
                          self._buildToggleArray();
  
                          if (!$button.hasClass(self.controls.activeClass)) {
                              trackClick($button, type);
  
                              self._toggleArray.push(filter);
                          } else {
                              trackClick($button, type, true);
                              ndx = self._toggleArray.indexOf(filter);
                              self._toggleArray.splice(ndx, 1);
                          }
  
                          self._toggleArray = $.grep(self._toggleArray, function(n) {
                              return(n);
                          });
  
                          self._toggleString = self._toggleArray.join(seperator);
  
                          self.filter(self._toggleString);
                      }
                  }
  
                  self._execAction('_processClick', 1, arguments);
              } else {
                  if (typeof self.callbacks.onMixBusy === 'function') {
                      self.callbacks.onMixBusy.call(self._domNode, self._state, self);
                  }
                  self._execAction('_processClickBusy', 1, arguments);
              }
          },
          /**
           * Build Toggle Array
           * @since 2.0.0
           */
  
          _buildToggleArray: function() {
              var self = this,
                      activeFilter = self._activeFilter.replace(/\s/g, '');
  
              self._execAction('_buildToggleArray', 0, arguments);
  
              if (self.controls.toggleLogic === 'or') {
                  self._toggleArray = activeFilter.split(',');
              } else {
                  self._toggleArray = activeFilter.split('.');
  
                  !self._toggleArray[0] && self._toggleArray.shift();
  
                  for (var i = 0, filter; filter = self._toggleArray[i]; i++) {
                      self._toggleArray[i] = '.' + filter;
                  }
              }
  
              self._execAction('_buildToggleArray', 1, arguments);
          },
          /**
           * Update Controls
           * @since 2.0.0
           * @param {object} command
           * @param {boolean} multi
           */
  
          _updateControls: function(command, multi) {
              var self = this,
                      output = {
                          filter: command.filter,
                          sort: command.sort
                      },
              update = function($el, filter) {
                  (multi && type == 'filter' && !(output.filter === 'none' || output.filter === '')) ?
                          $el.filter(filter).addClass(self.controls.activeClass) :
                          $el.removeClass(self.controls.activeClass).filter(filter).addClass(self.controls.activeClass);
              },
                      type = 'filter',
                      $el = null;
  
              self._execAction('_updateControls', 0, arguments);
  
              (command.filter === undf) && (output.filter = self._activeFilter);
              (command.sort === undf) && (output.sort = self._activeSort);
              (output.filter === self.selectors.target) && (output.filter = 'all');
  
              for (var i = 0; i < 2; i++) {
                  $el = self.controls.live ? $(self.selectors[type]) : self['_$' + type + 'Buttons'];
                  $el && update($el, '[data-' + type + '="' + output[type] + '"]');
                  type = 'sort';
              }
  
              self._execAction('_updateControls', 1, arguments);
          },
          /**
           * Filter (private)
           * @since 2.0.0
           */
  
          _filter: function() {
              var self = this;
  
              self._execAction('_filter', 0);
  
              for (var i = 0; i < self._$targets.length; i++) {
                  var $target = $(self._$targets[i]);
  
                  if ($target.is(self._activeFilter)) {
                      self._$show = self._$show.add($target);
                  } else {
                      self._$hide = self._$hide.add($target);
                  }
              }
  
              self._execAction('_filter', 1);
          },
          /**
           * Sort (private)
           * @since 2.0.0
           */
  
          _sort: function() {
              var self = this,
                      arrayShuffle = function(oldArray) {
                          var newArray = oldArray.slice(),
                                  len = newArray.length,
                                  i = len;
  
                          while (i--) {
                              var p = parseInt(Math.random() * len);
                              var t = newArray[i];
                              newArray[i] = newArray[p];
                              newArray[p] = t;
                          }
                          ;
                          return newArray;
                      };
  
              self._execAction('_sort', 0);
  
              self._startOrder = [];
  
              for (var i = 0; i < self._$targets.length; i++) {
                  var target = self._$targets[i];
  
                  self._startOrder.push(target);
              }
  
              switch (self._newSort[0].sortBy) {
                  case 'default':
                      self._newOrder = self._origOrder;
                      break;
                  case 'random':
                      self._newOrder = arrayShuffle(self._startOrder);
                      break;
                  case 'custom':
                      self._newOrder = self._newSort[0].order;
                      break;
                  default:
                      self._newOrder = self._startOrder.concat().sort(function(a, b) {
                          return self._compare(a, b);
                      });
              }
  
              self._execAction('_sort', 1);
          },
          /**
           * Compare Algorithm
           * @since 2.0.0
           * @param {string|number} a
           * @param {string|number} b
           * @param {number} depth (recursion)
           * @return {number}
           */
  
          _compare: function(a, b, depth) {
              depth = depth ? depth : 0;
  
              var self = this,
                      order = self._newSort[depth].order,
                      getData = function(el) {
                          return el.dataset[self._newSort[depth].sortBy] || 0;
                      },
                      attrA = isNaN(getData(a) * 1) ? getData(a).toLowerCase() : getData(a) * 1,
                      attrB = isNaN(getData(b) * 1) ? getData(b).toLowerCase() : getData(b) * 1;
  
              if (attrA < attrB)
                  return order == 'asc' ? -1 : 1;
              if (attrA > attrB)
                  return order == 'asc' ? 1 : -1;
              if (attrA == attrB && self._newSort.length > depth + 1)
                  return self._compare(a, b, depth + 1);
  
              return 0;
          },
          /**
           * Print Sort
           * @since 2.0.0
           * @param {boolean} reset
           */
  
          _printSort: function(reset) {
              var self = this,
                      order = reset ? self._startOrder : self._newOrder,
                      targets = self._$parent[0].querySelectorAll(self.selectors.target),
                      nextSibling = targets[targets.length - 1].nextElementSibling,
                      frag = document.createDocumentFragment();
  
              self._execAction('_printSort', 0, arguments);
  
              for (var i = 0; i < targets.length; i++) {
                  var target = targets[i],
                          whiteSpace = target.nextSibling;
  
                  if (target.style.position === 'absolute')
                      continue;
  
                  if (whiteSpace && whiteSpace.nodeName == '#text') {
                      self._$parent[0].removeChild(whiteSpace);
                  }
  
                  self._$parent[0].removeChild(target);
              }
  
              for (var i = 0; i < order.length; i++) {
                  var el = order[i];
  
                  if (self._newSort[0].sortBy == 'default' && self._newSort[0].order == 'desc' && !reset) {
                      var firstChild = frag.firstChild;
                      frag.insertBefore(el, firstChild);
                      frag.insertBefore(document.createTextNode(' '), el);
                  } else {
                      frag.appendChild(el);
                      frag.appendChild(document.createTextNode(' '));
                  }
              }
  
              nextSibling ?
                      self._$parent[0].insertBefore(frag, nextSibling) :
                      self._$parent[0].appendChild(frag);
  
              self._execAction('_printSort', 1, arguments);
          },
          /**
           * Parse Sort
           * @since 2.0.0
           * @param {string} sortString
           * @return {array} newSort
           */
  
          _parseSort: function(sortString) {
              var self = this,
                      rules = typeof sortString === 'string' ? sortString.split(' ') : [sortString],
                      newSort = [];
  
              for (var i = 0; i < rules.length; i++) {
                  var rule = typeof sortString === 'string' ? rules[i].split(':') : ['custom', rules[i]],
                          ruleObj = {
                              sortBy: self._helpers._camelCase(rule[0]),
                              order: rule[1] || 'asc'
                          };
  
                  newSort.push(ruleObj);
  
                  if (ruleObj.sortBy == 'default' || ruleObj.sortBy == 'random')
                      break;
              }
  
              return self._execFilter('_parseSort', newSort, arguments);
          },
          /**
           * Parse Effects
           * @since 2.0.0
           * @return {object} effects
           */
  
          _parseEffects: function() {
              var self = this,
                      effects = {
                          opacity: '',
                          transformIn: '',
                          transformOut: '',
                          filter: ''
                      },
              parse = function(effect, extract, reverse) {
                  if (self.animation.effects.indexOf(effect) > -1) {
                      if (extract) {
                          var propIndex = self.animation.effects.indexOf(effect + '(');
                          if (propIndex > -1) {
                              var str = self.animation.effects.substring(propIndex),
                                      match = /\(([^)]+)\)/.exec(str),
                                      val = match[1];
  
                              return {val: val};
                          }
                      }
                      return true;
                  } else {
                      return false;
                  }
              },
                      negate = function(value, invert) {
                          if (invert) {
                              return value.charAt(0) === '-' ? value.substr(1, value.length) : '-' + value;
                          } else {
                              return value;
                          }
                      },
                      buildTransform = function(key, invert) {
                          var transforms = [
                              ['scale', '.01'],
                              ['translateX', '20px'],
                              ['translateY', '20px'],
                              ['translateZ', '20px'],
                              ['rotateX', '90deg'],
                              ['rotateY', '90deg'],
                              ['rotateZ', '180deg'],
                          ];
  
                          for (var i = 0; i < transforms.length; i++) {
                              var prop = transforms[i][0],
                                      def = transforms[i][1],
                                      inverted = invert && prop !== 'scale';
  
                              effects[key] += parse(prop) ? prop + '(' + negate(parse(prop, true).val || def, inverted) + ') ' : '';
                          }
                      };
  
              effects.opacity = parse('fade') ? parse('fade', true).val || '0' : '1';
  
              buildTransform('transformIn');
  
              self.animation.reverseOut ? buildTransform('transformOut', true) : (effects.transformOut = effects.transformIn);
  
              effects.transition = {};
  
              effects.transition = self._getPrefixedCSS('transition', 'all ' + self.animation.duration + 'ms ' + self.animation.easing + ', opacity ' + self.animation.duration + 'ms linear');
  
              self.animation.stagger = parse('stagger') ? true : false;
              self.animation.staggerDuration = parseInt(parse('stagger') ? (parse('stagger', true).val ? parse('stagger', true).val : 100) : 100);
  
              return self._execFilter('_parseEffects', effects);
          },
          /**
           * Build State
           * @since 2.0.0
           * @param {boolean} future
           * @return {object} futureState
           */
  
          _buildState: function(future) {
              var self = this,
                      state = {};
  
              self._execAction('_buildState', 0);
  
              state = {
                  activeFilter: self._activeFilter === '' ? 'none' : self._activeFilter,
                  activeSort: future && self._newSortString ? self._newSortString : self._activeSort,
                  fail: !self._$show.length && self._activeFilter !== '',
                  $targets: self._$targets,
                  $show: self._$show,
                  $hide: self._$hide,
                  totalTargets: self._$targets.length,
                  totalShow: self._$show.length,
                  totalHide: self._$hide.length,
                  display: future && self._newDisplay ? self._newDisplay : self.layout.display
              };
  
              if (future) {
                  return self._execFilter('_buildState', state);
              } else {
                  self._state = state;
  
                  self._execAction('_buildState', 1);
              }
          },
          /**
           * Go Mix
           * @since 2.0.0
           * @param {boolean} animate
           */
  
          _goMix: function(animate) {
              var self = this,
                      phase1 = function() {
                          if (self._chrome && (self._chrome === 31)) {
                              chromeFix(self._$parent[0]);
                          }
  
                          self._setInter();
  
                          phase2();
                      },
                      phase2 = function() {
                          var scrollTop = window.pageYOffset,
                                  scrollLeft = window.pageXOffset,
                                  docHeight = document.documentElement.scrollHeight;
  
                          self._getInterMixData();
  
                          self._setFinal();
  
                          self._getFinalMixData();
  
                          (window.pageYOffset !== scrollTop) && window.scrollTo(scrollLeft, scrollTop);
  
                          self._prepTargets();
  
                          if (window.requestAnimationFrame) {
                              requestAnimationFrame(phase3);
                          } else {
                              setTimeout(function() {
                                  phase3();
                              }, 20);
                          }
                      },
                      phase3 = function() {
                          self._animateTargets();
  
                          if (self._targetsBound === 0) {
                              self._cleanUp();
                          }
                      },
                      chromeFix = function(grid) {
                          var parent = grid.parentElement,
                                  placeholder = document.createElement('div'),
                                  frag = document.createDocumentFragment();
  
                          parent.insertBefore(placeholder, grid);
                          frag.appendChild(grid);
                          parent.replaceChild(grid, placeholder);
                      },
                      futureState = self._buildState(true);
  
              self._execAction('_goMix', 0, arguments);
  
              !self.animation.duration && (animate = false);
  
              self._mixing = true;
  
              self._$container.removeClass(self.layout.containerClassFail);
  
              if (typeof self.callbacks.onMixStart === 'function') {
                  self.callbacks.onMixStart.call(self._domNode, self._state, futureState, self);
              }
  
              self._$container.trigger('mixStart', [self._state, futureState, self]);
  
              self._getOrigMixData();
  
              if (animate && !self._suckMode) {
  
                  window.requestAnimationFrame ?
                          requestAnimationFrame(phase1) :
                          phase1();
  
              } else {
                  self._cleanUp();
              }
  
              self._execAction('_goMix', 1, arguments);
          },
          /**
           * Get Target Data
           * @since 2.0.0
           */
  
          _getTargetData: function(el, stage) {
              var self = this,
                      elStyle;
  
              el.dataset[stage + 'PosX'] = el.offsetLeft;
              el.dataset[stage + 'PosY'] = el.offsetTop;
  
              if (self.animation.animateResizeTargets) {
                  elStyle = window.getComputedStyle(el);
  
                  el.dataset[stage + 'MarginBottom'] = parseInt(elStyle.marginBottom);
                  el.dataset[stage + 'MarginRight'] = parseInt(elStyle.marginRight);
                  el.dataset[stage + 'Width'] = el.offsetWidth;
                  el.dataset[stage + 'Height'] = el.offsetHeight;
              }
          },
          /**
           * Get Original Mix Data
           * @since 2.0.0
           */
  
          _getOrigMixData: function() {
              var self = this,
                      parentStyle = !self._suckMode ? window.getComputedStyle(self._$parent[0]) : {boxSizing: ''},
              parentBS = parentStyle.boxSizing || parentStyle[self._vendor + 'BoxSizing'];
  
              self._incPadding = (parentBS === 'border-box');
  
              self._execAction('_getOrigMixData', 0);
  
              !self._suckMode && (self.effects = self._parseEffects());
  
              self._$toHide = self._$hide.filter(':visible');
              self._$toShow = self._$show.filter(':hidden');
              self._$pre = self._$targets.filter(':visible');
  
              self._startHeight = self._incPadding ?
                      self._$parent.outerHeight() :
                      self._$parent.height();
  
              for (var i = 0; i < self._$pre.length; i++) {
                  var el = self._$pre[i];
  
                  self._getTargetData(el, 'orig');
              }
  
              self._execAction('_getOrigMixData', 1);
          },
          /**
           * Set Intermediate Positions
           * @since 2.0.0
           */
  
          _setInter: function() {
              var self = this;
  
              self._execAction('_setInter', 0);
  
              if (self._changingLayout && self.animation.animateChangeLayout) {
                  self._$toShow.css('display', self._newDisplay);
  
                  if (self._changingClass) {
                      self._$container
                              .removeClass(self.layout.containerClass)
                              .addClass(self._newClass);
                  }
              } else {
                  self._$toShow.css('display', self.layout.display);
              }
  
              self._execAction('_setInter', 1);
          },
          /**
           * Get Intermediate Mix Data
           * @since 2.0.0
           */
  
          _getInterMixData: function() {
              var self = this;
  
              self._execAction('_getInterMixData', 0);
  
              for (var i = 0; i < self._$toShow.length; i++) {
                  var el = self._$toShow[i];
  
                  self._getTargetData(el, 'inter');
              }
  
              for (var i = 0; i < self._$pre.length; i++) {
                  var el = self._$pre[i];
  
                  self._getTargetData(el, 'inter');
              }
  
              self._execAction('_getInterMixData', 1);
          },
          /**
           * Set Final Positions
           * @since 2.0.0
           */
  
          _setFinal: function() {
              var self = this;
  
              self._execAction('_setFinal', 0);
  
              self._sorting && self._printSort();
  
              self._$toHide.removeStyle('display');
  
              if (self._changingLayout && self.animation.animateChangeLayout) {
                  self._$pre.css('display', self._newDisplay);
              }
  
              self._execAction('_setFinal', 1);
          },
          /**
           * Get Final Mix Data
           * @since 2.0.0
           */
  
          _getFinalMixData: function() {
              var self = this;
  
              self._execAction('_getFinalMixData', 0);
  
              for (var i = 0; i < self._$toShow.length; i++) {
                  var el = self._$toShow[i];
  
                  self._getTargetData(el, 'final');
              }
  
              for (var i = 0; i < self._$pre.length; i++) {
                  var el = self._$pre[i];
  
                  self._getTargetData(el, 'final');
              }
  
              self._newHeight = self._incPadding ?
                      self._$parent.outerHeight() :
                      self._$parent.height();
  
              self._sorting && self._printSort(true);
  
              self._$toShow.removeStyle('display');
  
              self._$pre.css('display', self.layout.display);
  
              if (self._changingClass && self.animation.animateChangeLayout) {
                  self._$container
                          .removeClass(self._newClass)
                          .addClass(self.layout.containerClass);
              }
  
              self._execAction('_getFinalMixData', 1);
          },
          /**
           * Prepare Targets
           * @since 2.0.0
           */
  
          _prepTargets: function() {
              var self = this,
                      transformCSS = {
                          _in: self._getPrefixedCSS('transform', self.effects.transformIn),
                          _out: self._getPrefixedCSS('transform', self.effects.transformOut)
                      };
  
              self._execAction('_prepTargets', 0);
  
              if (self.animation.animateResizeContainer) {
                  self._$parent.css('height', self._startHeight + 'px');
              }
  
              for (var i = 0; i < self._$toShow.length; i++) {
                  var el = self._$toShow[i],
                          $el = $(el);
  
                  el.style.opacity = self.effects.opacity;
                  el.style.display = (self._changingLayout && self.animation.animateChangeLayout) ?
                          self._newDisplay :
                          self.layout.display;
  
                  $el.css(transformCSS._in);
  
                  if (self.animation.animateResizeTargets) {
                      el.style.width = el.dataset.finalWidth + 'px';
                      el.style.height = el.dataset.finalHeight + 'px';
                      el.style.marginRight = -(el.dataset.finalWidth - el.dataset.interWidth) + (el.dataset.finalMarginRight * 1) + 'px';
                      el.style.marginBottom = -(el.dataset.finalHeight - el.dataset.interHeight) + (el.dataset.finalMarginBottom * 1) + 'px';
                  }
              }
  
              for (var i = 0; i < self._$pre.length; i++) {
                  var el = self._$pre[i],
                          $el = $(el),
                          translate = {
                              x: el.dataset.origPosX - el.dataset.interPosX,
                              y: el.dataset.origPosY - el.dataset.interPosY
                          },
                  transformCSS = self._getPrefixedCSS('transform', 'translate(' + translate.x + 'px,' + translate.y + 'px)');
  
                  $el.css(transformCSS);
  
                  if (self.animation.animateResizeTargets) {
                      el.style.width = el.dataset.origWidth + 'px';
                      el.style.height = el.dataset.origHeight + 'px';
  
                      if (el.dataset.origWidth - el.dataset.finalWidth) {
                          el.style.marginRight = -(el.dataset.origWidth - el.dataset.interWidth) + (el.dataset.origMarginRight * 1) + 'px';
                      }
  
                      if (el.dataset.origHeight - el.dataset.finalHeight) {
                          el.style.marginBottom = -(el.dataset.origHeight - el.dataset.interHeight) + (el.dataset.origMarginBottom * 1) + 'px';
                      }
                  }
              }
  
              self._execAction('_prepTargets', 1);
          },
          /**
           * Animate Targets
           * @since 2.0.0
           */
  
          _animateTargets: function() {
              var self = this;
  
              self._execAction('_animateTargets', 0);
  
              self._targetsDone = 0;
              self._targetsBound = 0;
  
              self._$parent
                      .css(self._getPrefixedCSS('perspective', self.animation.perspectiveDistance + 'px'))
                      .css(self._getPrefixedCSS('perspective-origin', self.animation.perspectiveOrigin));
  
              if (self.animation.animateResizeContainer) {
                  self._$parent
                          .css(self._getPrefixedCSS('transition', 'height ' + self.animation.duration + 'ms ease'))
                          .css('height', self._newHeight + 'px');
              }
  
              for (var i = 0; i < self._$toShow.length; i++) {
                  var el = self._$toShow[i],
                          $el = $(el),
                          translate = {
                              x: el.dataset.finalPosX - el.dataset.interPosX,
                              y: el.dataset.finalPosY - el.dataset.interPosY
                          },
                  delay = self._getDelay(i),
                          toShowCSS = {};
  
                  el.style.opacity = '';
  
                  for (var j = 0; j < 2; j++) {
                      var a = j === 0 ? a = self._prefix : '';
  
                      if (self._ff && self._ff <= 20) {
                          toShowCSS[a + 'transition-property'] = 'all';
                          toShowCSS[a + 'transition-timing-function'] = self.animation.easing + 'ms';
                          toShowCSS[a + 'transition-duration'] = self.animation.duration + 'ms';
                      }
  
                      toShowCSS[a + 'transition-delay'] = delay + 'ms';
                      toShowCSS[a + 'transform'] = 'translate(' + translate.x + 'px,' + translate.y + 'px)';
                  }
  
                  if (self.effects.transform || self.effects.opacity) {
                      self._bindTargetDone($el);
                  }
  
                  (self._ff && self._ff <= 20) ?
                          $el.css(toShowCSS) :
                          $el.css(self.effects.transition).css(toShowCSS);
              }
  
              for (var i = 0; i < self._$pre.length; i++) {
                  var el = self._$pre[i],
                          $el = $(el),
                          translate = {
                              x: el.dataset.finalPosX - el.dataset.interPosX,
                              y: el.dataset.finalPosY - el.dataset.interPosY
                          },
                  delay = self._getDelay(i);
  
                  if (!(
                          el.dataset.finalPosX === el.dataset.origPosX &&
                          el.dataset.finalPosY === el.dataset.origPosY
                          )) {
                      self._bindTargetDone($el);
                  }
  
                  $el.css(self._getPrefixedCSS('transition', 'all ' + self.animation.duration + 'ms ' + self.animation.easing + ' ' + delay + 'ms'));
                  $el.css(self._getPrefixedCSS('transform', 'translate(' + translate.x + 'px,' + translate.y + 'px)'));
  
                  if (self.animation.animateResizeTargets) {
                      if (el.dataset.origWidth - el.dataset.finalWidth && el.dataset.finalWidth * 1) {
                          el.style.width = el.dataset.finalWidth + 'px';
                          el.style.marginRight = -(el.dataset.finalWidth - el.dataset.interWidth) + (el.dataset.finalMarginRight * 1) + 'px';
                      }
  
                      if (el.dataset.origHeight - el.dataset.finalHeight && el.dataset.finalHeight * 1) {
                          el.style.height = el.dataset.finalHeight + 'px';
                          el.style.marginBottom = -(el.dataset.finalHeight - el.dataset.interHeight) + (el.dataset.finalMarginBottom * 1) + 'px';
                      }
                  }
              }
  
              if (self._changingClass) {
                  self._$container
                          .removeClass(self.layout.containerClass)
                          .addClass(self._newClass);
              }
  
              for (var i = 0; i < self._$toHide.length; i++) {
                  var el = self._$toHide[i],
                          $el = $(el),
                          delay = self._getDelay(i),
                          toHideCSS = {};
  
                  for (var j = 0; j < 2; j++) {
                      var a = j === 0 ? a = self._prefix : '';
  
                      toHideCSS[a + 'transition-delay'] = delay + 'ms';
                      toHideCSS[a + 'transform'] = self.effects.transformOut;
                      toHideCSS.opacity = self.effects.opacity;
                  }
  
                  $el.css(self.effects.transition).css(toHideCSS);
  
                  if (self.effects.transform || self.effects.opacity) {
                      self._bindTargetDone($el);
                  }
                  ;
              }
  
              self._execAction('_animateTargets', 1);
  
          },
          /**
           * Bind Targets TransitionEnd
           * @since 2.0.0
           * @param {object} $el
           */
  
          _bindTargetDone: function($el) {
              var self = this,
                      el = $el[0];
  
              self._execAction('_bindTargetDone', 0, arguments);
  
              if (!el.dataset.bound) {
  
                  el.dataset.bound = true;
                  self._targetsBound++;
  
                  $el.on('webkitTransitionEnd.mixItUp transitionend.mixItUp', function(e) {
                      if (
                              (e.originalEvent.propertyName.indexOf('transform') > -1 ||
                                      e.originalEvent.propertyName.indexOf('opacity') > -1) &&
                              $(e.originalEvent.target).is(self.selectors.target)
                              ) {
                          $el.off('.mixItUp');
                          delete el.dataset.bound;
                          self._targetDone();
                      }
                  });
              }
  
              self._execAction('_bindTargetDone', 1, arguments);
          },
          /**
           * Target Done
           * @since 2.0.0
           */
  
          _targetDone: function() {
              var self = this;
  
              self._execAction('_targetDone', 0);
  
              self._targetsDone++;
  
              (self._targetsDone === self._targetsBound) && self._cleanUp();
  
              self._execAction('_targetDone', 1);
          },
          /**
           * Clean Up
           * @since 2.0.0
           */
  
          _cleanUp: function() {
              var self = this,
                      targetStyles = self.animation.animateResizeTargets ? 'transform opacity width height margin-bottom margin-right' : 'transform opacity';
              unBrake = function() {
                  self._$targets.removeStyle('transition', self._prefix);
              };
  
              self._execAction('_cleanUp', 0);
  
              !self._changingLayout ?
                      self._$show.css('display', self.layout.display) :
                      self._$show.css('display', self._newDisplay);
  
              self._$targets.css(self._brake);
  
              self._$targets
                      .removeStyle(targetStyles, self._prefix)
                      .removeAttr('data-inter-pos-x data-inter-pos-y data-final-pos-x data-final-pos-y data-orig-pos-x data-orig-pos-y data-orig-height data-orig-width data-final-height data-final-width data-inter-width data-inter-height data-orig-margin-right data-orig-margin-bottom data-inter-margin-right data-inter-margin-bottom data-final-margin-right data-final-margin-bottom');
  
              self._$hide.removeStyle('display');
  
              self._$parent.removeStyle('height transition perspective-distance perspective perspective-origin-x perspective-origin-y perspective-origin perspectiveOrigin', self._prefix);
  
              if (self._sorting) {
                  self._printSort();
                  self._activeSort = self._newSortString;
                  self._sorting = false;
              }
  
              if (self._changingLayout) {
                  if (self._changingDisplay) {
                      self.layout.display = self._newDisplay;
                      self._changingDisplay = false;
                  }
  
                  if (self._changingClass) {
                      self._$parent.removeClass(self.layout.containerClass).addClass(self._newClass);
                      self.layout.containerClass = self._newClass;
                      self._changingClass = false;
                  }
  
                  self._changingLayout = false;
              }
  
              self._refresh();
  
              self._buildState();
  
              if (self._state.fail) {
                  self._$container.addClass(self.layout.containerClassFail);
              }
  
              self._$show = $();
              self._$hide = $();
  
              if (window.requestAnimationFrame) {
                  requestAnimationFrame(unBrake);
              }
  
              self._mixing = false;
  
              if (typeof self.callbacks._user === 'function') {
                  self.callbacks._user.call(self._domNode, self._state, self);
              }
  
              if (typeof self.callbacks.onMixEnd === 'function') {
                  self.callbacks.onMixEnd.call(self._domNode, self._state, self);
              }
  
              self._$container.trigger('mixEnd', [self._state, self]);
  
              if (self._state.fail) {
                  (typeof self.callbacks.onMixFail === 'function') && self.callbacks.onMixFail.call(self._domNode, self._state, self);
                  self._$container.trigger('mixFail', [self._state, self]);
              }
  
              if (self._loading) {
                  (typeof self.callbacks.onMixLoad === 'function') && self.callbacks.onMixLoad.call(self._domNode, self._state, self);
                  self._$container.trigger('mixLoad', [self._state, self]);
              }
  
              if (self._queue.length) {
                  self._execAction('_queue', 0);
  
                  self.multiMix(self._queue[0][0], self._queue[0][1], self._queue[0][2]);
                  self._queue.splice(0, 1);
              }
  
              self._execAction('_cleanUp', 1);
  
              self._loading = false;
          },
          /**
           * Get Prefixed CSS
           * @since 2.0.0
           * @param {string} property
           * @param {string} value
           * @param {boolean} prefixValue
           * @return {object} styles
           */
  
          _getPrefixedCSS: function(property, value, prefixValue) {
              var self = this,
                      styles = {};
  
              for (i = 0; i < 2; i++) {
                  var prefix = i === 0 ? self._prefix : '';
                  prefixValue ? styles[prefix + property] = prefix + value : styles[prefix + property] = value;
              }
  
              return self._execFilter('_getPrefixedCSS', styles, arguments);
          },
          /**
           * Get Delay
           * @since 2.0.0
           * @param {number} i
           * @return {number} delay
           */
  
          _getDelay: function(i) {
              var self = this,
                      n = typeof self.animation.staggerSequence === 'function' ? self.animation.staggerSequence.call(self._domNode, i, self._state) : i,
                      delay = self.animation.stagger ? n * self.animation.staggerDuration : 0;
  
              return self._execFilter('_getDelay', delay, arguments);
          },
          /**
           * Parse MultiMix Arguments
           * @since 2.0.0
           * @param {array} args
           * @return {object} output
           */
  
          _parseMultiMixArgs: function(args) {
              var self = this,
                      output = {
                          command: null,
                          animate: self.animation.enable,
                          callback: null
                      };
  
              for (var i = 0; i < args.length; i++) {
                  var arg = args[i];
  
                  if (arg !== null) {
                      if (typeof arg === 'object' || typeof arg === 'string') {
                          output.command = arg;
                      } else if (typeof arg === 'boolean') {
                          output.animate = arg;
                      } else if (typeof arg === 'function') {
                          output.callback = arg;
                      }
                  }
              }
  
              return self._execFilter('_parseMultiMixArgs', output, arguments);
          },
          /**
           * Parse Insert Arguments
           * @since 2.0.0
           * @param {array} args
           * @return {object} output
           */
  
          _parseInsertArgs: function(args) {
              var self = this,
                      output = {
                          index: 0,
                          $object: $(),
                          multiMix: {filter: self._state.activeFilter},
                          callback: null
                      };
  
              for (var i = 0; i < args.length; i++) {
                  var arg = args[i];
  
                  if (typeof arg === 'number') {
                      output.index = arg;
                  } else if (typeof arg === 'object' && arg instanceof $) {
                      output.$object = arg;
                  } else if (typeof arg === 'object' && self._helpers._isElement(arg)) {
                      output.$object = $(arg);
                  } else if (typeof arg === 'object' && arg !== null) {
                      output.multiMix = arg;
                  } else if (typeof arg === 'boolean' && !arg) {
                      output.multiMix = false;
                  } else if (typeof arg === 'function') {
                      output.callback = arg;
                  }
              }
  
              return self._execFilter('_parseInsertArgs', output, arguments);
          },
          /**
           * Execute Action
           * @since 2.0.0
           * @param {string} methodName
           * @param {boolean} isPost
           * @param {array} args
           */
  
          _execAction: function(methodName, isPost, args) {
              var self = this,
                      context = isPost ? 'post' : 'pre';
  
              if (!self._actions.isEmptyObject && self._actions.hasOwnProperty(methodName)) {
                  for (var key in self._actions[methodName][context]) {
                      self._actions[methodName][context][key].call(self, args);
                  }
              }
          },
          /**
           * Execute Filter
           * @since 2.0.0
           * @param {string} methodName
           * @param {mixed} value
           * @return {mixed} value
           */
  
          _execFilter: function(methodName, value, args) {
              var self = this;
  
              if (!self._filters.isEmptyObject && self._filters.hasOwnProperty(methodName)) {
                  for (var key in self._filters[methodName]) {
                      return self._filters[methodName][key].call(self, args);
                  }
              } else {
                  return value;
              }
          },
          /* Helpers
           ---------------------------------------------------------------------- */
  
          _helpers: {
              /**
               * CamelCase
               * @since 2.0.0
               * @param {string}
               * @return {string}
               */
  
              _camelCase: function(string) {
                  return string.replace(/-([a-z])/g, function(g) {
                      return g[1].toUpperCase();
                  });
              },
              /**
               * Is Element
               * @since 2.1.3
               * @param {object} element to test
               * @return {boolean}
               */
  
              _isElement: function(el) {
                  if (window.HTMLElement) {
                      return el instanceof HTMLElement;
                  } else {
                      return (
                              el !== null &&
                              el.nodeType === 1 &&
                              el.nodeName === 'string'
                              );
                  }
              }
          },
          /* Public Methods
           ---------------------------------------------------------------------- */
  
          /**
           * Is Mixing
           * @since 2.0.0
           * @return {boolean}
           */
  
          isMixing: function() {
              var self = this;
  
              return self._execFilter('isMixing', self._mixing);
          },
          /**
           * Filter (public)
           * @since 2.0.0
           * @param {array} arguments
           */
  
          filter: function() {
              var self = this,
                      args = self._parseMultiMixArgs(arguments);
  
              self._clicking && (self._toggleString = '');
  
              self.multiMix({filter: args.command}, args.animate, args.callback);
          },
          /**
           * Sort (public)
           * @since 2.0.0
           * @param {array} arguments
           */
  
          sort: function() {
              var self = this,
                      args = self._parseMultiMixArgs(arguments);
  
              self.multiMix({sort: args.command}, args.animate, args.callback);
          },
          /**
           * Change Layout (public)
           * @since 2.0.0
           * @param {array} arguments
           */
  
          changeLayout: function() {
              var self = this,
                      args = self._parseMultiMixArgs(arguments);
  
              self.multiMix({changeLayout: args.command}, args.animate, args.callback);
          },
          /**
           * MultiMix
           * @since 2.0.0
           * @param {array} arguments
           */
  
          multiMix: function() {
              var self = this,
                      args = self._parseMultiMixArgs(arguments);
  
              self._execAction('multiMix', 0, arguments);
  
              if (!self._mixing) {
                  if (self.controls.enable && !self._clicking) {
                      self.controls.toggleFilterButtons && self._buildToggleArray();
                      self._updateControls(args.command, self.controls.toggleFilterButtons);
                  }
  
                  (self._queue.length < 2) && (self._clicking = false);
  
                  delete self.callbacks._user;
                  if (args.callback)
                      self.callbacks._user = args.callback;
  
                  var sort = args.command.sort,
                          filter = args.command.filter,
                          changeLayout = args.command.changeLayout;
  
                  self._refresh();
  
                  if (sort) {
                      self._newSort = self._parseSort(sort);
                      self._newSortString = sort;
  
                      self._sorting = true;
                      self._sort();
                  }
  
                  if (filter !== undf) {
                      filter = (filter === 'all') ? self.selectors.target : filter;
  
                      self._activeFilter = filter;
                  }
  
                  self._filter();
  
                  if (changeLayout) {
                      self._newDisplay = (typeof changeLayout === 'string') ? changeLayout : changeLayout.display || self.layout.display;
                      self._newClass = changeLayout.containerClass || '';
  
                      if (
                              self._newDisplay !== self.layout.display ||
                              self._newClass !== self.layout.containerClass
                              ) {
                          self._changingLayout = true;
  
                          self._changingClass = (self._newClass !== self.layout.containerClass);
                          self._changingDisplay = (self._newDisplay !== self.layout.display);
                      }
                  }
  
                  self._$targets.css(self._brake);
  
                  self._goMix(args.animate ^ self.animation.enable ? args.animate : self.animation.enable);
  
                  self._execAction('multiMix', 1, arguments);
  
              } else {
                  if (self.animation.queue && self._queue.length < self.animation.queueLimit) {
                      self._queue.push(arguments);
  
                      (self.controls.enable && !self._clicking) && self._updateControls(args.command);
  
                      self._execAction('multiMixQueue', 1, arguments);
  
                  } else {
                      if (typeof self.callbacks.onMixBusy === 'function') {
                          self.callbacks.onMixBusy.call(self._domNode, self._state, self);
                      }
                      self._$container.trigger('mixBusy', [self._state, self]);
  
                      self._execAction('multiMixBusy', 1, arguments);
                  }
              }
          },
          /**
           * Insert
           * @since 2.0.0
           * @param {array} arguments
           */
  
          insert: function() {
              var self = this,
                      args = self._parseInsertArgs(arguments),
                      callback = (typeof args.callback === 'function') ? args.callback : null,
                      frag = document.createDocumentFragment(),
                      target = (function() {
                          self._refresh();
  
                          if (self._$targets.length) {
                              return (args.index < self._$targets.length || !self._$targets.length) ?
                                      self._$targets[args.index] :
                                      self._$targets[self._$targets.length - 1].nextElementSibling;
                          } else {
                              return self._$parent[0].children[0];
                          }
                      })();
  
              self._execAction('insert', 0, arguments);
  
              if (args.$object) {
                  for (var i = 0; i < args.$object.length; i++) {
                      var el = args.$object[i];
  
                      frag.appendChild(el);
                      frag.appendChild(document.createTextNode(' '));
                  }
  
                  self._$parent[0].insertBefore(frag, target);
              }
  
              self._execAction('insert', 1, arguments);
  
              if (typeof args.multiMix === 'object') {
                  self.multiMix(args.multiMix, callback);
              }
          },
          /**
           * Prepend
           * @since 2.0.0
           * @param {array} arguments
           */
  
          prepend: function() {
              var self = this,
                      args = self._parseInsertArgs(arguments);
  
              self.insert(0, args.$object, args.multiMix, args.callback);
          },
          /**
           * Append
           * @since 2.0.0
           * @param {array} arguments
           */
  
          append: function() {
              var self = this,
                      args = self._parseInsertArgs(arguments);
  
              self.insert(self._state.totalTargets, args.$object, args.multiMix, args.callback);
          },
          /**
           * Get Option
           * @since 2.0.0
           * @param {string} string
           * @return {mixed} value
           */
  
          getOption: function(string) {
              var self = this,
                      getProperty = function(obj, prop) {
                          var parts = prop.split('.'),
                                  last = parts.pop(),
                                  l = parts.length,
                                  i = 1,
                                  current = parts[0] || prop;
  
                          while ((obj = obj[current]) && i < l) {
                              current = parts[i];
                              i++;
                          }
  
                          if (obj !== undf) {
                              return obj[last] !== undf ? obj[last] : obj;
                          }
                      };
  
              return string ? self._execFilter('getOption', getProperty(self, string), arguments) : self;
          },
          /**
           * Set Options
           * @since 2.0.0
           * @param {object} config
           */
  
          setOptions: function(config) {
              var self = this;
  
              self._execAction('setOptions', 0, arguments);
  
              typeof config === 'object' && $.extend(true, self, config);
  
              self._execAction('setOptions', 1, arguments);
          },
          /**
           * Get State
           * @since 2.0.0
           * @return {object} state
           */
  
          getState: function() {
              var self = this;
  
              return self._execFilter('getState', self._state, self);
          },
          /**
           * Force Refresh
           * @since 2.1.2
           */
  
          forceRefresh: function() {
              var self = this;
  
              self._refresh(false, true);
          },
          /**
           * Destroy
           * @since 2.0.0
           * @param {boolean} hideAll
           */
  
          destroy: function(hideAll) {
              var self = this;
  
              self._execAction('destroy', 0, arguments);
  
              self._$body
                      .add($(self.selectors.sort))
                      .add($(self.selectors.filter))
                      .off('.mixItUp');
  
              for (var i = 0; i < self._$targets.length; i++) {
                  var target = self._$targets[i];
  
                  hideAll && (target.style.display = '');
  
                  delete target.mixParent;
              }
  
              self._execAction('destroy', 1, arguments);
  
              delete $.MixItUp.prototype._instances[self._id];
          }
  
      };
  
      /* jQuery Methods
       ---------------------------------------------------------------------- */
  
      /**
       * jQuery .mixItUp() method
       * @since 2.0.0
       * @extends $.fn
       */
  
      $.fn.mixItUp = function() {
          var args = arguments,
                  dataReturn = [],
                  eachReturn,
                  _instantiate = function(domNode, settings) {
                      var instance = new $.MixItUp(),
                              rand = function() {
                                  return ('00000' + (Math.random() * 16777216 << 0).toString(16)).substr(-6).toUpperCase();
                              };
  
                      instance._execAction('_instantiate', 0, arguments);
  
                      domNode.id = !domNode.id ? 'MixItUp' + rand() : domNode.id;
  
                      if (!instance._instances[domNode.id]) {
                          instance._instances[domNode.id] = instance;
                          instance._init(domNode, settings);
                      }
  
                      instance._execAction('_instantiate', 1, arguments);
                  };
  
          eachReturn = this.each(function() {
              if (args && typeof args[0] === 'string') {
                  var instance = $.MixItUp.prototype._instances[this.id];
                  if (args[0] == 'isLoaded') {
                      dataReturn.push(instance ? true : false);
                  } else {
                      var data = instance[args[0]](args[1], args[2], args[3]);
                      if (data !== undf)
                          dataReturn.push(data);
                  }
              } else {
                  _instantiate(this, args[0]);
              }
          });
  
          if (dataReturn.length) {
              return dataReturn.length > 1 ? dataReturn : dataReturn[0];
          } else {
              return eachReturn;
          }
      };
  
      /**
       * jQuery .removeStyle() method
       * @since 2.0.0
       * @extends $.fn
       */
  
      $.fn.removeStyle = function(style, prefix) {
          prefix = prefix ? prefix : '';
  
          return this.each(function() {
              var el = this,
                      styles = style.split(' ');
  
              for (var i = 0; i < styles.length; i++) {
                  for (var j = 0; j < 2; j++) {
                      var prop = j ? styles[i] : prefix + styles[i];
                      if (
                              el.style[prop] !== undf &&
                              typeof el.style[prop] !== 'unknown' &&
                              el.style[prop].length > 0
                              ) {
                          el.style[prop] = '';
                      }
                      if (!prefix)
                          break;
                  }
              }
  
              if (el.attributes && el.attributes.style && el.attributes.style !== undf && el.attributes.style.nodeValue === '') {
                  el.attributes.removeNamedItem('style');
              }
          });
      };
  
  })(jQuery);