PageSourceSearch

https://randysuttonspeaks.com/sites/all/themes/athlete/js/jquery.mixitup.js?sco4vy

js randysuttonspeaks.com collected 2026-10-10 00:59:29 UTC 70,880 bytes, 2,006 lines download raw bytes

1/**!
2 * MixItUp v2.1.5
3 *
4 * @copyright Copyright 2014 KunkaLabs Limited.
5 * @author    KunkaLabs Limited.
6 * @link      https://mixitup.kunkalabs.com
7 *
8 * @license   Commercial use requires a commercial license.
9 *            https://mixitup.kunkalabs.com/licenses/
10 *
11 *            Non-commercial use permitted under terms of CC-BY-NC license.
12 *            http://creativecommons.org/licenses/by-nc/3.0/
13 */
14
15(function($, undf) {
16
17    /**
18     * MixItUp Constructor Function
19     * @constructor
20     * @extends jQuery
21     */
22
23    $.MixItUp = function() {
24        var self = this;
25
26        self._execAction('_constructor', 0);
27
28        $.extend(self, {
29            /* Public Properties
30             ---------------------------------------------------------------------- */
31
32            selectors: {
33                target: '.mix',
34                filter: '.filter',
35                sort: '.sort'
36            },
37            animation: {
38                enable: true,
39                effects: 'fade scale',
40                duration: 600,
41                easing: 'ease',
42                perspectiveDistance: '3000',
43                perspectiveOrigin: '50% 50%',
44                queue: true,
45                queueLimit: 1,
46                animateChangeLayout: false,
47                animateResizeContainer: true,
48                animateResizeTargets: false,
49                staggerSequence: false,
50                reverseOut: false
51            },
52            callbacks: {
53                onMixLoad: false,
54                onMixStart: false,
55                onMixBusy: false,
56                onMixEnd: false,
57                onMixFail: false,
58                _user: false
59            },
60            controls: {
61                enable: true,
62                live: false,
63                toggleFilterButtons: false,
64                toggleLogic: 'or',
65                activeClass: 'active'
66            },
67            layout: {
68                display: 'inline-block',
69                containerClass: '',
70                containerClassFail: 'fail'
71            },
72            load: {
73                filter: 'all',
74                sort: false
75            },
76            /* Private Properties
77             ---------------------------------------------------------------------- */
78
79            _$body: null,
80            _$container: null,
81            _$targets: null,
82            _$parent: null,
83            _$sortButtons: null,
84            _$filterButtons: null,
85            _suckMode: false,
86            _mixing: false,
87            _sorting: false,
88            _clicking: false,
89            _loading: true,
90            _changingLayout: false,
91            _changingClass: false,
92            _changingDisplay: false,
93            _origOrder: [],
94            _startOrder: [],
95            _newOrder: [],
96            _activeFilter: null,
97            _toggleArray: [],
98            _toggleString: '',
99            _activeSort: 'default:asc',
100            _newSort: null,
101            _startHeight: null,
102            _newHeight: null,
103            _incPadding: true,
104            _newDisplay: null,
105            _newClass: null,
106            _targetsBound: 0,
107            _targetsDone: 0,
108            _queue: [],
109            _$show: $(),
110            _$hide: $()
111        });
112
113        self._execAction('_constructor', 1);
114    };
115
116    /**
117     * MixItUp Prototype
118     * @override
119     */
120
121    $.MixItUp.prototype = {
122        constructor: $.MixItUp,
123        /* Static Properties
124         ---------------------------------------------------------------------- */
125
126        _instances: {},
127        _handled: {
128            _filter: {},
129            _sort: {}
130        },
131        _bound: {
132            _filter: {},
133            _sort: {}
134        },
135        _actions: {},
136        _filters: {},
137        /* Static Methods
138         ---------------------------------------------------------------------- */
139
140        /**
141         * Extend
142         * @since 2.1.0
143         * @param {object} new properties/methods
144         * @extends {object} prototype
145         */
146
147        extend: function(extension) {
148            for (var key in extension) {
149                $.MixItUp.prototype[key] = extension[key];
150            }
151        },
152        /**
153         * Add Action
154         * @since 2.1.0
155         * @param {string} hook name
156         * @param {string} namespace
157         * @param {function} function to execute
158         * @param {number} priority
159         * @extends {object} $.MixItUp.prototype._actions
160         */
161
162        addAction: function(hook, name, func, priority) {
163            $.MixItUp.prototype._addHook('_actions', hook, name, func, priority);
164        },
165        /**
166         * Add Filter
167         * @since 2.1.0
168         * @param {string} hook name
169         * @param {string} namespace
170         * @param {function} function to execute
171         * @param {number} priority
172         * @extends {object} $.MixItUp.prototype._filters
173         */
174
175        addFilter: function(hook, name, func, priority) {
176            $.MixItUp.prototype._addHook('_filters', hook, name, func, priority);
177        },
178        /**
179         * Add Hook
180         * @since 2.1.0
181         * @param {string} type of hook
182         * @param {string} hook name
183         * @param {function} function to execute
184         * @param {number} priority
185         * @extends {object} $.MixItUp.prototype._filters
186         */
187
188        _addHook: function(type, hook, name, func, priority) {
189            var collection = $.MixItUp.prototype[type],
190                    obj = {};
191
192            priority = (priority === 1 || priority === 'post') ? 'post' : 'pre';
193
194            obj[hook] = {};
195            obj[hook][priority] = {};
196            obj[hook][priority][name] = func;
197
198            $.extend(true, collection, obj);
199      },
200        /* Private Methods
201         ---------------------------------------------------------------------- */
202
203        /**
204         * Initialise
205         * @since 2.0.0
206         * @param {object} domNode
207         * @param {object} config
208         */
209
210        _init: function(domNode, config) {
211            var self = this;
212
213            self._execAction('_init', 0, arguments);
214
215            config && $.extend(true, self, config);
216
217            self._$body = $('body');
218            self._domNode = domNode;
219            self._$container = $(domNode);
220            self._$container.addClass(self.layout.containerClass);
221            self._id = domNode.id;
222
223            self._platformDetect();
224
225            self._brake = self._getPrefixedCSS('transition', 'none');
226
227            self._refresh(true);
228
229            self._$parent = self._$targets.parent().length ? self._$targets.parent() : self._$container;
230
231            if (self.load.sort) {
232                self._newSort = self._parseSort(self.load.sort);
233                self._newSortString = self.load.sort;
234                self._activeSort = self.load.sort;
235                self._sort();
236                self._printSort();
237            }
238
239            self._activeFilter = self.load.filter === 'all' ?
240                    self.selectors.target :
241                    self.load.filter === 'none' ?
242                    '' :
243                    self.load.filter;
244
245            self.controls.enable && self._bindHandlers();
246
247            if (self.controls.toggleFilterButtons) {
248                self._buildToggleArray();
249
250                for (var i = 0; i < self._toggleArray.length; i++) {
251                    self._updateControls({filter: self._toggleArray[i], sort: self._activeSort}, true);
252                }
253                ;
254            } else if (self.controls.enable) {
255                self._updateControls({filter: self._activeFilter, sort: self._activeSort});
256            }
257
258            self._filter();
259
260            self._init = true;
261
262            self._$container.data('mixItUp', self);
263
264            self._execAction('_init', 1, arguments);
265
266            self._buildState();
267
268            self._$targets.css(self._brake);
269
270            self._goMix(self.animation.enable);
271        },
272        /**
273         * Platform Detect
274         * @since 2.0.0
275         */
276
277        _platformDetect: function() {
278            var self = this,
279                    vendorsTrans = ['Webkit', 'Moz', 'O', 'ms'],
280                    vendorsRAF = ['webkit', 'moz'],
281                    chrome = window.navigator.appVersion.match(/Chrome\/(\d+)\./) || false,
282                    ff = typeof InstallTrigger !== 'undefined',
283                    prefix = function(el) {
284                        for (var i = 0; i < vendorsTrans.length; i++) {
285                            if (vendorsTrans[i] + 'Transition' in el.style) {
286                                return {
287                                    prefix: '-' + vendorsTrans[i].toLowerCase() + '-',
288                                    vendor: vendorsTrans[i]
289                                };
290                            }
291                            ;
292                        }
293                        ;
294                        return 'transition' in el.style ? '' : false;
295                    },
296                    transPrefix = prefix(self._domNode);
297
298            self._execAction('_platformDetect', 0);
299
300            self._chrome = chrome ? parseInt(chrome[1], 10) : false;
301            self._ff = ff ? parseInt(window.navigator.userAgent.match(/rv:([^)]+)\)/)[1]) : false;
302            self._prefix = transPrefix.prefix;
303            self._vendor = transPrefix.vendor;
304            self._suckMode = window.atob && self._prefix ? false : true;
305
306            self._suckMode && (self.animation.enable = false);
307            (self._ff && self._ff <= 4) && (self.animation.enable = false);
308
309            /* Polyfills
310             ---------------------------------------------------------------------- */
311
312            /**
313             * window.requestAnimationFrame
314             */
315
316            for (var x = 0; x < vendorsRAF.length && !window.requestAnimationFrame; x++) {
317                window.requestAnimationFrame = window[vendorsRAF[x] + 'RequestAnimationFrame'];
318            }
319
320            /**
321             * Object.getPrototypeOf
322             */
323
324            if (typeof Object.getPrototypeOf !== 'function') {
325                if (typeof 'test'.__proto__ === 'object') {
326                    Object.getPrototypeOf = function(object) {
327                        return object.__proto__;
328                    };
329                } else {
330                    Object.getPrototypeOf = function(object) {
331                        return object.constructor.prototype;
332                    };
333                }
334            }
335
336            /**
337             * Element.nextElementSibling
338             */
339
340            if (self._domNode.nextElementSibling === undf) {
341                Object.defineProperty(Element.prototype, 'nextElementSibling', {
342                    get: function() {
343                        var el = this.nextSibling;
344
345                        while (el) {
346                            if (el.nodeType === 1) {
347                                return el;
348                            }
349                            el = el.nextSibling;
350                        }
351                        return null;
352                    }
353                });
354            }
355
356            self._execAction('_platformDetect', 1);
357        },
358        /**
359         * Refresh
360         * @since 2.0.0
361         * @param {boolean} init
362         * @param {boolean} force
363         */
364
365        _refresh: function(init, force) {
366            var self = this;
367
368            self._execAction('_refresh', 0, arguments);
369
370            self._$targets = self._$container.find(self.selectors.target);
371
372            for (var i = 0; i < self._$targets.length; i++) {
373                var target = self._$targets[i];
374
375                if (target.dataset === undf || force) {
376
377                    target.dataset = {};
378
379                    for (var j = 0; j < target.attributes.length; j++) {
380
381                        var attr = target.attributes[j],
382                                name = attr.name,
383                                val = attr.nodeValue;
384
385                        if (name.indexOf('data-') > -1) {
386                            var dataName = self._helpers._camelCase(name.substring(5, name.length));
387                            target.dataset[dataName] = val;
388                        }
389                    }
390                }
391
392                if (target.mixParent === undf) {
393                    target.mixParent = self._id;
394                }
395            }
396
397            if (
398                    (self._$targets.length && init) ||
399                    (!self._origOrder.length && self._$targets.length)
400                    ) {
401                self._origOrder = [];
402
403                for (var i = 0; i < self._$targets.length; i++) {
404                    var target = self._$targets[i];
405
406                    self._origOrder.push(target);
407                }
408            }
409
410            self._execAction('_refresh', 1, arguments);
411        },
412        /**
413         * Bind Handlers
414         * @since 2.0.0
415         */
416
417        _bindHandlers: function() {
418            var self = this,
419                    filters = $.MixItUp.prototype._bound._filter,
420                    sorts = $.MixItUp.prototype._bound._sort;
421
422            self._execAction('_bindHandlers', 0);
423
424            if (self.controls.live) {
425                self._$body
426                        .on('click.mixItUp.' + self._id, self.selectors.sort, function() {
427                            self._processClick($(this), 'sort');
428                        })
429                        .on('click.mixItUp.' + self._id, self.selectors.filter, function() {
430                            self._processClick($(this), 'filter');
431                        });
432            } else {
433                self._$sortButtons = $(self.selectors.sort);
434                self._$filterButtons = $(self.selectors.filter);
435
436                self._$sortButtons.on('click.mixItUp.' + self._id, function() {
437                    self._processClick($(this), 'sort');
438                });
439
440                self._$filterButtons.on('click.mixItUp.' + self._id, function() {
441                    self._processClick($(this), 'filter');
442                });
443            }
444
445            filters[self.selectors.filter] = (filters[self.selectors.filter] === undf) ? 1 : filters[self.selectors.filter] + 1;
446            sorts[self.selectors.sort] = (sorts[self.selectors.sort] === undf) ? 1 : sorts[self.selectors.sort] + 1;
447
448            self._execAction('_bindHandlers', 1);
449        },
450        /**
451         * Process Click
452         * @since 2.0.0
453         * @param {object} $button
454         * @param {string} type
455         */
456
457        _processClick: function($button, type) {
458            var self = this,
459                    trackClick = function($button, type, off) {
460                        var proto = $.MixItUp.prototype;
461
462                        proto._handled['_' + type][self.selectors[type]] = (proto._handled['_' + type][self.selectors[type]] === undf) ?
463                                1 :
464                                proto._handled['_' + type][self.selectors[type]] + 1;
465
466                        if (proto._handled['_' + type][self.selectors[type]] === proto._bound['_' + type][self.selectors[type]]
466) {
467                            $button[(off ? 'remove' : 'add') + 'Class'](self.controls.activeClass);
468                            delete proto._handled['_' + type][self.selectors[type]];
469                        }
470                    };
471
472            self._execAction('_processClick', 0, arguments);
473
474            if (!self._mixing || (self.animation.queue && self._queue.length < self.animation.queueLimit)) {
475                self._clicking = true;
476
477                if (type === 'sort') {
478                    var sort = $button.attr('data-sort');
479
480                    if (!$button.hasClass(self.controls.activeClass) || sort.indexOf('random') > -1) {
481                        $(self.selectors.sort).removeClass(self.controls.activeClass);
482                        trackClick($button, type);
483                        self.sort(sort);
484                    }
485                }
486
487                if (type === 'filter') {
488                    var filter = $button.attr('data-filter'),
489                            ndx,
490                            seperator = self.controls.toggleLogic === 'or' ? ',' : '';
491
492                    if (!self.controls.toggleFilterButtons) {
493                        if (!$button.hasClass(self.controls.activeClass)) {
494                            $(self.selectors.filter).removeClass(self.controls.activeClass);
495                            trackClick($button, type);
496                            self.filter(filter);
497                        }
498                    } else {
499                        self._buildToggleArray();
500
501                        if (!$button.hasClass(self.controls.activeClass)) {
502                            trackClick($button, type);
503
504                            self._toggleArray.push(filter);
505                        } else {
506                            trackClick($button, type, true);
507                            ndx = self._toggleArray.indexOf(filter);
508                            self._toggleArray.splice(ndx, 1);
509                        }
510
511                        self._toggleArray = $.grep(self._toggleArray, function(n) {
512                            return(n);
513                        });
514
515                        self._toggleString = self._toggleArray.join(seperator);
516
517                        self.filter(self._toggleString);
518                    }
519                }
520
521                self._execAction('_processClick', 1, arguments);
522            } else {
523                if (typeof self.callbacks.onMixBusy === 'function') {
524                    self.callbacks.onMixBusy.call(self._domNode, self._state, self);
525                }
526                self._execAction('_processClickBusy', 1, arguments);
527            }
528        },
529        /**
530         * Build Toggle Array
531         * @since 2.0.0
532         */
533
534        _buildToggleArray: function() {
535            var self = this,
536                    activeFilter = self._activeFilter.replace(/\s/g, '');
537
538            self._execAction('_buildToggleArray', 0, arguments);
539
540            if (self.controls.toggleLogic === 'or') {
541                self._toggleArray = activeFilter.split(',');
542            } else {
543                self._toggleArray = activeFilter.split('.');
544
545                !self._toggleArray[0] && self._toggleArray.shift();
546
547                for (var i = 0, filter; filter = self._toggleArray[i]; i++) {
548                    self._toggleArray[i] = '.' + filter;
549                }
550            }
551
552            self._execAction('_buildToggleArray', 1, arguments);
553        },
554        /**
555         * Update Controls
556         * @since 2.0.0
557         * @param {object} command
558         * @param {boolean} multi
559         */
560
561        _updateControls: function(command, multi) {
562            var self = this,
563                    output = {
564                        filter: command.filter,
565                        sort: command.sort
566                    },
567            update = function($el, filter) {
568                (multi && type == 'filter' && !(output.filter === 'none' || output.f
568ilter === '')) ?
569                        $el.filter(filter).addClass(self.controls.activeClass) :
570                        $el.removeClass(self.controls.activeClass).filter(filter).addClass(self.controls.activeClass);
571            },
572                    type = 'filter',
573                    $el = null;
574
575            self._execAction('_updateControls', 0, arguments);
576
577            (command.filter === undf) && (output.filter = self._activeFilter);
578            (command.sort === undf) && (output.sort = self._activeSort);
579            (output.filter === self.selectors.target) && (output.filter = 'all');
580
581            for (var i = 0; i < 2; i++) {
582                $el = self.controls.live ? $(self.selectors[type]) : self['_$' + type + 'Buttons'];
583                $el && update($el, '[data-' + type + '="' + output[type] + '"]');
584                type = 'sort';
585            }
586
587            self._execAction('_updateControls', 1, arguments);
588        },
589        /**
590         * Filter (private)
591         * @since 2.0.0
592         */
593
594        _filter: function() {
595            var self = this;
596
597            self._execAction('_filter', 0);
598
599            for (var i = 0; i < self._$targets.length; i++) {
600                var $target = $(self._$targets[i]);
601
602                if ($target.is(self._activeFilter)) {
603                    self._$show = self._$show.add($target);
604                } else {
605                    self._$hide = self._$hide.add($target);
606                }
607            }
608
609            self._execAction('_filter', 1);
610        },
611        /**
612         * Sort (private)
613         * @since 2.0.0
614         */
615
616        _sort: function() {
617            var self = this,
618                    arrayShuffle = function(oldArray) {
619                        var newArray = oldArray.slice(),
620                                len = newArray.length,
621                                i = len;
622
623                        while (i--) {
624                            var p = parseInt(Math.random() * len);
625                            var t = newArray[i];
626                            newArray[i] = newArray[p];
627                            newArray[p] = t;
628                        }
629                        ;
630                        return newArray;
631                    };
632
633            self._execAction('_sort', 0);
634
635            self._startOrder = [];
636
637            for (var i = 0; i < self._$targets.length; i++) {
638                var target = self._$targets[i];
639
640                self._startOrder.push(target);
641            }
642
643            switch (self._newSort[0].sortBy) {
644                case 'default':
645                    self._newOrder = self._origOrder;
646                    break;
647                case 'random':
648                    self._newOrder = arrayShuffle(self._startOrder);
649                    break;
650                case 'custom':
651                    self._newOrder = self._newSort[0].order;
652                    break;
653                default:
654                    self._newOrder = self._startOrder.concat().sort(function(a, b) {
655                        return self._compare(a, b);
656                    });
657            }
658
659            self._execAction('_sort', 1);
660        },
661        /**
662         * Compare Algorithm
663         * @since 2.0.0
664         * @param {string|number} a
665         * @param {string|number} b
666         * @param {number} depth (recursion)
667         * @return {number}
668         */
669
670        _compare: function(a, b, depth) {
671            depth = depth ? depth : 0;
672
673            var self = this,
674                    order = self._newSort[depth].order,
675                    getData = function(el) {
676                        return el.dataset[self._newSort[depth].sortBy] || 0;
677                    },
678                    attrA = isNaN(getData(a) * 1) ? getData(a).toLowerCase() : getData(a) * 1,
679                    attrB = isNaN(getData(b) * 1) ? getData(b).toLowerCase() : getData(b) * 1;
680
681            if (attrA < attrB)
682                return order == 'asc' ? -1 : 1;
683            if (attrA > attrB)
684                return order == 'asc' ? 1 : -1;
685            if (attrA == attrB && self._newSort.length > depth + 1)
686                return self._compare(a, b, depth + 1);
687
688            return 0;
689        },
690        /**
691         * Print Sort
692         * @since 2.0.0
693         * @param {boolean} reset
694         */
695
696        _printSort: function(reset) {
697            var self = this,
698                    order = reset ? self._startOrder : self._newOrder,
699                    targets = self._$parent[0].querySelectorAll(self.selectors.target),
700                    nextSibling = targets[targets.length - 1].nextElementSibling,
701                    frag = document.createDocumentFragment();
702
703            self._execAction('_printSort', 0, arguments);
704
705            for (var i = 0; i < targets.length; i++) {
706                var target = targets[i],
707                        whiteSpace = target.nextSibling;
708
709                if (target.style.position === 'absolute')
710                    continue;
711
712                if (whiteSpace && whiteSpace.nodeName == '#text') {
713                    self._$parent[0].removeChild(whiteSpace);
714                }
715
716                self._$parent[0].removeChild(target);
717            }
718
719            for (var i = 0; i < order.length; i++) {
720                var el = order[i];
721
722                if (self._newSort[0].sortBy == 'default' && self._newSort[0].order == 'desc' && !reset) {
723                    var firstChild = frag.firstChild;
724                    frag.insertBefore(el, firstChild);
725                    frag.insertBefore(document.createTextNode(' '), el);
726                } else {
727                    frag.appendChild(el);
728                    frag.appendChild(document.createTextNode(' '));
729                }
730            }
731
732            nextSibling ?
733                    self._$parent[0].insertBefore(frag, nextSibling) :
734                    self._$parent[0].appendChild(frag);
735
736            self._execAction('_printSort', 1, arguments);
737        },
738        /**
739         * Parse Sort
740         * @since 2.0.0
741         * @param {string} sortString
742         * @return {array} newSort
743         */
744
745        _parseSort: function(sortString) {
746            var self = this,
747                    rules = typeof sortString === 'string' ? sortString.split(' ') : [sortString],
748                    newSort = [];
749
750            for (var i = 0; i < rules.length; i++) {
751                var rule = typeof sortString === 'string' ? rules[i].split(':') : ['custom', rules[i]],
752                        ruleObj = {
753                            sortBy: self._helpers._camelCase(rule[0]),
754                            order: rule[1] || 'asc'
755                        };
756
757                newSort.push(ruleObj);
758
759                if (ruleObj.sortBy == 'default' || ruleObj.sortBy == 'random')
760                    break;
761            }
762
763            return self._execFilter('_parseSort', newSort, arguments);
764        },
765        /**
766         * Parse Effects
767         * @since 2.0.0
768         * @return {object} effects
769         */
770
771        _parseEffects: function() {
772            var self = this,
773                    effects = {
774                        opacity: '',
775                        transformIn: '',
776                        transformOut: '',
777                        filter: ''
778                    },
779            parse = function(effect, extract, reverse) {
780                if (self.animation.effects.indexOf(effect) > -1) {
781                    if (extract) {
782                        var propIndex = self.animation.effects.indexOf(effect + '(');
783                        if (propIndex > -1) {
784                            var str = self.animation.effects.substring(propIndex),
785                                    match = /\(([^)]+)\)/.exec(str),
786                                    val = match[1];
787
788                            return {val: val};
789                        }
790                    }
791                    return true;
792                } else {
793                    return false;
794                }
795            },
796                    negate = function(value, invert) {
797                        if (invert) {
798                            return value.charAt(0) === '-' ? value.substr(1, value.length) : '-' + value;
799                        } else {
800                            return value;
801                        }
802                    },
803                    buildTransform = function(key, invert) {
804                        var transforms = [
805                            ['scale', '.01'],
806                            ['translateX', '20px'],
807                            ['translateY', '20px'],
808                            ['translateZ', '20px'],
809                            ['rotateX', '90deg'],
810                            ['rotateY', '90deg'],
811                            ['rotateZ', '180deg'],
812                        ];
813
814                        for (var i = 0; i < transforms.length; i++) {
815                            var prop = transforms[i][0],
816                                    def = transforms[i][1],
817                                    inverted = invert && prop !== 'scale';
818
819                            effects[key] += parse(prop) ? prop + '(' + negate(parse(prop, true).val || def, inverted) + ') ' : '';
820                        }
821                    };
822
823            effects.opacity = parse('fade') ? parse('fade', true).val || '0' : '1';
824
825            buildTransform('transformIn');
826
827            self.animation.reverseOut ? buildTransform('transformOut', true) : (effects.transformOut = effects.transformIn);
828
829            effects.transition = {};
830
831            effects.transition = self._getPrefixedCSS('transition', 'all ' + self.animation.duration + 'ms ' + self.animation.easing + ', opacity ' + self.animation.duration + 'ms linear');
832
833            self.animation.stagger = parse('stagger') ? true : false;
834            self.animation.staggerDuration = parseInt(parse('stagger') ? (parse('stagger', true).val ? parse('stagger', true).val : 100) : 100);
835
836            return self._execFilter('_parseEffects', effects);
837        },
838        /**
839         * Build State
840         * @since 2.0.0
841         * @param {boolean} future
842         * @return {object} futureState
843         */
844
845        _buildState: function(future) {
846            var self = this,
847                    state = {};
848
849            self._execAction('_buildState', 0);
850
851            state = {
852                activeFilter: self._activeFilter === '' ? 'none' : self._activeFilter,
853                activeSort: future && self._newSortString ? self._newSortString : self._activeSort,
854                fail: !self._$show.length && self._activeFilter !== '',
855                $targets: self._$targets,
856                $show: self._$show,
857                $hide: self._$hide,
858                totalTargets: self._$targets.length,
859                totalShow: self._$show.length,
860                totalHide: self._$hide.length,
861                display: future && self._newDisplay ? self._newDisplay : self.layout.display
862            };
863
864            if (future) {
865                return self._execFilter('_buildState', state);
866            } else {
867                self._state = state;
868
869                self._execAction('_buildState', 1);
870            }
871        },
872        /**
873         * Go Mix
874         * @since 2.0.0
875         * @param {boolean} animate
876         */
877
878        _goMix: function(animate) {
879            var self = this,
880                    phase1 = function() {
881                        if (self._chrome && (self._chrome === 31)) {
882                            chromeFix(self._$parent[0]);
883                        }
884
885                        self._setInter();
886
887                        phase2();
888                    },
889                    phase2 = function() {
890                        var scrollTop = window.pageYOffset,
891                                scrollLeft = window.pageXOffset,
892                                docHeight = document.documentElement.scrollHeight;
893
894                        self._getInterMixData();
895
896                        self._setFinal();
897
898                        self._getFinalMixData();
899
900                        (window.pageYOffset !== scrollTop) && window.scrollTo(scrollLeft, scrollTop);
901
902                        self._prepTargets();
903
904                        if (window.requestAnimationFrame) {
905                            requestAnimationFrame(phase3);
906                        } else {
907                            setTimeout(function() {
908                                phase3();
909                            }, 20);
910                        }
911                    },
912                    phase3 = function() {
913                        self._animateTargets();
914
915                        if (self._targetsBound === 0) {
916                            self._cleanUp();
917                        }
918                    },
919                    chromeFix = function(grid) {
920                        var parent = grid.parentElement,
921                                placeholder = document.createElement('div'),
922                                frag = document.createDocumentFragment();
923
924                        parent.insertBefore(placeholder, grid);
925                        frag.appendChild(grid);
926                        parent.replaceChild(grid, placeholder);
927                    },
928                    futureState = self._buildState(true);
929
930            self._execAction('_goMix', 0, arguments);
931
932            !self.animation.duration && (animate = false);
933
934            self._mixing = true;
935
936            self._$container.removeClass(self.layout.containerClassFail);
937
938            if (typeof self.callbacks.onMixStart === 'function') {
939                self.callbacks.onMixStart.call(self._domNode, self._state, futureState, self);
940            }
941
942            self._$container.trigger('mixStart', [self._state, futureState, self]);
943
944            self._getOrigMixData();
945
946            if (animate && !self._suckMode) {
947
948                window.requestAnimationFrame ?
949                        requestAnimationFrame(phase1) :
950                        phase1();
951
952            } else {
953                self._cleanUp();
954            }
955
956            self._execAction('_goMix', 1, arguments);
957        },
958        /**
959         * Get Target Data
960         * @since 2.0.0
961         */
962
963        _getTargetData: function(el, stage) {
964            var self = this,
965                    elStyle;
966
967            el.dataset[stage + 'PosX'] = el.offsetLeft;
968            el.dataset[stage + 'PosY'] = el.offsetTop;
969
970            if (self.animation.animateResizeTargets) {
971                elStyle = window.getComputedStyle(el);
972
973                el.dataset[stage + 'MarginBottom'] = parseInt(elStyle.marginBottom);
974                el.dataset[stage + 'MarginRight'] = parseInt(elStyle.marginRight);
975                el.dataset[stage + 'Width'] = el.offsetWidth;
976                el.dataset[stage + 'Height'] = el.offsetHeight;
977            }
978        },
979        /**
980         * Get Original Mix Data
981         * @since 2.0.0
982         */
983
984        _getOrigMixData: function() {
985            var self = this,
986                    parentStyle = !self._suckMode ? window.getComputedStyle(self._$parent[0]) : {boxSizing: ''},
987            parentBS = parentStyle.boxSizing || parentStyle[self._vendor + 'BoxSizing'];
988
989            self._incPadding = (parentBS === 'border-box');
990
991            self._execAction('_getOrigMixData', 0);
992
993            !self._suckMode && (self.effects = self._parseEffects());
994
995            self._$toHide = self._$hide.filter(':visible');
996            self._$toShow = self._$show.filter(':hidden');
997            self._$pre = self._$targets.filter(':visible');
998
999            self._startHeight = self._incPadding ?
1000                    self._$parent.outerHeight() :
1001                    self._$parent.height();
1002
1003            for (var i = 0; i < self._$pre.length; i++) {
1004                var el = self._$pre[i];
1005
1006                self._getTargetData(el, 'orig');
1007            }
1008
1009            self._execAction('_getOrigMixData', 1);
1010        },
1011        /**
1012         * Set Intermediate Positions
1013         * @since 2.0.0
1014         */
1015
1016        _setInter: function() {
1017            var self = this;
1018
1019            self._execAction('_setInter', 0);
1020
1021            if (self._changingLayout && self.animation.animateChangeLayout) {
1022                self._$toShow.css('display', self._newDisplay);
1023
1024                if (self._changingClass) {
1025                    self._$container
1026                            .removeClass(self.layout.containerClass)
1027                            .addClass(self._newClass);
1028                }
1029            } else {
1030                self._$toShow.css('display', self.layout.display);
1031            }
1032
1033            self._execAction('_setInter', 1);
1034        },
1035        /**
1036         * Get Intermediate Mix Data
1037         * @since 2.0.0
1038         */
1039
1040        _getInterMixData: function() {
1041            var self = this;
1042
1043            self._execAction('_getInterMixData', 0);
1044
1045            for (var i = 0; i < self._$toShow.length; i++) {
1046                var el = self._$toShow[i];
1047
1048                self._getTargetData(el, 'inter');
1049            }
1050
1051            for (var i = 0; i < self._$pre.length; i++) {
1052                var el = self._$pre[i];
1053
1054                self._getTargetData(el, 'inter');
1055            }
1056
1057            self._execAction('_getInterMixData', 1);
1058        },
1059        /**
1060         * Set Final Positions
1061         * @since 2.0.0
1062         */
1063
1064        _setFinal: function() {
1065            var self = this;
1066
1067            self._execAction('_setFinal', 0);
1068
1069            self._sorting && self._printSort();
1070
1071            self._$toHide.removeStyle('display');
1072
1073            if (self._changingLayout && self.animation.animateChangeLayout) {
1074                self._$pre.css('display', self._newDisplay);
1075            }
1076
1077            self._execAction('_setFinal', 1);
1078        },
1079        /**
1080         * Get Final Mix Data
1081         * @since 2.0.0
1082         */
1083
1084        _getFinalMixData: function() {
1085            var self = this;
1086
1087            self._execAction('_getFinalMixData', 0);
1088
1089            for (var i = 0; i < self._$toShow.length; i++) {
1090                var el = self._$toShow[i];
1091
1092                self._getTargetData(el, 'final');
1093            }
1094
1095            for (var i = 0; i < self._$pre.length; i++) {
1096                var el = self._$pre[i];
1097
1098                self._getTargetData(el, 'final');
1099            }
1100
1101            self._newHeight = self._incPadding ?
1102                    self._$parent.outerHeight() :
1103                    self._$parent.height();
1104
1105            self._sorting && self._printSort(true);
1106
1107            self._$toShow.removeStyle('display');
1108
1109            self._$pre.css('display', self.layout.display);
1110
1111            if (self._changingClass && self.animation.animateChangeLayout) {
1112                self._$container
1113                        .removeClass(self._newClass)
1114                        .addClass(self.layout.containerClass);
1115            }
1116
1117            self._execAction('_getFinalMixData', 1);
1118        },
1119        /**
1120         * Prepare Targets
1121         * @since 2.0.0
1122         */
1123
1124        _prepTargets: function() {
1125            var self = this,
1126                    transformCSS = {
1127                        _in: self._getPrefixedCSS('transform', self.effects.transformIn),
1128                        _out: self._getPrefixedCSS('transform', self.effects.transformOut)
1129                    };
1130
1131            self._execAction('_prepTargets', 0);
1132
1133            if (self.animation.animateResizeContainer) {
1134                self._$parent.css('height', self._startHeight + 'px');
1135            }
1136
1137            for (var i = 0; i < self._$toShow.length; i++) {
1138                var el = self._$toShow[i],
1139                        $el = $(el);
1140
1141                el.style.opacity = self.effects.opacity;
1142                el.style.display = (self._changingLayout && self.animation.animateChangeLayout) ?
1143                        self._newDisplay :
1144                        self.layout.display;
1145
1146                $el.css(transformCSS._in);
1147
1148                if (self.animation.animateResizeTargets) {
1149                    el.style.width = el.dataset.finalWidth + 'px';
1150                    el.style.height = el.dataset.finalHeight + 'px';
1151                    el.style.marginRight = -(el.dataset.finalWidth - el.dataset.interWidth) + (el.dataset.finalMarginRight * 1) + 'px';
1152                    el.style.marginBottom = -(el.dataset.finalHeight - el.dataset.interHeight) + (el.dataset.finalMarginBottom * 1) + 'px';
1153                }
1154            }
1155
1156            for (var i = 0; i < self._$pre.length; i++) {
1157                var el = self._$pre[i],
1158                        $el = $(el),
1159                        translate = {
1160                            x: el.dataset.origPosX - el.dataset.interPosX,
1161                            y: el.dataset.origPosY - el.dataset.interPosY
1162                        },
1163                transformCSS = self._getPrefixedCSS('transform', 'translate(' + translate.x + 'px,' + translate.y + 'px)');
1164
1165                $el.css(transformCSS);
1166
1167                if (self.animation.animateResizeTargets) {
1168                    el.style.width = el.dataset.origWidth + 'px';
1169                    el.style.height = el.dataset.origHeight + 'px';
1170
1171                    if (el.dataset.origWidth - el.dataset.finalWidth) {
1172                        el.style.marginRight = -(el.dataset.origWidth - el.dataset.interWidth) + (el.dataset.origMarginRight * 1) + 'px';
1173                    }
1174
1175                    if (el.dataset.origHeight - el.dataset.finalHeight) {
1176                        el.style.marginBottom = -(el.dataset.origHeight - el.dataset.interHeight) + (el.dataset.origMarginBottom * 1) + 'px';
1177                    }
1178                }
1179            }
1180
1181            self._execAction('_prepTargets', 1);
1182        },
1183        /**
1184         * Animate Targets
1185         * @since 2.0.0
1186         */
1187
1188        _animateTargets: function() {
1189            var self = this;
1190
1191            self._execAction('_animateTargets', 0);
1192
1193            self._targetsDone = 0;
1194            self._targetsBound = 0;
1195
1196            self._$parent
1197                    .css(self._getPrefixedCSS('perspective', self.animation.perspectiveDistance + 'px'))
1198                    .css(self._getPrefixedCSS('perspective-origin', self.animation.perspectiveOrigin));
1199
1200            if (self.animation.animateResizeContainer) {
1201                self._$parent
1202                        .css(self._getPrefixedCSS('transition', 'height ' + self.animation.duration + 'ms ease'))
1203                        .css('height', self._newHeight + 'px');
1204            }
1205
1206            for (var i = 0; i < self._$toShow.length; i++) {
1207                var el = self._$toShow[i],
1208                        $el = $(el),
1209                        translate = {
1210                            x: el.dataset.finalPosX - el.dataset.interPosX,
1211                            y: el.dataset.finalPosY - el.dataset.interPosY
1212                        },
1213                delay = self._getDelay(i),
1214                        toShowCSS = {};
1215
1216                el.style.opacity = '';
1217
1218                for (var j = 0; j < 2; j++) {
1219                    var a = j === 0 ? a = self._prefix : '';
1220
1221                    if (self._ff && self._ff <= 20) {
1222                        toShowCSS[a + 'transition-property'] = 'all';
1223                        toShowCSS[a + 'transition-timing-function'] = self.animation.easing + 'ms';
1224                        toShowCSS[a + 'transition-duration'] = self.animation.duration + 'ms';
1225                    }
1226
1227                    toShowCSS[a + 'transition-delay'] = delay + 'ms';
1228                    toShowCSS[a + 'transform'] = 'translate(' + translate.x + 'px,' + translate.y + 'px)';
1229                }
1230
1231                if (self.effects.transform || self.effects.opacity) {
1232                    self._bindTargetDone($el);
1233                }
1234
1235                (self._ff && self._ff <= 20) ?
1236                        $el.css(toShowCSS) :
1237                        $el.css(self.effects.transition).css(toShowCSS);
1238            }
1239
1240            for (var i = 0; i < self._$pre.length; i++) {
1241                var el = self._$pre[i],
1242                        $el = $(el),
1243                        translate = {
1244                            x: el.dataset.finalPosX - el.dataset.interPosX,
1245                            y: el.dataset.finalPosY - el.dataset.interPosY
1246                        },
1247                delay = self._getDelay(i);
1248
1249                if (!(
1250                        el.dataset.finalPosX === el.dataset.origPosX &&
1251                        el.dataset.finalPosY === el.dataset.origPosY
1252                        )) {
1253                    self._bindTargetDone($el);
1254                }
1255
1256                $el.css(self._getPrefixedCSS('transition', 'all ' + self.animation.duration + 'ms ' + self.animation.easing + ' ' + delay + 'ms'));
1257                $el.css(self._getPrefixedCSS('transform', 'translate(' + translate.x + 'px,' + translate.y + 'px)'));
1258
1259                if (self.animation.animateResizeTargets) {
1260                    if (el.dataset.origWidth - el.dataset.finalWidth && el.dataset.finalWidth * 1) {
1261                        el.style.width = el.dataset.finalWidth + 'px';
1262                        el.style.marginRight = -(el.dataset.finalWidth - el.dataset.interWidth) + (el.dataset.finalMarginRight * 1) + 'px';
1263                    }
1264
1265                    if (el.dataset.origHeight - el.dataset.finalHeight && el.dataset.finalHeight * 1) {
1266                        el.style.height = el.dataset.finalHeight + 'px';
1267                        el.style.marginBottom = -(el.dataset.finalHeight - el.dataset.interHeight) + (el.dataset.finalMarginBottom * 1) + 'px';
1268                    }
1269                }
1270            }
1271
1272            if (self._changingClass) {
1273                self._$container
1274                        .removeClass(self.layout.containerClass)
1275                        .addClass(self._newClass);
1276            }
1277
1278            for (var i = 0; i < self._$toHide.length; i++) {
1279                var el = self._$toHide[i],
1280                        $el = $(el),
1281                        delay = self._getDelay(i),
1282                        toHideCSS = {};
1283
1284                for (var j = 0; j < 2; j++) {
1285                    var a = j === 0 ? a = self._prefix : '';
1286
1287                    toHideCSS[a + 'transition-delay'] = delay + 'ms';
1288                    toHideCSS[a + 'transform'] = self.effects.transformOut;
1289                    toHideCSS.opacity = self.effects.opacity;
1290                }
1291
1292                $el.css(self.effects.transition).css(toHideCSS);
1293
1294                if (self.effects.transform || self.effects.opacity) {
1295                    self._bindTargetDone($el);
1296                }
1297                ;
1298            }
1299
1300            self._execAction('_animateTargets', 1);
1301
1302        },
1303        /**
1304         * Bind Targets TransitionEnd
1305         * @since 2.0.0
1306         * @param {object} $el
1307         */
1308
1309        _bindTargetDone: function($el) {
1310            var self = this,
1311                    el = $el[0];
1312
1313            self._execAction('_bindTargetDone', 0, arguments);
1314
1315            if (!el.dataset.bound) {
1316
1317                el.dataset.bound = true;
1318                self._targetsBound++;
1319
1320                $el.on('webkitTransitionEnd.mixItUp transitionend.mixItUp', function(e) {
1321                    if (
1322                            (e.originalEvent.propertyName.indexOf('transform') > -1 ||
1323                                    e.originalEvent.propertyName.indexOf('opacity') > -1) &&
1324                            $(e.originalEvent.target).is(self.selectors.target)
1325                            ) {
1326                        $el.off('.mixItUp');
1327                        delete el.dataset.bound;
1328                        self._targetDone();
1329                    }
1330                });
1331            }
1332
1333            self._execAction('_bindTargetDone', 1, arguments);
1334        },
1335        /**
1336         * Target Done
1337         * @since 2.0.0
1338         */
1339
1340        _targetDone: function() {
1341            var self = this;
1342
1343            self._execAction('_targetDone', 0);
1344
1345            self._targetsDone++;
1346
1347            (self._targetsDone === self._targetsBound) && self._cleanUp();
1348
1349            self._execAction('_targetDone', 1);
1350        },
1351        /**
1352         * Clean Up
1353         * @since 2.0.0
1354         */
1355
1356        _cleanUp: function() {
1357            var self = this,
1358                    targetStyles = self.animation.animateResizeTargets ? 'transform opacity width height margin-bottom margin-right' : 'transform opacity';
1359            unBrake = function() {
1360                self._$targets.removeStyle('transition', self._prefix);
1361            };
1362
1363            self._execAction('_cleanUp', 0);
1364
1365            !self._changingLayout ?
1366                    self._$show.css('display', self.layout.display) :
1367                    self._$show.css('display', self._newDisplay);
1368
1369            self._$targets.css(self._brake);
1370
1371            self._$targets
1372                    .removeStyle(targetStyles, self._prefix)
1373                    .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');
1374
1375            self._$hide.removeStyle('display');
1376
1377            self._$parent.removeStyle('height transition perspective-distance perspective perspective-origin-x perspective-origin-y perspective-origin perspectiveOrigin', self._prefix);
1378
1379            if (self._sorting) {
1380                self._printSort();
1381                self._activeSort = self._newSortString;
1382                self._sorting = false;
1383            }
1384
1385            if (self._changingLayout) {
1386                if (self._changingDisplay) {
1387                    self.layout.display = self._newDisplay;
1388                    self._changingDisplay = false;
1389                }
1390
1391                if (self._changingClass) {
1392                    self._$parent.removeClass(self.layout.containerClass).addClass(self._newClass);
1393                    self.layout.containerClass = self._newClass;
1394                    self._changingClass = false;
1395                }
1396
1397                self._changingLayout = false;
1398            }
1399
1400            self._refresh();
1401
1402            self._buildState();
1403
1404            if (self._state.fail) {
1405                self._$container.addClass(self.layout.containerClassFail);
1406            }
1407
1408            self._$show = $();
1409            self._$hide = $();
1410
1411            if (window.requestAnimationFrame) {
1412                requestAnimationFrame(unBrake);
1413            }
1414
1415            self._mixing = false;
1416
1417            if (typeof self.callbacks._user === 'function') {
1418                self.callbacks._user.call(self._domNode, self._state, self);
1419            }
1420
1421            if (typeof self.callbacks.onMixEnd === 'function') {
1422                self.callbacks.onMixEnd.call(self._domNode, self._state, self);
1423            }
1424
1425            self._$container.trigger('mixEnd', [self._state, self]);
1426
1427            if (self._state.fail) {
1428                (typeof self.callbacks.onMixFail === 'function') && self.callbacks.onMixFail.call(self._domNode, self._state, self);
1429                self._$container.trigger('mixFail', [self._state, self]);
1430            }
1431
1432            if (self._loading) {
1433                (typeof self.callbacks.onMixLoad === 'function') && self.callbacks.onMixLoad.call(self._domNode, self._state, self);
1434                self._$container.trigger('mixLoad', [self._state, self]);
1435            }
1436
1437            if (self._queue.length) {
1438                self._execAction('_queue', 0);
1439
1440                self.multiMix(self._queue[0][0], self._queue[0][1], self._queue[0][2]);
1441                self._queue.splice(0, 1);
1442            }
1443
1444            self._execAction('_cleanUp', 1);
1445
1446            self._loading = false;
1447        },
1448        /**
1449         * Get Prefixed CSS
1450         * @since 2.0.0
1451         * @param {string} property
1452         * @param {string} value
1453         * @param {boolean} prefixValue
1454         * @return {object} styles
1455         */
1456
1457        _getPrefixedCSS: function(property, value, prefixValue) {
1458            var self = this,
1459                    styles = {};
1460
1461            for (i = 0; i < 2; i++) {
1462                var prefix = i === 0 ? self._prefix : '';
1463                prefixValue ? styles[prefix + property] = prefix + value : styles[prefix + property] = value;
1464            }
1465
1466            return self._execFilter('_getPrefixedCSS', styles, arguments);
1467        },
1468        /**
1469         * Get Delay
1470         * @since 2.0.0
1471         * @param {number} i
1472         * @return {number} delay
1473         */
1474
1475        _getDelay: function(i) {
1476            var self = this,
1477                    n = typeof self.animation.staggerSequence === 'function' ? self.animation.staggerSequence.call(self._domNode, i, self._state) : i,
1478                    delay = self.animation.stagger ? n * self.animation.staggerDuration : 0;
1479
1480            return self._execFilter('_getDelay', delay, arguments);
1481        },
1482        /**
1483         * Parse MultiMix Arguments
1484         * @since 2.0.0
1485         * @param {array} args
1486         * @return {object} output
1487         */
1488
1489        _parseMultiMixArgs: function(args) {
1490            var self = this,
1491                    output = {
1492                        command: null,
1493                        animate: self.animation.enable,
1494                        callback: null
1495                    };
1496
1497            for (var i = 0; i < args.length; i++) {
1498                var arg = args[i];
1499
1500                if (arg !== null) {
1501                    if (typeof arg === 'object' || typeof arg === 'string') {
1502                        output.command = arg;
1503                    } else if (typeof arg === 'boolean') {
1504                        output.animate = arg;
1505                    } else if (typeof arg === 'function') {
1506                        output.callback = arg;
1507                    }
1508                }
1509            }
1510
1511            return self._execFilter('_parseMultiMixArgs', output, arguments);
1512        },
1513        /**
1514         * Parse Insert Arguments
1515         * @since 2.0.0
1516         * @param {array} args
1517         * @return {object} output
1518         */
1519
1520        _parseInsertArgs: function(args) {
1521            var self = this,
1522                    output = {
1523                        index: 0,
1524                        $object: $(),
1525                        multiMix: {filter: self._state.activeFilter},
1526                        callback: null
1527                    };
1528
1529            for (var i = 0; i < args.length; i++) {
1530                var arg = args[i];
1531
1532                if (typeof arg === 'number') {
1533                    output.index = arg;
1534                } else if (typeof arg === 'object' && arg instanceof $) {
1535                    output.$object = arg;
1536                } else if (typeof arg === 'object' && self._helpers._isElement(arg)) {
1537                    output.$object = $(arg);
1538                } else if (typeof arg === 'object' && arg !== null) {
1539                    output.multiMix = arg;
1540                } else if (typeof arg === 'boolean' && !arg) {
1541                    output.multiMix = false;
1542                } else if (typeof arg === 'function') {
1543                    output.callback = arg;
1544                }
1545            }
1546
1547            return self._execFilter('_parseInsertArgs', output, arguments);
1548        },
1549        /**
1550         * Execute Action
1551         * @since 2.0.0
1552         * @param {string} methodName
1553         * @param {boolean} isPost
1554         * @param {array} args
1555         */
1556
1557        _execAction: function(methodName, isPost, args) {
1558            var self = this,
1559                    context = isPost ? 'post' : 'pre';
1560
1561            if (!self._actions.isEmptyObject && self._actions.hasOwnProperty(methodName)) {
1562                for (var key in self._actions[methodName][context]) {
1563                    self._actions[methodName][context][key].call(self, args);
1564                }
1565            }
1566        },
1567        /**
1568         * Execute Filter
1569         * @since 2.0.0
1570         * @param {string} methodName
1571         * @param {mixed} value
1572         * @return {mixed} value
1573         */
1574
1575        _execFilter: function(methodName, value, args) {
1576            var self = this;
1577
1578            if (!self._filters.isEmptyObject && self._filters.hasOwnProperty(methodName)) {
1579                for (var key in self._filters[methodName]) {
1580                    return self._filters[methodName][key].call(self, args);
1581                }
1582            } else {
1583                return value;
1584            }
1585        },
1586        /* Helpers
1587         ---------------------------------------------------------------------- */
1588
1589        _helpers: {
1590            /**
1591             * CamelCase
1592             * @since 2.0.0
1593             * @param {string}
1594             * @return {string}
1595             */
1596
1597            _camelCase: function(string) {
1598                return string.replace(/-([a-z])/g, function(g) {
1599                    return g[1].toUpperCase();
1600                });
1601            },
1602            /**
1603             * Is Element
1604             * @since 2.1.3
1605             * @param {object} element to test
1606             * @return {boolean}
1607             */
1608
1609            _isElement: function(el) {
1610                if (window.HTMLElement) {
1611                    return el instanceof HTMLElement;
1612                } else {
1613                    return (
1614                            el !== null &&
1615                            el.nodeType === 1 &&
1616                            el.nodeName === 'string'
1617                            );
1618                }
1619            }
1620        },
1621        /* Public Methods
1622         ---------------------------------------------------------------------- */
1623
1624        /**
1625         * Is Mixing
1626         * @since 2.0.0
1627         * @return {boolean}
1628         */
1629
1630        isMixing: function() {
1631            var self = this;
1632
1633            return self._execFilter('isMixing', self._mixing);
1634        },
1635        /**
1636         * Filter (public)
1637         * @since 2.0.0
1638         * @param {array} arguments
1639         */
1640
1641        filter: function() {
1642            var self = this,
1643                    args = self._parseMultiMixArgs(arguments);
1644
1645            self._clicking && (self._toggleString = '');
1646
1647            self.multiMix({filter: args.command}, args.animate, args.callback);
1648        },
1649        /**
1650         * Sort (public)
1651         * @since 2.0.0
1652         * @param {array} arguments
1653         */
1654
1655        sort: function() {
1656            var self = this,
1657                    args = self._parseMultiMixArgs(arguments);
1658
1659            self.multiMix({sort: args.command}, args.animate, args.callback);
1660        },
1661        /**
1662         * Change Layout (public)
1663         * @since 2.0.0
1664         * @param {array} arguments
1665         */
1666
1667        changeLayout: function() {
1668            var self = this,
1669                    args = self._parseMultiMixArgs(arguments);
1670
1671            self.multiMix({changeLayout: args.command}, args.animate, args.callback);
1672        },
1673        /**
1674         * MultiMix
1675         * @since 2.0.0
1676         * @param {array} arguments
1677         */
1678
1679        multiMix: function() {
1680            var self = this,
1681                    args = self._parseMultiMixArgs(arguments);
1682
1683            self._execAction('multiMix', 0, arguments);
1684
1685            if (!self._mixing) {
1686                if (self.controls.enable && !self._clicking) {
1687                    self.controls.toggleFilterButtons && self._buildToggleArray();
1688                    self._updateControls(args.command, self.controls.toggleFilterButtons);
1689                }
1690
1691                (self._queue.length < 2) && (self._clicking = false);
1692
1693                delete self.callbacks._user;
1694                if (args.callback)
1695                    self.callbacks._user = args.callback;
1696
1697                var sort = args.command.sort,
1698                        filter = args.command.filter,
1699                        changeLayout = args.command.changeLayout;
1700
1701                self._refresh();
1702
1703                if (sort) {
1704                    self._newSort = self._parseSort(sort);
1705                    self._newSortString = sort;
1706
1707                    self._sorting = true;
1708                    self._sort();
1709                }
1710
1711                if (filter !== undf) {
1712                    filter = (filter === 'all') ? self.selectors.target : filter;
1713
1714                    self._activeFilter = filter;
1715                }
1716
1717                self._filter();
1718
1719                if (changeLayout) {
1720                    self._newDisplay = (typeof changeLayout === 'string') ? changeLayout : changeLayout.display || self.layout.display;
1721                    self._newClass = changeLayout.containerClass || '';
1722
1723                    if (
1724                            self._newDisplay !== self.layout.display ||
1725                            self._newClass !== self.layout.containerClass
1726                            ) {
1727                        self._changingLayout = true;
1728
1729                        self._changingClass = (self._newClass !== self.layout.containerClass);
1730                        self._changingDisplay = (self._newDisplay !== self.layout.display);
1731                    }
1732                }
1733
1734                self._$targets.css(self._brake);
1735
1736                self._goMix(args.animate ^ self.animation.enable ? args.animate : self.animation.enable);
1737
1738                self._execAction('multiMix', 1, arguments);
1739
1740            } else {
1741                if (self.animation.queue && self._queue.length < self.animation.queueLimit) {
1742                    self._queue.push(arguments);
1743
1744                    (self.controls.enable && !self._clicking) && self._updateControls(args.command);
1745
1746                    self._execAction('multiMixQueue', 1, arguments);
1747
1748                } else {
1749                    if (typeof self.callbacks.onMixBusy === 'function') {
1750                        self.callbacks.onMixBusy.call(self._domNode, self._state, self);
1751                    }
1752                    self._$container.trigger('mixBusy', [self._state, self]);
1753
1754                    self._execAction('multiMixBusy', 1, arguments);
1755                }
1756            }
1757        },
1758        /**
1759         * Insert
1760         * @since 2.0.0
1761         * @param {array} arguments
1762         */
1763
1764        insert: function() {
1765            var self = this,
1766                    args = self._parseInsertArgs(arguments),
1767                    callback = (typeof args.callback === 'function') ? args.callback : null,
1768                    frag = document.createDocumentFragment(),
1769                    target = (function() {
1770                        self._refresh();
1771
1772                        if (self._$targets.length) {
1773                            return (args.index < self._$targets.length || !self._$targets.length) ?
1774                                    self._$targets[args.index] :
1775                                    self._$targets[self._$targets.length - 1].nextElementSibling;
1776                        } else {
1777                            return self._$parent[0].children[0];
1778                        }
1779                    })();
1780
1781            self._execAction('insert', 0, arguments);
1782
1783            if (args.$object) {
1784                for (var i = 0; i < args.$object.length; i++) {
1785                    var el = args.$object[i];
1786
1787                    frag.appendChild(el);
1788                    frag.appendChild(document.createTextNode(' '));
1789                }
1790
1791                self._$parent[0].insertBefore(frag, target);
1792            }
1793
1794            self._execAction('insert', 1, arguments);
1795
1796            if (typeof args.multiMix === 'object') {
1797                self.multiMix(args.multiMix, callback);
1798            }
1799        },
1800        /**
1801         * Prepend
1802         * @since 2.0.0
1803         * @param {array} arguments
1804         */
1805
1806        prepend: function() {
1807            var self = this,
1808                    args = self._parseInsertArgs(arguments);
1809
1810            self.insert(0, args.$object, args.multiMix, args.callback);
1811        },
1812        /**
1813         * Append
1814         * @since 2.0.0
1815         * @param {array} arguments
1816         */
1817
1818        append: function() {
1819            var self = this,
1820                    args = self._parseInsertArgs(arguments);
1821
1822            self.insert(self._state.totalTargets, args.$object, args.multiMix, args.callback);
1823        },
1824        /**
1825         * Get Option
1826         * @since 2.0.0
1827         * @param {string} string
1828         * @return {mixed} value
1829         */
1830
1831        getOption: function(string) {
1832            var self = this,
1833                    getProperty = function(obj, prop) {
1834                        var parts = prop.split('.'),
1835                                last = parts.pop(),
1836                                l = parts.length,
1837                                i = 1,
1838                                current = parts[0] || prop;
1839
1840                        while ((obj = obj[current]) && i < l) {
1841                            current = parts[i];
1842                            i++;
1843                        }
1844
1845                        if (obj !== undf) {
1846                            return obj[last] !== undf ? obj[last] : obj;
1847                        }
1848                    };
1849
1850            return string ? self._execFilter('getOption', getProperty(self, string), arguments) : self;
1851        },
1852        /**
1853         * Set Options
1854         * @since 2.0.0
1855         * @param {object} config
1856         */
1857
1858        setOptions: function(config) {
1859            var self = this;
1860
1861            self._execAction('setOptions', 0, arguments);
1862
1863            typeof config === 'object' && $.extend(true, self, config);
1864
1865            self._execAction('setOptions', 1, arguments);
1866        },
1867        /**
1868         * Get State
1869         * @since 2.0.0
1870         * @return {object} state
1871         */
1872
1873        getState: function() {
1874            var self = this;
1875
1876            return self._execFilter('getState', self._state, self);
1877        },
1878        /**
1879         * Force Refresh
1880         * @since 2.1.2
1881         */
1882
1883        forceRefresh: function() {
1884            var self = this;
1885
1886            self._refresh(false, true);
1887        },
1888        /**
1889         * Destroy
1890         * @since 2.0.0
1891         * @param {boolean} hideAll
1892         */
1893
1894        destroy: function(hideAll) {
1895            var self = this;
1896
1897            self._execAction('destroy', 0, arguments);
1898
1899            self._$body
1900                    .add($(self.selectors.sort))
1901                    .add($(self.selectors.filter))
1902                    .off('.mixItUp');
1903
1904            for (var i = 0; i < self._$targets.length; i++) {
1905                var target = self._$targets[i];
1906
1907                hideAll && (target.style.display = '');
1908
1909                delete target.mixParent;
1910            }
1911
1912            self._execAction('destroy', 1, arguments);
1913
1914            delete $.MixItUp.prototype._instances[self._id];
1915        }
1916
1917    };
1918
1919    /* jQuery Methods
1920     ---------------------------------------------------------------------- */
1921
1922    /**
1923     * jQuery .mixItUp() method
1924     * @since 2.0.0
1925     * @extends $.fn
1926     */
1927
1928    $.fn.mixItUp = function() {
1929        var args = arguments,
1930                dataReturn = [],
1931                eachReturn,
1932                _instantiate = function(domNode, settings) {
1933                    var instance = new $.MixItUp(),
1934                            rand = function() {
1935                                return ('00000' + (Math.random() * 16777216 << 0).toString(16)).substr(-6).toUpperCase();
1936                            };
1937
1938                    instance._execAction('_instantiate', 0, arguments);
1939
1940                    domNode.id = !domNode.id ? 'MixItUp' + rand() : domNode.id;
1941
1942                    if (!instance._instances[domNode.id]) {
1943                        instance._instances[domNode.id] = instance;
1944                        instance._init(domNode, settings);
1945                    }
1946
1947                    instance._execAction('_instantiate', 1, arguments);
1948                };
1949
1950        eachReturn = this.each(function() {
1951            if (args && typeof args[0] === 'string') {
1952                var instance = $.MixItUp.prototype._instances[this.id];
1953                if (args[0] == 'isLoaded') {
1954                    dataReturn.push(instance ? true : false);
1955                } else {
1956                    var data = instance[args[0]](args[1], args[2], args[3]);
1957                    if (data !== undf)
1958                        dataReturn.push(data);
1959                }
1960            } else {
1961                _instantiate(this, args[0]);
1962            }
1963        });
1964
1965        if (dataReturn.length) {
1966            return dataReturn.length > 1 ? dataReturn : dataReturn[0];
1967        } else {
1968            return eachReturn;
1969        }
1970    };
1971
1972    /**
1973     * jQuery .removeStyle() method
1974     * @since 2.0.0
1975     * @extends $.fn
1976     */
1977
1978    $.fn.removeStyle = function(style, prefix) {
1979        prefix = prefix ? prefix : '';
1980
1981        return this.each(function() {
1982            var el = this,
1983                    styles = style.split(' ');
1984
1985            for (var i = 0; i < styles.length; i++) {
1986                for (var j = 0; j < 2; j++) {
1987                    var prop = j ? styles[i] : prefix + styles[i];
1988                    if (
1989                            el.style[prop] !== undf &&
1990                            typeof el.style[prop] !== 'unknown' &&
1991                            el.style[prop].length > 0
1992                            ) {
1993                        el.style[prop] = '';
1994                    }
1995                    if (!prefix)
1996                        break;
1997                }
1998            }
1999
2000            if (el.attributes && el.attributes.style && el.attributes.style !== undf && el.attributes.style.nodeValue === '') {
2001                el.attributes.removeNamedItem('style');
2002            }
2003        });
2004    };
2005
2006})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.